Files
junhong_cmp_fiber/pkg/logger/logger.go

160 lines
3.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package logger
import (
"os"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
var (
// appLogger 应用日志记录器
appLogger *zap.Logger
// accessLogger 访问日志记录器
accessLogger *zap.Logger
)
// InitLoggers 初始化应用和访问日志记录器
func InitLoggers(
level string,
development bool,
appLogConfig LogRotationConfig,
accessLogConfig LogRotationConfig,
) error {
// 解析日志级别
zapLevel := parseLevel(level)
// 创建编码器配置
encoderConfig := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
MessageKey: "msg",
StacktraceKey: "stacktrace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalColorLevelEncoder, // 使用彩色级别编码器
EncodeTime: zapcore.ISO8601TimeEncoder, // 2025-11-11T17:50:52.830+0800 格式
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder, // 输出 middleware/trace.go:58 格式
}
// 选择编码器(开发模式使用控制台,生产使用 JSON
var encoder zapcore.Encoder
if development {
encoder = zapcore.NewConsoleEncoder(encoderConfig)
} else {
encoder = zapcore.NewJSONEncoder(encoderConfig)
}
// 创建应用日志写入器
appWriter := zapcore.AddSync(newLumberjackLogger(appLogConfig))
// 开发模式下同时输出到控制台
if development {
appWriter = zapcore.NewMultiWriteSyncer(
appWriter,
zapcore.AddSync(os.Stdout),
)
}
// 创建应用日志核心
appCore := zapcore.NewCore(
encoder,
appWriter,
zapLevel,
)
// 创建访问日志核心(始终使用 JSON
accessCore := zapcore.NewCore(
zapcore.NewJSONEncoder(encoderConfig),
zapcore.AddSync(newLumberjackLogger(accessLogConfig)),
zapcore.InfoLevel, // 访问日志始终使用 info 级别
)
// 构建日志记录器
if development {
// 开发模式:添加调用者信息和堆栈跟踪
appLogger = zap.New(appCore, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel), zap.Development())
} else {
// 生产模式:添加调用者信息,仅在 error 时添加堆栈跟踪
appLogger = zap.New(appCore, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
}
// 访问日志不需要调用者信息
accessLogger = zap.New(accessCore)
return nil
}
// GetAppLogger 返回应用日志记录器
func GetAppLogger() *zap.Logger {
if appLogger == nil {
// 如果未初始化,返回 nop logger
return zap.NewNop()
}
return appLogger
}
// GetAccessLogger 返回访问日志记录器
func GetAccessLogger() *zap.Logger {
if accessLogger == nil {
// 如果未初始化,返回 nop logger
return zap.NewNop()
}
return accessLogger
}
// Sync 刷新所有日志缓冲区
func Sync() error {
if appLogger != nil {
if err := appLogger.Sync(); err != nil {
return err
}
}
if accessLogger != nil {
if err := accessLogger.Sync(); err != nil {
return err
}
}
return nil
}
// parseLevel 解析日志级别字符串
func parseLevel(level string) zapcore.Level {
switch level {
case "debug":
return zapcore.DebugLevel
case "info":
return zapcore.InfoLevel
case "warn":
return zapcore.WarnLevel
case "error":
return zapcore.ErrorLevel
default:
return zapcore.InfoLevel
}
}
// newLumberjackLogger 创建 Lumberjack 日志轮转器
func newLumberjackLogger(config LogRotationConfig) *lumberjack.Logger {
return &lumberjack.Logger{
Filename: config.Filename,
MaxSize: config.MaxSize,
MaxBackups: config.MaxBackups,
MaxAge: config.MaxAge,
Compress: config.Compress,
LocalTime: true, // 使用本地时间
}
}
// LogRotationConfig 日志轮转配置(从 config 包复制以避免循环依赖)
type LogRotationConfig struct {
Filename string
MaxSize int
MaxBackups int
MaxAge int
Compress bool
}