You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
1.7 KiB
75 lines
1.7 KiB
package logger |
|
|
|
import ( |
|
"fmt" |
|
"os" |
|
|
|
"go.uber.org/zap" |
|
"go.uber.org/zap/zapcore" |
|
"gopkg.in/natefinch/lumberjack.v2" |
|
) |
|
|
|
func getLogLevel(level string) *zapcore.Level { |
|
// 设置日志级别 |
|
logLevel := zap.InfoLevel |
|
switch level { |
|
case "debug": |
|
logLevel = zap.DebugLevel |
|
case "info": |
|
logLevel = zap.InfoLevel |
|
case "warn": |
|
logLevel = zap.WarnLevel |
|
case "error": |
|
logLevel = zap.ErrorLevel |
|
} |
|
|
|
return &logLevel |
|
} |
|
|
|
func NewLogger(level, path string) *zap.Logger { |
|
// 1. 始终保留控制台输出 |
|
consoleEncoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()) |
|
consoleWriter := zapcore.Lock(os.Stderr) // 加锁保证线程安全 |
|
|
|
cores := []zapcore.Core{ |
|
zapcore.NewCore(consoleEncoder, consoleWriter, getLogLevel(level)), |
|
} |
|
|
|
// 2. 条件性添加文件输出 |
|
if path != "" { |
|
fileWriter := zapcore.AddSync(&lumberjack.Logger{ |
|
Filename: path, |
|
MaxSize: 10, |
|
MaxBackups: 5, |
|
MaxAge: 30, |
|
Compress: false, |
|
}) |
|
|
|
fileEncoder := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()) |
|
cores = append(cores, zapcore.NewCore(fileEncoder, fileWriter, getLogLevel(level))) |
|
} |
|
|
|
// 3. 创建带恢复机制的Logger |
|
return zap.New( |
|
zapcore.NewTee(cores...), |
|
zap.AddCaller(), |
|
zap.AddStacktrace(zapcore.ErrorLevel), |
|
zap.WrapCore(func(core zapcore.Core) zapcore.Core { |
|
return &safeCore{Core: core} // 包装核心添加recover |
|
}), |
|
) |
|
} |
|
|
|
// 安全核心包装器 |
|
type safeCore struct { |
|
zapcore.Core |
|
} |
|
|
|
func (c *safeCore) Write(ent zapcore.Entry, fields []zapcore.Field) error { |
|
defer func() { |
|
if r := recover(); r != nil { |
|
fmt.Fprintf(os.Stderr, "Recovered from logger panic: %v\n", r) |
|
} |
|
}() |
|
return c.Core.Write(ent, fields) |
|
}
|
|
|