info debug 級別的日誌輸出到 /path/log/demo.log
warn error .... 級別的日誌輸出到 /path/log/demo_error.log
日誌自動按小時分割 最多保留7天的日誌git
https://github.com/uber-go/zapgithub
https://github.com/lestrrat-go/file-rotatelogsapi
zap提供日誌分級,打點key-value參數等功能,而file-foratelogs則提供日誌自動按時間分割的功能,github上start數比較多的 https://github.com/natefinch/lumberjack 也提供相似功能,可是是根據文件大小分片,感受除非藉助其餘工具,不然找某個時間點的日誌時,體驗可能不是那麼友好。工具
package demo import ( rotatelogs "github.com/lestrrat-go/file-rotatelogs" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) var Logger *zap.Logger func init() { // 設置一些基本日誌格式 具體含義還比較好理解,直接看zap源碼也不難懂 encoder := zapcore.NewConsoleEncoder(zapcore.EncoderConfig{ MessageKey: "msg", LevelKey: "level", EncodeLevel: zapcore.CapitalLevelEncoder, TimeKey: "ts", EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("2006-01-02 15:04:05")) }, CallerKey: "file", EncodeCaller: zapcore.ShortCallerEncoder, EncodeDuration: func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) { enc.AppendInt64(int64(d) / 1000000) }, }) // 實現兩個判斷日誌等級的interface infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { return lvl < zapcore.WarnLevel }) warnLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { return lvl >= zapcore.WarnLevel }) // 獲取 info、warn日誌文件的io.Writer 抽象 getWriter() 在下方實現 infoWriter := getWriter("/path/log/demo.log") warnWriter := getWriter("/path/log/demo_error.log") // 最後建立具體的Logger core := zapcore.NewTee( zapcore.NewCore(*encoder, zapcore.AddSync(infoHook), infoLevel), zapcore.NewCore(*encoder, zapcore.AddSync(warnHook), warnLevel), ) Logger = zap.New(core, zap.AddCaller()) // 須要傳入 zap.AddCaller() 纔會顯示打日誌點的文件名和行數, 有點小坑 } func getWriter(filename string) io.Writer { // 生成rotatelogs的Logger 實際生成的文件名 demo.log.YYmmddHH // demo.log是指向最新日誌的連接 // 保存7天內的日誌,每1小時(整點)分割一第二天志 hook, err := rotatelogs.New( filename+".%Y%m%d%H", // 沒有使用go風格反人類的format格式 rotatelogs.WithLinkName(filename), rotatelogs.WithMaxAge(time.Hour*24*7), rotatelogs.WithRotationTime(time.Hour), ) if err != nil { panic(err) } return hook }
zap.NewCore接收的參數是io.Writer而不是本身包的struct,開發者能夠按需傳入本身須要的io.Writer 挺好。debug