package log import ( "fmt" "github.com/natefinch/lumberjack" "go.uber.org/zap" "go.uber.org/zap/zapcore" "os" "runtime" "time" ) var ( logger *zap.Logger file *os.File ) var ( Info func(msg string, fields ...zapcore.Field) Debug func(msg string, fields ...zapcore.Field) Warn func(msg string, fields ...zapcore.Field) Error func(msg string, fields ...zapcore.Field) Fatal func(msg string, fields ...zapcore.Field) ) const ( DebugLevel = zapcore.DebugLevel InfoLevel = zapcore.InfoLevel WarnLevel = zapcore.WarnLevel ErrorLevel = zapcore.ErrorLevel DPanicLevel = zapcore.DPanicLevel PanicLevel = zapcore.PanicLevel FatalLevel = zapcore.FatalLevel ) func Open(filepath string, level int) { // 自定义时间编码器,不显示时区 customTimeEncoder := func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("2006-01-02 15:04:05.000")) // 使用不含时区的格式 } // 配置lumberjack file := &lumberjack.Logger{ Filename: filepath, // 日志文件的位置 MaxSize: 100, // 每个日志文件保存的最大尺寸 单位:MB MaxBackups: 3, // 日志文件最多保存多少个备份 MaxAge: 28, // 文件最多保存多少天 Compress: true, // 是否压缩/归档旧文件 } //var err error //// 打开日志文件 //file, err = os.OpenFile(filepath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) //if err != nil { // zap.L().Fatal("无法打开日志文件", zap.Error(err)) //} // 设置编码器配置 encoderConfig := zapcore.EncoderConfig{ TimeKey: "time", LevelKey: "level", NameKey: "logger", CallerKey: "caller", MessageKey: "msg", StacktraceKey: "stacktrace", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: zapcore.LowercaseLevelEncoder, EncodeTime: customTimeEncoder, EncodeDuration: zapcore.SecondsDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, } // 创建控制台输出 consoleEncoder := zapcore.NewConsoleEncoder(encoderConfig) consoleWriter := zapcore.AddSync(os.Stdout) consoleCore := zapcore.NewCore(consoleEncoder, consoleWriter, zap.NewAtomicLevelAt(zap.DebugLevel)) // 创建文件输出 fileEncoder := zapcore.NewJSONEncoder(encoderConfig) fileWriter := zapcore.AddSync(file) fileCore := zapcore.NewCore(fileEncoder, fileWriter, zap.NewAtomicLevelAt(zapcore.Level(level))) // 将两个 Core 组合成一个 MultiWriteSyncer core := zapcore.NewTee(consoleCore, fileCore) // 创建logger对象 logger = zap.New(core, zap.AddCaller()) Info = logger.Info Debug = logger.Debug Warn = logger.Warn Error = logger.Error Fatal = logger.Fatal } func Close() { if logger != nil { _ = logger.Sync() logger = nil } if file != nil { _ = file.Close() file = nil } } func StackTrace() string { var pcs [32]uintptr n := runtime.Callers(3, pcs[:]) // 跳过前3个栈帧,即printStackTrace, caller, 和runtime.Callers本身 frames := runtime.CallersFrames(pcs[:n]) s := "" for { frame, more := frames.Next() s += fmt.Sprintf("%+v\n", frame) if !more { break } } return s }