golang有用的庫及工具 之 zap.Logger包的使用指南
zap.Logger 是go語言中相對日誌庫中效能最高的。那麼如何開始使用?
不多說直接上程式碼:
import ( "encoding/json" "fmt" "log" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) var Logger *zap.Logger func InitLogger() { // 日誌地址 "out.log" 自定義 lp := Conf.Common.LogPath // 日誌級別 DEBUG,ERROR,INFO lv := Conf.Common.LogLevel // 是否 DEBUG isDebug := true if Conf.Common.IsDebug != true { isDebug = false } initLogger(lp,lv,isDebug) log.SetFlags(log.Lmicroseconds | log.Lshortfile | log.LstdFlags) } func initLogger(lp string,lv string,isDebug bool) { var js string if isDebug { js = fmt.Sprintf(`{ "level": "%s","encoding": "json","outputPaths": ["stdout"],"errorOutputPaths": ["stdout"] }`,lv) } else { js = fmt.Sprintf(`{ "level": "%s","outputPaths": ["%s"],"errorOutputPaths": ["%s"] }`,lp,lp) } var cfg zap.Config if err := json.Unmarshal([]byte(js),&cfg); err != nil { panic(err) } cfg.EncoderConfig = zap.NewProductionEncoderConfig() cfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder var err error Logger,err = cfg.Build() if err != nil { log.Fatal("init logger error: ",err) } }
如何使用:
func TestInitLogger(t *testing.T) { InitLogger("out.log","DEBUG",false) s := []string{ "hello info","hello error","hello debug","hello fatal",} Log.Info("info:",zap.String("s",s[0])) Log.Error("info:",s[1])) Log.Debug("info:",s[2])) Log.Fatal("info:",s[3])) }
輸出:
{"level":"info","ts":"2017-10-25 13:45:42.332","caller":"logger/logger_test.go:16","msg":"info:","s":"hello info"} {"level":"error","ts":"2017-10-25 13:45:42.396","caller":"logger/logger_test.go:17","s":"hello error","stacktrace":"go.uber.org/zap.Stack\n\tD:/gopath/src/go.uber.org/zap/field.go:191\ngo.uber.org/zap.(*Logger).check\n\tD:/gopath/src/go.uber.org/zap/logger.go:301\ngo.uber.org/zap.(*Logger).Error\n\tD:/gopath/src/go.uber.org/zap/logger.go:202\ngithub.com/corego/hermes/logger.TestInitLogger\n\tD:/gopath/src/github.com/corego/hermes/logger/logger_test.go:17\ntesting.tRunner\n\tD:/Program Files (x86)/go/src/testing/testing.go:746"} {"level":"debug","caller":"logger/logger_test.go:18","s":"hello debug"} {"level":"fatal","caller":"logger/logger_test.go:19","s":"hello fatal","stacktrace":"go.uber.org/zap.Stack\n\tD:/gopath/src/go.uber.org/zap/field.go:191\ngo.uber.org/zap.(*Logger).check\n\tD:/gopath/src/go.uber.org/zap/logger.go:301\ngo.uber.org/zap.(*Logger).Fatal\n\tD:/gopath/src/go.uber.org/zap/logger.go:235\ngithub.com/corego/hermes/logger.TestInitLogger\n\tD:/gopath/src/github.com/corego/hermes/logger/logger_test.go:19\ntesting.tRunner\n\tD:/Program Files (x86)/go/src/testing/testing.go:746"}
拓展:Golang成長之路:使用Zap來做日誌服務
我們在專案中,經常會記錄一些資料資訊到檔案中,或者日誌檔案。
例如nginx會有nginx訪問請求日誌,使用golang的時候,我也想做一個這樣的訪問日誌,所以我就找到了go的一個開源高效的日誌庫zap。
很多人也使用logrus或者go自帶的Logger(支援的東西太少,效能一般),具體為啥最後選擇了zap,是因為很多人說zap效能更高些,當然我自己沒有測試過。
1、安裝zap
go get -u go.uber.org/zap
如果沒反應,可能需要配置下代理,
go env -w GOPROXY=https://goproxy.cn
然後在執行安裝的命令。
2、簡單例項(預設配置)
Zap提供了兩種型別的日誌記錄器—Sugared Logger和Logger。
package main import ( "go.uber.org/zap" "time" ) func main() { // zap.NewDevelopment 格式化輸出 logger,_ := zap.NewDevelopment() defer logger.Sync() logger.Info("測試",zap.String("url","http://www.baidu.com"),zap.Int("attempt",3),zap.Duration("backoff",time.Second),) // zap.NewProduction json序列化輸出 logger,_ := zap.NewProduction() defer logger.Sync() logger.Info("測試",) }
3、自定義配置
封裝好一個logger包
package logger import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "time" "fmt" ) var sugarLogger *zap.SugaredLogger //格式化日期 func formatEncodeTime(t time.Time,enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(fmt.Sprintf("%d-%02d-%02d %02d:%02d:%02d",t.Year(),t.Month(),t.Day(),t.Hour(),t.Minute(),t.Second())) } func InitConfig() *zap.SugaredLogger { encoderConfig := zapcore.EncoderConfig{ TimeKey: "ts",LevelKey: "level",NameKey: "logger",CallerKey: "caller",MessageKey: "msg",StacktraceKey: "stacktrace",LineEnding: zapcore.DefaultLineEnding,EncodeLevel: zapcore.LowercaseLevelEncoder,// 小寫編碼器 EncodeTime: formatEncodeTime,//時間格式 EncodeDuration: zapcore.SecondsDurationEncoder,EncodeCaller: zapcore.FullCallerEncoder,// 全路徑編碼器 } // 設定日誌級別(預設info級別,可以根據需要設定級別) atom := zap.NewAtomicLevelAt(zap.InfoLevel) config := zap.Config{ Level: atom,// 日誌級別 Development: true,// 開發模式,堆疊跟蹤 Encoding: "json",// 輸出格式 console 或 json EncoderConfig: encoderConfig,// 編碼器配置 OutputPaths: []string{"stdout",'需要寫入檔案的路徑'},// 日誌寫入檔案的地址 ErrorOutputPaths: []string{"stderr",// 將系統內的error記錄到檔案的地址 } // 構建日誌 logger,_ := config.Build() sugarLogger = logger.Sugar() return sugarLogger } func Debug(args ...interface{}) { sugarLogger.Debug(args...) } func Debugf(template string,args ...interface{}) { sugarLogger.Debugf(template,args...) } func Info(args ...interface{}) { sugarLogger.Info(args...) } func Infof(template string,args ...interface{}) { sugarLogger.Infof(template,args...) } func Infow(template string,args ...interface{}) { sugarLogger.Infow(template,args...) } func Warn(args ...interface{}) { sugarLogger.Warn(args...) } func Warnf(template string,args ...interface{}) { sugarLogger.Warnf(template,args...) } func Error(args ...interface{}) { sugarLogger.Error(args...) } func Errorf(template string,args ...interface{}) { sugarLogger.Errorf(template,args...) } func DPanic(args ...interface{}) { sugarLogger.DPanic(args...) } func DPanicf(template string,args ...interface{}) { sugarLogger.DPanicf(template,args...) } func Panic(args ...interface{}) { sugarLogger.Panic(args...) } func Panicf(template string,args ...interface{}) { sugarLogger.Panicf(template,args...) } func Fatal(args ...interface{}) { sugarLogger.Fatal(args...) } func Fatalf(template string,args ...interface{}) { sugarLogger.Fatalf(template,args...) }
EncoderConfig配置說明
MessageKey:輸入資訊的key名
LevelKey:輸出日誌級別的key名
TimeKey:輸出時間的key名
NameKey CallerKey StacktraceKey跟以上類似,看名字就知道
LineEnding:每行的分隔符。基本zapcore.DefaultLineEnding 即"\n"
EncodeLevel:基本zapcore.LowercaseLevelEncoder。將日誌級別字串轉化為小寫
EncodeTime:輸出的時間格式
EncodeDuration:一般zapcore.SecondsDurationEncoder,執行消耗的時間轉化成浮點型的秒
EncodeCaller:一般zapcore.ShortCallerEncoder,以包/檔案:行號 格式化呼叫堆疊
EncodeName:可選值。
使用案例
package main import ( "logger"//匯入寫好的包(具體需要改為自己寫的路徑) ) func main() { //初始化日誌配置 logger.InitConfig() //寫入檔案 logger.Infow("access_log","code",200,"ip",192.168.1.1,"Method","POST","url","www.baidu.com","latencyTime(ms)",1000,) }
好了,這就是自己搗鼓的zap使用方法,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。