// Pacage logger provides a simple wrapper around zap logger package logger import ( "fmt" "os" "strings" "time" "github.com/runningwater/gohub/pkg/app" "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" ) // Logger 全局日志对象 var Logger *zap.Logger // Init 初始化日志 func Init(filename string, maxSize, maxBackup, maxAge int, compress bool, logType, level string) { // 获取日志写入介质 writeSyncer := getLogWriter(filename, maxSize, maxBackup, maxAge, compress, logType) // 设置日志等级, 具体见 config/log.go logLevel := new(zap.AtomicLevel) if err := logLevel.UnmarshalText([]byte(level)); err != nil { fmt.Println("日志初始化错误,日志级别设置有误。请修改 config/log.go 中的 log.level") } // 初始化 core core := zapcore.NewCore(getEncoder(), writeSyncer, logLevel) // 初始化 logger Logger = zap.New(core, zap.AddCaller(), // 调用文件和行号,内部使用 runtime.Caller zap.AddCallerSkip(1), // 调用文件和行号,内部使用 runtime.Caller zap.Development(), // 开发模式,堆栈跟踪 zap.AddStacktrace(zapcore.ErrorLevel), // 记录错误级别以上的堆栈信息 ) // 设置全局 logger // 将自定义的 logger 替换 zap 的全局 logger zap.ReplaceGlobals(Logger) } // getEncoder 获取编码器(如何写入日志), 输出: 日志格式 func getEncoder() zapcore.Encoder { // 日志模式规则 encoderConfig := zapcore.EncoderConfig{ TimeKey: "time", // 时间字段名 LevelKey: "level", // 日志级别字段名 NameKey: "logger", // 日志名称字段名 CallerKey: "caller", // 调用者字段名 FunctionKey: zapcore.OmitKey, // 函数名字段名,不显示 MessageKey: "msg", // 消息字段名 StacktraceKey: "stacktrace", // 堆栈跟踪字段名 LineEnding: zapcore.DefaultLineEnding, // 每行日志的结尾添加换行符 EncodeLevel: zapcore.CapitalLevelEncoder, // 大写编码器 EncodeTime: customTimeEncoder, // 自定义时间编码器 EncodeDuration: zapcore.SecondsDurationEncoder, // 以秒为单位显示持续时间 EncodeCaller: zapcore.ShortCallerEncoder, // 短路径编码器 } if app.IsLocal() { encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder // 彩色编码器 // 如果是本地环境,使用 console 编码器 return zapcore.NewConsoleEncoder(encoderConfig) } // 如果不是本地环境,使用 JSON 编码器 return zapcore.NewJSONEncoder(encoderConfig) } func customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { // 自定义时间格式 enc.AppendString(t.Format("2006-01-02 15:04:05")) } // getLogWriter 获取日志写入介质 // os.Stdout: 标准输出 // 文件输出 func getLogWriter(filename string, maxSize, maxBackup, maxAge int, compress bool, logType string) zapcore.WriteSyncer { // 如果配置了按日期记录日志,则使用按日期记录日志 if logType == "daily" { logname := time.Now().Format("2006-01-02") + ".log" filename = strings.Replace(filename, "logs.log", logname, 1) } // 滚动日志,详见 config/log.go lumberJackLogger := &lumberjack.Logger{ Filename: filename, // 日志文件名 MaxSize: maxSize, // 每个日志文件保存的最大尺寸 单位:MB MaxBackups: maxBackup, // 日志文件最多保存多少个备份 MaxAge: maxAge, // 文件最多保存多少天 Compress: compress, // 是否压缩 } if app.IsLocal() { // 如果是本地环境,使用标准输出和文件输出 return zapcore.NewMultiWriteSyncer( zapcore.AddSync(os.Stdout), zapcore.AddSync(lumberJackLogger), ) } else { // 生产环境只记录文件 return zapcore.AddSync(lumberJackLogger) } }