如何在 uber-zap 的鉤子中訪問有關日志事件的完整資訊?
例如,我試圖將 a 添加zapcore.Field到日志記錄事件中,但它沒有顯示在zapcore.Entry.
如果不可能,我至少可以以某種方式獲得完全格式化的字串嗎?目標是在出現錯誤時發送電子郵件/自動訊息/哨兵/等。
package main
import (
"log"
"github.com/davecgh/go-spew/spew"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func main() {
prodLogger, err := zap.NewProduction(zap.Hooks(func(entry zapcore.Entry) error {
if entry.Level == zapcore.ErrorLevel {
spew.Dump(entry) // fancy console printer
}
return nil
}))
if err != nil {
log.Fatal(err)
}
prodLogger.
Named("logger_name").
Error("something happened", zap.String("foo", "bar"))
}
輸出 - 沒有foo或 的痕跡bar:
{"level":"error","ts":1640722252.899601,"logger":"logger_name","caller":"awesomep2/main.go:23","msg":"something happened","foo":"bar","stacktrace":"main.main\n\t/Users/xxx/GitHub/awesomep2/main.go:23\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:255"}
(zapcore.Entry) {
Level: (zapcore.Level) error,
Time: (time.Time) 2021-12-28 13:10:52.899601 -0700 MST m= 0.000629089,
LoggerName: (string) (len=11) "logger_name",
Message: (string) (len=18) "something happened",
Caller: (zapcore.EntryCaller) /Users/xxx/GitHub/awesomep2/main.go:23,
Stack: (string) (len=103) "main.main\n\t/Users/xxx/GitHub/awesomep2/main.go:23\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:255"
}
uj5u.com熱心網友回復:
欄位在 Zap 掛鉤中不可用。的檔案zap.Hooks明確地說:
[...] Hooks 對于簡單的副作用很有用,例如捕獲已發出日志數量的指標。更復雜的副作用,包括任何需要訪問條目的結構化欄位的東西,都應該作為 zapcore.Core 來實作。[...]
因此,要使用 go-spew 轉儲日志,您需要一個自定義核心。您有兩個主要選擇。
帶有自定義編碼器的自定義內核
這具有允許更多定制的優點。
條目的欄位在zapcore.Encoder.EncodeEntry. 與往常一樣,策略是將 a 嵌入zapcore.Encoder到您的結構中并重新實作EncodeEntry:
type spewDumpEncoder struct {
zapcore.Encoder
}
func (e *spewDumpEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
if entry.Level == zapcore.ErrorLevel {
spew.Dump(entry, fields)
}
return e.Encoder.EncodeEntry(entry, fields)
}
Clone()如果您計劃使用結構化日志記錄,請記住也實施。
定制核心 Write
這具有允許更簡單初始化的優點。
與第一個選項類似,zapcore.Core也是一個介面,因此您可以通過嵌入到結構中來實作它,并且僅重新實作Write:
type MyCore struct {
zapcore.Core
}
func (c *MyCore) Write(entry zapcore.Entry, fields []zapcore.Field) error {
if entry.Level == zapcore.ErrorLevel {
spew.Dump(entry, fields)
}
return c.Core.Write(entry, fields)
}
并通過從默認 zap 記錄器中獲取現有核心來實體化它:
l, _ := zap.NewProduction()
logger := zap.New(&MyCore{Core: l.Core()})
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/400789.html
上一篇:如何從go傳遞訊息并使用rabbitmq從nestjs使用它?
下一篇:Docker GolangHTTPS問題。OpenSSLSSL_connect:SSL_ERROR_SYSCALL
