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

如何在Go中使用slog包编程获取当前日志级别?

在Go的slog包中编程获取当前日志级别

slog标准库本身并没有提供直接获取当前日志级别的API,但可以通过自定义或包装Handler的方式实现这一需求——核心是利用slog Handler的Enabled方法逻辑:日志是否输出由Handler的级别判断决定,我们可以在Handler中维护当前级别并暴露获取方法。

方式一:包装默认Handler实现级别获取

通过包装slog内置的TextHandler/JSONHandler,添加级别存储和获取方法:

import (
	"log/slog"
	"os"
)

type LevelHandler struct {
	level   slog.Level
	handler slog.Handler
}

func NewLevelHandler(level slog.Level, handler slog.Handler) *LevelHandler {
	return &LevelHandler{
		level:   level,
		handler: handler,
	}
}

// 实现slog.Handler接口的Enabled方法
func (h *LevelHandler) Enabled(lvl slog.Level) bool {
	return h.level <= lvl
}

// 委托其他Handler接口方法给内部handler
func (h *LevelHandler) Handle(r slog.Record) error {
	return h.handler.Handle(r)
}

func (h *LevelHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return NewLevelHandler(h.level, h.handler.WithAttrs(attrs))
}

func (h *LevelHandler) WithGroup(name string) slog.Handler {
	return NewLevelHandler(h.level, h.handler.WithGroup(name))
}

// 暴露获取当前日志级别的方法
func (h *LevelHandler) GetLogLevel() slog.Level {
	return h.level
}

// 使用示例
func main() {
	baseHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})
	levelHandler := NewLevelHandler(slog.LevelInfo, baseHandler)
	logger := slog.New(levelHandler)

	// 获取并打印当前级别
	currentLevel := levelHandler.GetLogLevel()
	logger.Info("当前日志级别", "level", currentLevel.String())
}

方式二:支持动态调整级别的线程安全实现

如果需要在运行时动态修改日志级别,需要添加同步锁保证并发安全:

import (
	"log/slog"
	"os"
	"sync"
)

type LevelHandler struct {
	mu      sync.RWMutex
	level   slog.Level
	handler slog.Handler
}

func NewLevelHandler(level slog.Level, handler slog.Handler) *LevelHandler {
	return &LevelHandler{
		level:   level,
		handler: handler,
	}
}

func (h *LevelHandler) Enabled(lvl slog.Level) bool {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return h.level <= lvl
}

func (h *LevelHandler) Handle(r slog.Record) error {
	return h.handler.Handle(r)
}

func (h *LevelHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return NewLevelHandler(h.level, h.handler.WithAttrs(attrs))
}

func (h *LevelHandler) WithGroup(name string) slog.Handler {
	return NewLevelHandler(h.level, h.handler.WithGroup(name))
}

// 获取当前日志级别(线程安全)
func (h *LevelHandler) GetLogLevel() slog.Level {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return h.level
}

// 修改当前日志级别(线程安全)
func (h *LevelHandler) SetLogLevel(level slog.Level) {
	h.mu.Lock()
	defer h.mu.Unlock()
	h.level = level
}

// 使用示例
func main() {
	baseHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{})
	levelHandler := NewLevelHandler(slog.LevelInfo, baseHandler)
	logger := slog.New(levelHandler)

	logger.Info("初始级别", "level", levelHandler.GetLogLevel().String())
	// 动态调整级别
	levelHandler.SetLogLevel(slog.LevelDebug)
	logger.Debug("调整后级别生效", "level", levelHandler.GetLogLevel().String())
}

注意事项

  • 若使用第三方slog Handler(如各种适配器),优先查看其是否自带级别获取方法;若没有,同样可以用上述包装方式实现。
  • 不要直接访问slog内部的私有字段来获取级别,这会导致代码依赖未公开的实现细节,版本更新时极易出错。

内容的提问来源于stack exchange,提问作者Fabrice Jammes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:16:15