需求:將日誌文件統一輸出到D:/bian/logs/dspcollect.log文件中,go程序重啓後日志累加寫入文件,每24小時分割一次日誌,保存30天內的日誌文件。
對比了幾款go 日誌框架:zap , logrus ,seelog等。其中logrus
是目前Github上star數量最多的日誌庫,能強大,性能高效,而且具有高度靈活性,提供了自定義插件的功能。zap是Uber推出的一個快速、結構化的分級日誌庫.具有強大的ad-hoc分析功能,並且具有靈活的儀表盤。seelog提供了靈活的異步調度、格式化和過濾功能。
關於logrus的使用可以參考這篇博客:https://mojotv.cn/2018/12/27/golang-logrus-tutorial
本文主要使用zap,涉及到的go包如下:
github.com/lestrrat/go-file-rotatelogs //由於zap,logrus都不支持日誌分割,所有依賴rotate進行日誌分割
go.uber.org/zap
package main
import (
"github.com/lestrrat/go-file-rotatelogs"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"io"
"time"
)
var Logger *zap.SugaredLogger
func main() {
Logger.Error("error....")
Logger.Info("info....")
Logger.Warn("warn....")
}
func init() {
initLogger()
}
func initLogger() {
logPath := "D:/bian/logs/dspcollect.log"
if !Exists(logPath) {
file, err := os.Create(logPath)
defer file.Close()
if err != nil{
fmt.Println("mkdir logPath err!")
return
}
}
encoder := initEncoder()
// 想要將日常文件區分開來,可以實現多個日誌等級接口
/*infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl < zapcore.WarnLevel
})*/
debugLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= zapcore.DebugLevel
})
// 獲取 info、warn日誌文件的io.Writer
//infoIoWriter := getWriter("D:/bian/logs/dspcollect.log")
warnIoWriter := getWriter("D:/bian/logs/dspcollect.log")
// 創建Logger
core := zapcore.NewTee(
//zapcore.NewCore(encoder, zapcore.AddSync(infoIoWriter), infoLevel),
zapcore.NewCore(encoder, zapcore.AddSync(warnIoWriter), debugLevel),
)
logger := zap.New(core, zap.AddCaller()) // 需要傳入 zap.AddCaller() 纔會顯示打日誌點的文件名和行數
Logger = logger.Sugar()
}
//初始化Encoder
func initEncoder() zapcore.Encoder {
return zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
MessageKey: "msg",
LevelKey: "level",
TimeKey: "time",
CallerKey: "file",
EncodeLevel: zapcore.CapitalLevelEncoder, //基本zapcore.LowercaseLevelEncoder。將日誌級別字符串轉化爲小寫
EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02 15:04:05"))
},
EncodeCaller: zapcore.ShortCallerEncoder, //一般zapcore.ShortCallerEncoder,以包/文件:行號 格式化調用堆棧
EncodeDuration: func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) { //一般zapcore.SecondsDurationEncoder,執行消耗的時間轉化成浮點型的秒
enc.AppendInt64(int64(d) / 1000000)
},
})
}
//日誌文件切割
func getWriter(filename string) io.Writer {
// 保存30天內的日誌,每24小時(整點)分割一次日誌
hook, err := rotatelogs.New(
filename+".%Y%m%d",
rotatelogs.WithLinkName(filename),
rotatelogs.WithMaxAge(time.Hour*24*30),
rotatelogs.WithRotationTime(time.Hour*24),
)
if err != nil {
panic(err)
}
return hook
}
//查看文件/文件夾是否存在
func Exists(path string) bool {
_, err := os.Stat(path)
if err != nil{
if os.IsExist(err){
return true
}
return false
}
return true
}
日誌效果:
分割效果: