亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么在 Uber Zap 中調用 logger.With 后自定義編碼會丟失?

為什么在 Uber Zap 中調用 logger.With 后自定義編碼會丟失?

Go
ibeautiful 2022-10-24 09:20:53
我用自定義的編碼器替換了我的 uber-zap 記錄器的編碼器,以在每個日志條目前加上 SystemD 友好的錯誤級別 ( <LEVEL>),但是現在在我使用帶有附加字段 ( With(fields ...Field)) 的記錄器后,自定義的前置就消失了:package mainimport (    "os"    "go.uber.org/zap"    "go.uber.org/zap/buffer"    "go.uber.org/zap/zapcore")func getConfig() zap.Config {    // your current config options    return zap.NewProductionConfig()}type prependEncoder struct {    // embed a zapcore encoder    // this makes prependEncoder implement the interface without extra work    zapcore.Encoder    // zap buffer pool    pool buffer.Pool}// EncodeEntry implementing only EncodeEntryfunc (e *prependEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {    // new log buffer    buf := e.pool.Get()    // prepend the JournalD prefix based on the entry level    buf.AppendString(e.toJournaldPrefix(entry.Level))    buf.AppendString(" ")    // calling the embedded encoder's EncodeEntry to keep the original encoding format    consolebuf, err := e.Encoder.EncodeEntry(entry, fields)    if err != nil {        return nil, err    }    // just write the output into your own buffer    _, err = buf.Write(consolebuf.Bytes())    if err != nil {        return nil, err    }    return buf, nil}// some mapper functionfunc (e *prependEncoder) toJournaldPrefix(lvl zapcore.Level) string {    switch lvl {    case zapcore.DebugLevel:        return "<7>"    case zapcore.InfoLevel:        return "<6>"    case zapcore.WarnLevel:        return "<4>"    }    return ""}func main() {    cfg := getConfig()    // constructing our prependEncoder with a ConsoleEncoder using your original configs    enc := &prependEncoder{        Encoder: zapcore.NewConsoleEncoder(cfg.EncoderConfig),        pool:    buffer.NewPool(),    }我得到的輸出是:<6> 1.640656130756576e+09   info    this is info<7> 1.640656130756611e+09   debug   this is debug<4> 1.640656130756615e+09   warn    this is warn1.6406561307566311e+09  info    this does not have the prefix :(    {"foo": "bar"}我究竟做錯了什么?
查看完整描述

1 回答

?
滄海一幻覺

TA貢獻1824條經驗 獲得超5個贊

您還必須Clone()從zapcore.Encoder接口實現。如果您希望保持父記錄器不變,則必須構建一個實際的克隆——可能具有相同的配置,因此您可能希望將其存儲為一個字段:


type prependEncoder struct {

    zapcore.Encoder

    pool buffer.Pool

    cfg  zapcore.EncoderConfig

}


func (e *prependEncoder) Clone() zapcore.Encoder {

    return &prependEncoder{

        // cloning the encoder with the base config

        Encoder: zapcore.NewConsoleEncoder(e.cfg),

        pool:    buffer.NewPool(),

        cfg:     e.cfg,

    }

}

如果你不實現它,運行的方法是調用時下一個最淺的方法logger.Clone(),它是Clone()在嵌入的聲明的zapcore.Encoder。那一個就沒有你的習慣EncodeEntry了。


現在運行以下命令:


    logger.Info("this is info")

    logger.Debug("this is debug")

    logger.Warn("this is warn")

    child := logger.With(zap.String("foo", "bar"))

    logger.Warn("original")

    child.Info("new one")

輸出:


<6> INFO        this is info

<7> DEBUG       this is debug

<4> WARN        this is warn

cloning...

<4> WARN        original

<6> INFO        new one {"foo": "bar"}


查看完整回答
反對 回復 2022-10-24
  • 1 回答
  • 0 關注
  • 115 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號