如何为Go的Zap日志库所有日志消息添加指定前缀?
问题
已通过以下配置完成Zap日志库的搭建:
outLevel := zap.LevelEnablerFunc(func(level zapcore.Level) bool { return level < zapcore.WarnLevel }) // Warnings and everything above will be printed to stderr errorLevel := zap.LevelEnablerFunc(func(level zapcore.Level) bool { return level >= zapcore.WarnLevel }) stdoutSyncer := zapcore.Lock(os.Stdout) stderrSyncer := zapcore.Lock(os.Stderr) config := zap.NewDevelopmentConfig() config.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder config.EncoderConfig.TimeKey = "" core := zapcore.NewTee( zapcore.NewCore( zapcore.NewConsoleEncoder(config.EncoderConfig), stdoutSyncer, outLevel, ), zapcore.NewCore( zapcore.NewConsoleEncoder(config.EncoderConfig), stderrSyncer, errorLevel, ), ) logger := zap.New(core) zap.ReplaceGlobals(logger)
希望实现类似Go标准库log的SetPrefix功能,为所有DEBUG、INFO级别的日志消息添加前缀"=>"。例如执行:
zap.L().Info("this is new message")
最终日志输出格式为:
=> this is new message
尝试使用log.With API,但生成的是JSON对象,不符合需求,寻求解决方案。
解决方案
无需使用With API(它会添加结构化字段导致JSON格式输出),可以通过自定义ConsoleEncoder的消息编码逻辑实现需求,具体代码如下:
import ( "os" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) func main() { outLevel := zap.LevelEnablerFunc(func(level zapcore.Level) bool { return level < zapcore.WarnLevel }) errorLevel := zap.LevelEnablerFunc(func(level zapcore.Level) bool { return level >= zapcore.WarnLevel }) stdoutSyncer := zapcore.Lock(os.Stdout) stderrSyncer := zapcore.Lock(os.Stderr) config := zap.NewDevelopmentConfig() config.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder config.EncoderConfig.TimeKey = "" // 自定义带前缀的ConsoleEncoder customEncoder := func(cfg zapcore.EncoderConfig) zapcore.Encoder { baseEncoder := zapcore.NewConsoleEncoder(cfg) return &prefixEncoder{base: baseEncoder} } core := zapcore.NewTee( zapcore.NewCore( customEncoder(config.EncoderConfig), stdoutSyncer, outLevel, ), zapcore.NewCore( zapcore.NewConsoleEncoder(config.EncoderConfig), // 错误级别保持原格式 stderrSyncer, errorLevel, ), ) logger := zap.New(core) zap.ReplaceGlobals(logger) // 测试输出 zap.L().Info("this is new message") zap.L().Debug("debug message") zap.L().Warn("warn message") } // prefixEncoder 包装原生ConsoleEncoder,给特定级别消息添加前缀 type prefixEncoder struct { base zapcore.Encoder } func (e *prefixEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) ([]byte, error) { // 仅给DEBUG和INFO级别日志添加前缀 if entry.Level == zapcore.DebugLevel || entry.Level == zapcore.InfoLevel { entry.Message = "=> " + entry.Message } return e.base.EncodeEntry(entry, fields) } func (e *prefixEncoder) Clone() zapcore.Encoder { return &prefixEncoder{base: e.base.Clone()} }
核心逻辑说明:
- 定义
prefixEncoder结构体包装原生ConsoleEncoder,重写EncodeEntry方法 - 在
EncodeEntry中判断日志级别,仅对DEBUG/INFO级消息添加前缀"=>" - 错误级别(Warn及以上)保留原编码器,维持原有输出格式
- 该方案不会引入结构化字段,完全符合纯文本控制台输出的需求
内容的提问来源于stack exchange,提问作者Viren
相关产品推荐
相关产品推荐

