为了账号安全,请及时绑定邮箱和手机立即绑定

Zap logger 是否支持转义字符 '\n' 和 '\t' 来打印换行

Zap logger 是否支持转义字符 '\n' 和 '\t' 来打印换行

Go
浮云间 2022-10-10 16:12:26
func InitLogger() {    loggerMgr, err := zap.NewProduction()    if err != nil {        log.Println("error")    }    defer loggerMgr.Sync()    logger := loggerMgr.Sugar()    logger.Error("START!")}结果{"level":"error","ts":1635248463.347698,"caller":"cgw-go-utils/main.go:36","msg":"START!","stacktrace":"main.raiseError \n\t/Users/I053322/dev/repo/cgw-go-utils/main.go:36\nmain.main\n\t/Users/I053322/dev/repo/cgw-go-utils/main.go :22\nruntime.main\n\t/usr/local/opt/go/libexec/src/runtime/proc.go:225"}我想得到逃避的结果{"level":"error","ts":1635248463.347698,"caller":"cgw-go-utils/main.go:36","msg":"START!","stacktrace":"main.raiseError    /Users/I053322/dev/repo/cgw-go-utils/main.go:36main.main    /Users/I053322/dev/repo/cgw-go-utils/main.go:22runtime.main    /usr/local/opt/go/libexec/src/runtime/proc.go:225"}
查看完整描述

2 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

不。


zap.NewProduction()返回一个带有 JSON 编码的记录器,并将转义序列\n逐字编码\t为JSON。如果没有,它就不是有效的 JSON。


如果你真的必须,并且你可以生成无效的 JSON,你可以通过装饰现有的 zap JSON 编码器来实现你自己的编码器。


示范代码:


package main


import (

    "bytes"

    "go.uber.org/zap"

    "go.uber.org/zap/buffer"

    "go.uber.org/zap/zapcore"

    "os"

)


func main() {

    core := zapcore.NewCore(

        &EscapeSeqJSONEncoder{ Encoder: zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()) },

        os.Stdout,

        zapcore.InfoLevel,

    )

    logger := zap.New(core)

    logger.Info("foo", zap.String("some_field", "foo\nbar"))

}


type EscapeSeqJSONEncoder struct {

    zapcore.Encoder

}


func (enc *EscapeSeqJSONEncoder) Clone() zapcore.Encoder {

    return enc // TODO: change me

}


func (enc *EscapeSeqJSONEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {

    // call EncodeEntry on the embedded interface to get the 

    // original output

    b, err := enc.Encoder.EncodeEntry(entry, fields)

    if err != nil {

        return nil, err

    }

    newb := buffer.NewPool().Get()


    // then manipulate that output into what you need it to be

    newb.Write(bytes.Replace(b.Bytes(), []byte("\\n"), []byte("\n"), -1))

    return newb, nil

}

输出:


{"level":"info","ts":1635257984.618096,"msg":"foo","some_field":"foo

bar"}

注意:该函数zapcore.NewCore接受一个zapcore.Encoder参数,它是一个接口。这个接口实现起来很麻烦。这个想法是将它嵌入到您的自定义结构中,以便您免费获得所有方法。


查看完整回答
反对 回复 2022-10-10
?
米脂

TA贡献1836条经验 获得超3个赞

您可以将 zap.Config 编码设置为“控制台”


zapConfig := zap.Config{

    Level:       level,

    Development: false,

    Sampling: &zap.SamplingConfig{

        Initial:    100,

        Thereafter: 100,

    },

    Encoding:         "console",

    EncoderConfig:    zapEncoderConfig,

    OutputPaths:      []string{"stderr"},

    ErrorOutputPaths: []string{"stderr"},

}


return zapConfig.Build()


查看完整回答
反对 回复 2022-10-10
  • 2 回答
  • 0 关注
  • 186 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信