package logger import ( "log" "strings" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) var Log *zap.Logger var Sugar *zap.SugaredLogger var Std *log.Logger // Init 初始化全局 zap 日志。 // // env 环境标识:pro 使用生产配置(默认 Warn),其他使用开发配置(默认 Info)。 // level 强制指定的日志级别(debug/info/warn/error),为空时使用对应环境的默认级别。 func Init(env string, level string) error { opt := zap.AddStacktrace(zap.ErrorLevel) // error 日志打印堆栈信息 // 解析强制指定的级别;未指定或非法时 forced 为 nil,表示使用环境默认级别。 forced := parseLevel(level) var err error if env == "pro" { // Log, err = zap.NewProduction(opt) Log, err = newProduction(forced, opt) log.Println("zap init newProduction") } else { // Log, err = zap.NewDevelopment(opt) Log, err = newDevelopment(forced, opt) log.Println("zap init newDevelopment") } if err == nil { Sugar = Log.Sugar() } zap.ReplaceGlobals(Log) // 全局logger,zap.L() 和 zap.S() 需要调用 ReplaceGlobals 函数才会记录日志信息 // 之后可以使用zap.L()代替Log,zap.S()代替Sugar Std = zap.NewStdLog(Log) // 标准输入自动转换为 zap.logger日志 return err } // parseLevel 解析级别字符串,支持 debug/info/warn(warning)/error,不区分大小写。 // 无法识别(含空串)时返回 nil,调用方据此回退到环境默认级别。 func parseLevel(level string) *zapcore.Level { switch strings.ToLower(strings.TrimSpace(level)) { case "debug": l := zapcore.DebugLevel return &l case "info": l := zapcore.InfoLevel return &l case "warn", "warning": l := zapcore.WarnLevel return &l case "error": l := zapcore.ErrorLevel return &l default: return nil } } func newProduction(forced *zapcore.Level, options ...zap.Option) (*zap.Logger, error) { lvl := zapcore.WarnLevel // 生产环境默认 Warn if forced != nil { lvl = *forced } config := zap.Config{ Level: zap.NewAtomicLevelAt(lvl), Development: false, Sampling: &zap.SamplingConfig{ Initial: 100, Thereafter: 100, }, Encoding: "json", EncoderConfig: zap.NewProductionEncoderConfig(), OutputPaths: []string{"stderr"}, ErrorOutputPaths: []string{"stderr"}, } return config.Build(options...) } func newDevelopment(forced *zapcore.Level, options ...zap.Option) (*zap.Logger, error) { lvl := zapcore.InfoLevel // 开发环境默认 Info if forced != nil { lvl = *forced } config := zap.Config{ Level: zap.NewAtomicLevelAt(lvl), Development: true, Encoding: "console", EncoderConfig: zap.NewDevelopmentEncoderConfig(), OutputPaths: []string{"stderr"}, ErrorOutputPaths: []string{"stderr"}, } return config.Build(options...) }