如何配置Go的log/slog实现多输出与多格式(TextHandler、JSONHandler)
Go Slog 多输出目标Handler实现方案
Go标准库slog本身没有内置支持日志复制到多个输出目标的Handler,但有两种方案可以实现你要的效果:
一、自己实现极简的转发Handler
你可以快速实现一个符合slog.Handler接口的CopyHandler,把日志转发给多个子Handler,代码如下:
package main import ( "context" "log/slog" "os" ) // CopyHandler 转发日志到多个子Handler type CopyHandler struct { handlers []slog.Handler } // NewCopyHandler 创建多Handler转发实例 func NewCopyHandler(handlers ...slog.Handler) *CopyHandler { return &CopyHandler{handlers: handlers} } // Enabled 检查是否有子Handler启用对应日志级别 func (h *CopyHandler) Enabled(ctx context.Context, level slog.Level) bool { for _, handler := range h.handlers { if handler.Enabled(ctx, level) { return true } } return false } // Handle 将日志分发给所有子Handler func (h *CopyHandler) Handle(ctx context.Context, r slog.Record) error { for _, handler := range h.handlers { if err := handler.Handle(ctx, r); err != nil { return err // 可根据需求调整错误处理逻辑 } } return nil } // WithAttrs 为所有子Handler添加属性,返回新的CopyHandler func (h *CopyHandler) WithAttrs(attrs []slog.Attr) slog.Handler { newHandlers := make([]slog.Handler, len(h.handlers)) for i, handler := range h.handlers { newHandlers[i] = handler.WithAttrs(attrs) } return &CopyHandler{handlers: newHandlers} } // WithGroup 为所有子Handler添加分组,返回新的CopyHandler func (h *CopyHandler) WithGroup(name string) slog.Handler { newHandlers := make([]slog.Handler, len(h.handlers)) for i, handler := range h.handlers { newHandlers[i] = handler.WithGroup(name) } return &CopyHandler{handlers: newHandlers} } func main() { logger := slog.New(NewCopyHandler( slog.NewTextHandler(os.Stdout, nil), slog.NewJSONHandler(os.Stdout, nil), )) logger.Info("mytest", "attr1", "value1", "attr2", "value2") }
运行这段代码后,会同时输出文本格式和JSON格式的日志,完全符合你期望的效果。这个实现完整支持slog的所有核心特性,包括属性、分组和级别控制。
二、使用第三方扩展库
如果不想自己写代码,可以用专门的slog扩展库,比如slog-multi,它提供了开箱即用的多Handler聚合功能,还支持日志路由、过滤等进阶特性,能快速实现多输出目标的需求。
内容的提问来源于stack exchange,提问作者RubenLaguna
相关产品推荐
相关产品推荐

