Zap 记录器是否支持转义字符 '\n' 和 '\t' 来打印换行符 errorVerbose 或 stacktrace
Does Zap logger support escape character '\n' and '\t' to print new line errorVerbose or stacktrace
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:36
main.main
/Users/I053322/dev/repo/cgw-go-utils/main.go:22
runtime.main
/usr/local/opt/go/libexec/src/runtime/proc.go:225"}
没有
zap.NewProduction()
returns 使用 JSON 编码的记录器,转义序列如 \n
和 \t
被编码 verbatim 变成 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
参数,它是一个接口。这个接口实现起来很麻烦。这个想法是将它嵌入到您的自定义结构中,这样您就可以免费获得所有方法。
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:36
main.main
/Users/I053322/dev/repo/cgw-go-utils/main.go:22
runtime.main
/usr/local/opt/go/libexec/src/runtime/proc.go:225"}
没有
zap.NewProduction()
returns 使用 JSON 编码的记录器,转义序列如 \n
和 \t
被编码 verbatim 变成 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
参数,它是一个接口。这个接口实现起来很麻烦。这个想法是将它嵌入到您的自定义结构中,这样您就可以免费获得所有方法。