You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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")
}

关键说明

  1. 级别控制保留:Enabled方法通过对比当前日志级别与programLevel的设定值,决定是否输出日志,完全保留了原有的级别动态控制能力。
  2. 格式自定义:在Handle方法中,使用Go时间布局字符串"2006/01/02 15:04:05"生成目标时间格式,直接拼接级别名称与消息内容,得到简洁的日志行。
  3. 扩展性:如果需要支持日志附加属性(如slog.Info("xxx", slog.String("key", "value"))),可以在Handle方法中通过r.Attrs(func(a slog.Attr) bool { ... })遍历属性并拼接进日志内容。

内容的提问来源于stack exchange,提问作者Chauncey Eller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 22:13:16