跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

Go语言如何用slog_Go语言slog标准日志教程【完整】

slog 默认不输出日志因使用空 handler,需显式设置带选项的 TextHandler 或 JSONHandler 并调用 slog.SetDefault;Debug 级别默认被过滤,须通过 HandlerOptions.Level 配置 LevelVar 才生效。 slog 是 Go 1.21+ 官方推荐的日志方案,但直接用
slog.New
默认输出是无格式、无时间戳、无调用位置的,不适用于生产环境。 为什么默认的
slog.New
看起来像没生效 Go 标准库的
slog
默认使用
slog.Handler
的最简实现(
slog.TextHandler
或
slog.JSONHandler
)需要显式传入,否则
slog.New
返回的是一个“空 handler”——它会静默丢弃所有日志。 常见错误现象:
slog.Info("hello")
运行后控制台完全没输出,也没报错 根本原因:没设置全局 logger,也没给
slog.New
传 handler;
slog.Default()
在未初始化时也返回空 handler 正确做法:必须显式构造带 handler 的 logger,并用
slog.SetDefault
激活,或直接用该 logger 实例 示例:
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, nil))) slog.Info("server started", "port", ":8080")
slog.TextHandler
和
slog.JSONHandler
怎么选 两者性能接近,差异主要在可读性、解析友好性和调试成本上。
slog.TextHandler
:适合本地开发、CI 日志查看,人类可读,但字段顺序不固定,无法被结构化日志系统(如 Loki、Datadog)自动解析
slog.JSONHandler
:字段名固定、嵌套清晰,能被大多数日志收集器识别;但单行 JSON 不易肉眼扫读,调试时需格式化 注意:
slog.JSONHandler
默认不输出时间戳和程序位置,需手动加
slog.HandlerOptions{AddSource: true, AddTime: true}
示例(带时间 + 文件行号):
h := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ AddTime: true, AddSource: true, }) slog.SetDefault(slog.New(h))
如何加自定义字段(比如 request_id、trace_id)
slog
不支持全局 context 字段(不像 zap 的
With
),必须每次调用时显式传入,或封装一层。 go语言参考手册 中文CHM版 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译 下载 立即学习 “ go语言免费学习笔记(深入) ”; 直接传参:每次写
slog.Info("msg", "request_id", rid, "trace_id", tid, ...)
很冗长 推荐封装:
type Logger struct { *slog.Logger; reqID, traceID string }
,然后提供
WithRequest(...)
方法返回新实例 更轻量做法:用
slog.With
创建子 logger(Go 1.22+ 支持),它会继承父 handler 并叠加属性 示例:
reqLogger := slog.With("request_id", "abc123", "trace_id", "t-789") reqLogger.Info("handling request", "path", "/api/users")
为什么
slog.Debug
不输出,以及怎么开调试日志
slog
默认只输出
LevelInfo
及以上级别(即 Info / Warn / Error),
Debug
被静默过滤。 常见错误现象:
slog.Debug("debug only")
完全没输出,以为函数失效 解决方法:配置 handler 时传入
LevelVar
或固定
LevelDebug
安全做法:用
slog.LevelVar
动态控制,避免硬编码(尤其上线后想临时开 debug) 示例:
var level = new(slog.LevelVar) level.Set(slog.LevelDebug) h := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: level}) slog.SetDefault(slog.New(h))
真正容易被忽略的点是:handler 的
Level
设置必须作用于 handler 构造时,而不是 logger;且
slog.Debug
在非调试模式下不仅不输出,连参数求值都跳过(惰性求值),所以别依赖它的副作用。

相关文章