[uber-zap/part3]自定義記錄器
說明
- 之前翻譯的一個教程(沒有備份原地址,梯子被封了)。原地址找到後補上
正文
zap 提供的欄位編碼器並一定完全合適自己的需求,比如:希望日誌記錄的輸出和syslog或者其他常見的日誌格式類似;可能希望日誌中的時間戳忽略秒;將日誌包含在方括號內等,這時候就需要自定義編碼器了
效能因素
你可以自定義編碼器time
,leve
,caller
等。需要注意的是,編碼器要儘可能高效,因為這是zap的記憶體、效能上的優勢,畢竟每個日誌行都要呼叫這些函式。所以要避免建立臨時變數或者進行任何高強度的計算。
也就是說,下面的例子只是一個示範,不一定就是預設功能的最佳替代品。
自定義時間戳格式
這是一個常見的syslog格式的實現
func SyslogTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("jan 2 15:04:05")) } func main() { cfg := zap.Config{ Encoding:"console", Level:zap.NewAtomicLevelAt(zap.DebugLevel), OutputPaths: []string{"stderr"}, EncoderConfig: zapcore.EncoderConfig{ MessageKey: "message", TimeKey: "time", }, } cfg.EncoderConfig.EncodeTime = SyslogTimeEncoder logger, _ := cfg.Build() logger.Info("This should have a syslog style timestamp") }
輸出
jan 1 09:22:59This should have a syslog style timestamp
應該注意到,編碼器應該將基元(primitives)附加到物件陣列。zap使用此陣列以最小的記憶體分配有效的編碼輸出
自定義級別格式
func CustomLevelEncoder(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString("[" + level.CapitalString() + "]") } func main() { cfg := zap.Config{ Encoding:"console", Level:zap.NewAtomicLevelAt(zap.DebugLevel), OutputPaths: []string{"stderr"}, EncoderConfig: zapcore.EncoderConfig{ MessageKey: "message", LevelKey: "level", }, } cfg.EncoderConfig.EncodeLevel = CustomLevelEncoder logger, _ := cfg.Build() logger.Info("This should have a bracketed level name") }
輸出
[INFO]This should have a bracketed level name
注意:上面示例中,拼接多個子字串形成一個字串,並附加到陣列中。這可能會導致臨時記憶體分配。我不得不這樣做,如果我單獨附加子串,zap會將他們視為輸出中的單獨欄位,並將它們用空格隔開