golang?日志庫ZAP[uber-go?zap]示例詳解
golang 日志庫ZAP[uber-go zap]
1. 簡要說明
zap 是 uber 開源的 Go 高性能日志庫,支持不同的日志級別, 能夠打印基本信息等,但不支持日志的分割,這里我們可以使用 lumberjack 也是 zap 官方推薦用于日志分割,結(jié)合這兩個庫我們就可以實現(xiàn)以下功能的日志機制:
能夠?qū)⑹录涗浀轿募?,而不是?yīng)用程序控制臺;日志切割能夠根據(jù)文件大小、時間或間隔等來切割日志文件;支持不同的日志級別,例如 DEBUG , INFO , WARN , ERROR 等;能夠打印基本信息,如調(diào)用文件、函數(shù)名和行號,日志時間等;官網(wǎng)地址:https://github.com/uber-go/zap
2. 下載安裝
// 初始化go mod 通過mod管理擴展包 go mod init zaplog //使用下面命令安裝 go get -u go.uber.org/zap //如果下載失敗,則使用以下命令重新下載安裝 go get github.com/uber-go/zap //下載安裝成功后還有如下提示: package github.com/uber-go/zap: code in directory src/github.com/uber-go/zap expects import "go.uber.org/zap"
3. 配置 zap Logger
zap 提供了兩種類型的日志記錄器—和 Logger 和 Sugared Logger 。兩者之間的區(qū)別是:
- 在每一微秒和每一次內(nèi)存分配都很重要的上下文中,使用Logger。它甚至比SugaredLogger更快,內(nèi)存分配次數(shù)也更少,但它只支持強類型的結(jié)構(gòu)化日志記錄。
- 在性能很好但不是很關(guān)鍵的上下文中,使用SugaredLogger。它比其他結(jié)構(gòu)化日志記錄包快 4-10 倍,并且支持結(jié)構(gòu)化和 printf 風格的日志記錄。
- 所以一般場景下我們使用 Sugared Logger 就足夠了。
3.1 Logger
- 通過調(diào)用zap.NewProduction()/zap.NewDevelopment()或者zap.NewExample()創(chuàng)建一個 Logger 。
- 上面的每一個函數(shù)都將創(chuàng)建一個 logger 。唯一的區(qū)別在于它將記錄的信息不同。例如 production logger 默認記錄調(diào)用函數(shù)信息、日期和時間等。
- 通過 Logger 調(diào)用 INFO 、 ERROR 等。
- 默認情況下日志都會打印到應(yīng)用程序的 console 界面。
3.1.1 NewExample
//代碼示例: package main import ( "go.uber.org/zap" ) func main() { log := zap.NewExample() log.Debug("this is debug message") log.Info("this is info message") log.Info("this is info message with fileds", zap.Int("age", 24), zap.String("agender", "man")) log.Warn("this is warn message") log.Error("this is error message") log.Panic("this is panic message") } //輸出結(jié)果: {"level":"debug","msg":"this is debug message"} {"level":"info","msg":"this is info message"} {"level":"info","msg":"this is info message with fileds","age":24,"agender":"man"} {"level":"warn","msg":"this is warn message"} {"level":"error","msg":"this is error message"} {"level":"panic","msg":"this is panic message"} panic: this is panic message
3.1.2 NewDevelopment
//代碼示例: func main() { log, _ := zap.NewDevelopment() log.Debug("this is debug message") log.Info("this is info message") log.Info("this is info message with fileds", zap.Int("age", 24), zap.String("agender", "man")) log.Warn("this is warn message") log.Error("this is error message") // log.DPanic("This is a DPANIC message") // log.Panic("this is panic message") // log.Fatal("This is a FATAL message") } //輸出結(jié)果: 2020-06-12T18:51:11.457+0800 DEBUG task/main.go:9 this is debug message 2020-06-12T18:51:11.457+0800 INFO task/main.go:10 this is info message 2020-06-12T18:51:11.457+0800 INFO task/main.go:11 this is info message with fileds {"age": 24, "agender": "man"} 2020-06-12T18:51:11.457+0800 WARN task/main.go:13 this is warn message main.main /home/wohu/GoCode/src/task/main.go:13 runtime.main /usr/local/go/src/runtime/proc.go:200 2020-06-12T18:51:11.457+0800 ERROR task/main.go:14 this is error message main.main /home/wohu/GoCode/src/task/main.go:14 runtime.main /usr/local/go/src/runtime/proc.go:200
3.1.3 NewProduction
代碼示例: func main() { log, _ := zap.NewProduction() log.Debug("this is debug message") log.Info("this is info message") log.Info("this is info message with fileds", zap.Int("age", 24), zap.String("agender", "man")) log.Warn("this is warn message") log.Error("this is error message") // log.DPanic("This is a DPANIC message") // log.Panic("this is panic message") // log.Fatal("This is a FATAL message") } 輸出結(jié)果: {"level":"info","ts":1591959367.316352,"caller":"task/main.go:10","msg":"this is info message"} {"level":"info","ts":1591959367.3163702,"caller":"task/main.go:11","msg":"this is info message with fileds","age":24,"agender":"man"} {"level":"warn","ts":1591959367.3163917,"caller":"task/main.go:13","msg":"this is warn message"} {"level":"error","ts":1591959367.3163974,"caller":"task/main.go:14","msg":"this is error message","stacktrace":"main.main\n\t/home/wohu/GoCode/src/task/main.go:14\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:200"}
3.1.4 對比總結(jié)
Example和Production使用的是 json 格式輸出,Development 使用行的形式輸出
- Development
- 從警告級別向上打印到堆棧中來跟蹤
- 始終打印包/文件/行(方法)
- 在行尾添加任何額外字段作為 json 字符串
- 以大寫形式打印級別名稱
- 以毫秒為單位打印 ISO8601 格式的時間戳
- Production
- 調(diào)試級別消息不記錄
- Error , Dpanic 級別的記錄,會在堆棧中跟蹤文件, Warn 不會
- 始終將調(diào)用者添加到文件中
- 以時間戳格式打印日期
- 以小寫形式打印級別名稱
- 在上面的代碼中,我們首先創(chuàng)建了一個 Logger ,然后使用 Info / Error 等 Logger 方法記錄消息。
日志記錄器方法的語法是這樣的:
func (log *Logger) MethodXXX(msg string, fields ...Field)
其中 MethodXXX 是一個可變參數(shù)函數(shù),可以是 Info / Error / Debug / Panic 等。每個方法都接受一個消息字符串和任意數(shù)量的 zapcore.Field 長參數(shù)。
每個 zapcore.Field 其實就是一組鍵值對參數(shù)。
3.2 Sugared Logger
默認的 zap 記錄器需要結(jié)構(gòu)化標簽,即對每個標簽,需要使用特定值類型的函數(shù)。
log.Info("this is info message with fileds",zap.Int("age", 24), zap.String("agender", "man"))
雖然會顯的很長,但是對性能要求較高的話,這是最快的選擇。也可以使用suger logger, 它基于 printf 分割的反射類型檢測,提供更簡單的語法來添加混合類型的標簽。
我們使用 Sugared Logger 來實現(xiàn)相同的功能。
- 大部分的實現(xiàn)基本都相同;
- 惟一的區(qū)別是,我們通過調(diào)用主 logger 的.Sugar()方法來獲取一個SugaredLogger;
- 然后使用SugaredLogger以printf格式記錄語句;
func main() { logger, _ := zap.NewDevelopment() slogger := logger.Sugar() slogger.Debugf("debug message age is %d, agender is %s", 19, "man") slogger.Info("Info() uses sprint") slogger.Infof("Infof() uses %s", "sprintf") slogger.Infow("Infow() allows tags", "name", "Legolas", "type", 1) } //輸出結(jié)果: 2020-06-12T19:23:54.184+0800 DEBUG task/main.go:11 debug message age is 19, agender is man 2020-06-12T19:23:54.185+0800 INFO task/main.go:12 Info() uses sprint 2020-06-12T19:23:54.185+0800 INFO task/main.go:13 Infof() uses sprintf 2020-06-12T19:23:54.185+0800 INFO task/main.go:14 Infow() allows tags {"name": "Legolas", "type": 1}
如果需要,可以隨時使用記錄器上的 .Desugar() 方法從 sugar logger 切換到標準記錄器。
log := slogger.Desugar() log.Info("After Desugar; INFO message") log.Warn("After Desugar; WARN message") log.Error("After Desugar; ERROR message")
4. 將日志寫入文件
我們將使用zap.New(…)方法來手動傳遞所有配置,而不是使用像zap.NewProduction()這樣的預(yù)置方法來創(chuàng)建 logger 。
func New(core zapcore.Core, options ...Option) *Logger
zapcore.Core需要三個配置——Encoder,WriteSyncer,LogLevel。
Encoder :編碼器(如何寫入日志)。我們將使用開箱即用的 NewConsoleEncoder() ,并使用預(yù)先設(shè)置的 ProductionEncoderConfig() 。
zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig())
WriterSyncer :指定日志將寫到哪里去。我們使用 zapcore.AddSync() 函數(shù)并且將打開的文件句柄傳進去。
file, _ := os.Create("./test.log") writeSyncer := zapcore.AddSync(file)
Log Level :哪種級別的日志將被寫入。
// 代碼示例: package main import ( "os" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) var sugarLogger *zap.SugaredLogger func InitLogger() { encoder := getEncoder() writeSyncer := getLogWriter() core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel) // zap.AddCaller() 添加將調(diào)用函數(shù)信息記錄到日志中的功能。 logger := zap.New(core, zap.AddCaller()) sugarLogger = logger.Sugar() } func getEncoder() zapcore.Encoder { encoderConfig := zap.NewProductionEncoderConfig() encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // 修改時間編碼器 // 在日志文件中使用大寫字母記錄日志級別 encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder // NewConsoleEncoder 打印更符合人們觀察的方式 return zapcore.NewConsoleEncoder(encoderConfig) } func getLogWriter() zapcore.WriteSyncer { file, _ := os.Create("./test.log") return zapcore.AddSync(file) } func main() { InitLogger() sugarLogger.Info("this is info message") sugarLogger.Infof("this is %s, %d", "aaa", 1234) sugarLogger.Error("this is error message") sugarLogger.Info("this is info message") } // 輸出日志文件: 2020-06-16T09:01:06.192+0800 INFO task/main.go:40 this is info message 2020-06-16T09:01:06.192+0800 INFO task/main.go:41 this is aaa, 1234 2020-06-16T09:01:06.192+0800 ERROR task/main.go:42 this is error message 2020-06-16T09:01:06.192+0800 INFO task/main.go:43 this is info message
到此這篇關(guān)于golang 日志庫ZAP[uber-go zap]詳解的文章就介紹到這了,更多相關(guān)golang 日志庫ZAP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang 類型轉(zhuǎn)換的實現(xiàn)(斷言、強制、顯式類型)
將一個值從一種類型轉(zhuǎn)換到另一種類型,便發(fā)生了類型轉(zhuǎn)換,在go可以分為斷言、強制、顯式類型轉(zhuǎn)換,本文就詳細的介紹一下這就幾種轉(zhuǎn)換方式,具有一定的參考價值,感興趣的可以了解一下2023-09-09Golang常用環(huán)境變量說明與設(shè)置詳解
這篇文章主要介紹了Golang常用環(huán)境變量說明與設(shè)置,需要的朋友可以參考下2020-02-02Qt6.5 grpc組件使用 + golang grpc server
這篇文章主要介紹了Qt6.5 grpc組件使用+golang grpc server示例,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05