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

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)
}