Golang中使用slog时如何隐藏日志KEY并自定义格式(保留日志级别)
自定义Go slog日志格式并保留级别控制
问题描述
使用Go标准库slog时,已通过programLevel.Set(slog.LevelDebug)实现日志级别动态控制,但默认TextHandler的输出格式带有time=、level=等键值前缀,希望将日志格式改为简洁的「2023/11/04 21:27:26 INFO Init driver」形式,同时保留日志级别控制功能。
现有代码
var programLevel = new(slog.LevelVar) programLevel.Set(slog.LevelDebug) h := slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel, AddSource: false}) slog.SetDefault(slog.New(h)) slog.Info("Init driver!")
当前输出
time=2023-11-04T21:07:42.208+08:00 level=INFO msg="Init driver"
期望输出
2023/11/04 21:27:26 INFO Init driver
实现方案
由于slog默认的TextHandler不支持直接修改为这种简洁格式,我们需要自定义实现slog.Handler接口,在保留级别控制逻辑的同时,自定义日志输出格式。
完整代码示例
package main import ( "context" "io" "log/slog" "os" "time" ) var programLevel = new(slog.LevelVar) // CustomHandler 自定义slog处理器,实现slog.Handler接口 type CustomHandler struct { level *slog.LevelVar // 用于控制日志级别 writer io.Writer // 日志输出目标 } // NewCustomHandler 创建自定义处理器实例 func NewCustomHandler(w io.Writer, level *slog.LevelVar) *CustomHandler { return &CustomHandler{ level: level, writer: w, } } // Enabled 判断当前日志级别是否允许输出 func (h *CustomHandler) Enabled(ctx context.Context, level slog.Level) bool { return level >= h.level.Level() } // Handle 处理日志记录,生成自定义格式的日志内容 func (h *CustomHandler) Handle(ctx context.Context, r slog.Record) error { // 格式化时间为YYYY/MM/DD HH:MM:SS格式 timeStr := r.Time.Format("2006/01/02 15:04:05") // 获取大写的级别名称(如INFO、DEBUG) levelStr := r.Level.String() // 日志消息内容 msg := r.Message // 拼接成目标格式的日志行 logLine := timeStr + " " + levelStr + " " + msg + "\n" // 将日志写入输出目标 _, err := h.writer.Write([]byte(logLine)) return err } // WithAttrs 实现接口方法,此处暂不支持附加属性(可按需扩展) func (h *CustomHandler) WithAttrs(attrs []slog.Attr) slog.Handler { return h } // WithGroup 实现接口方法,此处暂不支持分组(可按需扩展) func (h *CustomHandler) WithGroup(name string) slog.Handler { return h } func main() { // 设置初始日志级别为Debug programLevel.Set(slog.LevelDebug) // 使用自定义处理器替换默认Handler h := NewCustomHandler(os.Stderr, programLevel) slog.SetDefault(slog.New(h)) // 测试不同级别的日志输出 slog.Info("Init driver!") slog.Debug("Debug message") slog.Warn("Warning message") // 动态调整日志级别为Info,Debug日志将不再输出 programLevel.Set(slog.LevelInfo) slog.Debug("This debug message won't show up") }
关键说明
- 级别控制保留:
Enabled方法通过对比当前日志级别与programLevel的设定值,决定是否输出日志,完全保留了原有的级别动态控制能力。 - 格式自定义:在
Handle方法中,使用Go时间布局字符串"2006/01/02 15:04:05"生成目标时间格式,直接拼接级别名称与消息内容,得到简洁的日志行。 - 扩展性:如果需要支持日志附加属性(如
slog.Info("xxx", slog.String("key", "value"))),可以在Handle方法中通过r.Attrs(func(a slog.Attr) bool { ... })遍历属性并拼接进日志内容。
内容的提问来源于stack exchange,提问作者Chauncey Eller
相关产品推荐
相关产品推荐

