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.
76 lines
1.7 KiB
76 lines
1.7 KiB
1 month ago
|
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)
|
||
|
}
|