slog 默认不输出日志因使用空 handler,需显式设置带选项的 TextHandler 或 JSONHandler 并调用 slog.SetDefault;Debug 级别默认被过滤,须通过 HandlerOptions.Level 配置 LevelVar 才生效。
slog 是 Go 1.21+ 官方推荐的日志方案,但直接用默认输出是无格式、无时间戳、无调用位置的,不适用于生产环境。
为什么默认的
看起来像没生效
Go 标准库的
默认使用
的最简实现(
或
)需要显式传入,否则
返回的是一个“空 handler”——它会静默丢弃所有日志。
常见错误现象:
运行后控制台完全没输出,也没报错
根本原因:没设置全局 logger,也没给
传 handler;
在未初始化时也返回空 handler
正确做法:必须显式构造带 handler 的 logger,并用
激活,或直接用该 logger 实例
示例:
和
怎么选
两者性能接近,差异主要在可读性、解析友好性和调试成本上。
:适合本地开发、CI 日志查看,人类可读,但字段顺序不固定,无法被结构化日志系统(如 Loki、Datadog)自动解析
:字段名固定、嵌套清晰,能被大多数日志收集器识别;但单行 JSON 不易肉眼扫读,调试时需格式化
注意:
默认不输出时间戳和程序位置,需手动加
示例(带时间 + 文件行号):
如何加自定义字段(比如 request_id、trace_id)
不支持全局 context 字段(不像 zap 的
),必须每次调用时显式传入,或封装一层。
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语言免费学习笔记(深入)
”;
直接传参:每次写
很冗长
推荐封装:
,然后提供
方法返回新实例
更轻量做法:用
创建子 logger(Go 1.22+ 支持),它会继承父 handler 并叠加属性
示例:
为什么
不输出,以及怎么开调试日志
默认只输出
及以上级别(即 Info / Warn / Error),
被静默过滤。
常见错误现象:
完全没输出,以为函数失效
解决方法:配置 handler 时传入
或固定
安全做法:用
动态控制,避免硬编码(尤其上线后想临时开 debug)
示例:
真正容易被忽略的点是:handler 的
设置必须作用于 handler 构造时,而不是 logger;且
在非调试模式下不仅不输出,连参数求值都跳过(惰性求值),所以别依赖它的副作用。
slog.Newslog.Newslogslog.Handlerslog.TextHandlerslog.JSONHandlerslog.Newslog.Info("hello")slog.Newslog.Default()slog.SetDefaultslog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, nil)))
slog.Info("server started", "port", ":8080")slog.TextHandlerslog.JSONHandlerslog.TextHandlerslog.JSONHandlerslog.JSONHandlerslog.HandlerOptions{AddSource: true, AddTime: true}h := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
AddTime: true,
AddSource: true,
})
slog.SetDefault(slog.New(h))slogWithslog.Info("msg", "request_id", rid, "trace_id", tid, ...)type Logger struct { *slog.Logger; reqID, traceID string }WithRequest(...)slog.WithreqLogger := slog.With("request_id", "abc123", "trace_id", "t-789")
reqLogger.Info("handling request", "path", "/api/users")slog.DebugslogLevelInfoDebugslog.Debug("debug only")LevelVarLevelDebugslog.LevelVarvar level = new(slog.LevelVar)
level.Set(slog.LevelDebug)
h := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: level})
slog.SetDefault(slog.New(h))Levelslog.Debug