Go中Zerolog日志级别差异化配置:仅终端显示ERROR级日志
问题
我在Go应用中使用zerolog库,有如下需求:
- 仅将ERROR级别的日志消息显示在终端/控制台
- 所有日志消息(无论DEBUG、INFO、WARNING、ERROR级别)均需发送至自定义Hook进行后续处理
现有代码如下:
func InitLogger(ctx context.Context, cfg *config, mc *mongo.Client) *zerolog.Logger { once.Do(func() { var multi zerolog.LevelWriter consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout, NoColor: true, TimeFormat: time.RFC3339} multi = zerolog.MultiLevelWriter(consoleWriter) logger := zerolog.New(multi).Level(zerolog.TraceLevel).With().Timestamp().Logger() logger = logger.Hook(&ZerologHook{ mClient: mc, }) zLog = &logger }) return zLog } type ZerologHook struct { mClient *mongo.Client } func (zh *ZerologHook) Run(e *zerolog.Event, level zerolog.Level, message string) { wg.Add(1) go func() { logData := LogData{} _ = zh.sendLogToMongoDB(e.GetCtx(), message, logData) wg.Done() }() }
解决方案
完全可以实现这个需求,核心是给控制台输出的Writer添加级别过滤,同时保证Hook能接收所有级别的日志。具体修改如下:
为ConsoleWriter添加级别过滤
zerolog提供了LevelWriter的包装器zerolog.LevelFilter,可以指定只让ERROR级别及以上的日志通过控制台输出。保持Logger的全局级别为TraceLevel
这样所有级别的日志都会被Hook捕获,不会被Logger本身的级别过滤掉。
修改后的完整代码:
func InitLogger(ctx context.Context, cfg *config, mc *mongo.Client) *zerolog.Logger { once.Do(func() { // 初始化控制台Writer,并添加级别过滤:仅ERROR级别 consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout, NoColor: true, TimeFormat: time.RFC3339} filteredConsoleWriter := zerolog.LevelFilter{ Level: zerolog.ErrorLevel, Writer: consoleWriter, } // 初始化Logger,全局级别设为TraceLevel以保留所有日志 logger := zerolog.New(filteredConsoleWriter).Level(zerolog.TraceLevel).With().Timestamp().Logger() // 注册自定义Hook,Hook会接收所有级别的日志 logger = logger.Hook(&ZerologHook{ mClient: mc, }) zLog = &logger }) return zLog } type ZerologHook struct { mClient *mongo.Client } func (zh *ZerologHook) Run(e *zerolog.Event, level zerolog.Level, message string) { wg.Add(1) go func() { defer wg.Done() // 建议添加defer,避免panic导致WaitGroup计数泄漏 logData := LogData{} _ = zh.sendLogToMongoDB(e.GetCtx(), message, logData) }() }
关键说明:
zerolog.LevelFilter会检查日志级别,只有大于等于指定Level的日志才会被写入对应的Writer,这里设置为zerolog.ErrorLevel,就只会输出ERROR级别的日志到控制台。- Logger的
Level(zerolog.TraceLevel)确保所有级别的日志都会被生成并传递给Hook,不会被Logger本身过滤掉。 - 额外优化:在Hook的goroutine里添加
defer wg.Done(),防止sendLogToMongoDB发生panic时导致WaitGroup计数无法减少,造成程序阻塞。
内容的提问来源于stack exchange,提问作者leonardo watch
相关产品推荐
相关产品推荐

