1. 程式人生 > 實用技巧 >golang 日誌框架(zap)完整配置和使用

golang 日誌框架(zap)完整配置和使用

目錄結構:

logger.go檔案:

package log

import (
    rotatelogs "github.com/lestrrat-go/file-rotatelogs"
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
    "io"
    "os"
    "time"
)

var errorLogger *zap.SugaredLogger

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.InfoLevel }) errorLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { return lvl >= zapcore.ErrorLevel }) // 獲取 info、error日誌檔案的io.Writer 抽象 getWriter() 在下方實現
infoWriter := getWriter("./logs/info.log") errorWriter := getWriter("./logs/error.log") // 最後建立具體的Logger core := zapcore.NewTee( zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), infoLevel), //列印到控制檯 zapcore.NewCore(encoder, zapcore.AddSync(infoWriter), infoLevel), zapcore.NewCore(encoder, zapcore.AddSync(errorWriter), errorLevel), ) log := zap.New(core, zap.AddCaller()) // 需要傳入 zap.AddCaller() 才會顯示打日誌點的檔名和行數, 有點小坑 errorLogger = log.Sugar() } func getWriter(filename string) io.Writer { // 生成rotatelogs的Logger 實際生成的檔名 info.log.YYmmddHH // info.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 } func Debug(args ...interface{}) { errorLogger.Debug(args...) } func Debugf(template string, args ...interface{}) { errorLogger.Debugf(template, args...) } func Info(args ...interface{}) { errorLogger.Info(args...) } func Infof(template string, args ...interface{}) { errorLogger.Infof(template, args...) } func Warn(args ...interface{}) { errorLogger.Warn(args...) } func Warnf(template string, args ...interface{}) { errorLogger.Warnf(template, args...) } func Error(args ...interface{}) { errorLogger.Error(args...) } func Errorf(template string, args ...interface{}) { errorLogger.Errorf(template, args...) } func DPanic(args ...interface{}) { errorLogger.DPanic(args...) } func DPanicf(template string, args ...interface{}) { errorLogger.DPanicf(template, args...) } func Panic(args ...interface{}) { errorLogger.Panic(args...) } func Panicf(template string, args ...interface{}) { errorLogger.Panicf(template, args...) } func Fatal(args ...interface{}) { errorLogger.Fatal(args...) } func Fatalf(template string, args ...interface{}) { errorLogger.Fatalf(template, args...) }

使用方法:

main.go

package main

import log "svctest/logger"

func main() {
    log.Info("aaaaa")
    log.Warn("bbb")
    log.Error("accc")
}