大家好,我是木川
Go 1.21 引入了 Go 官方结构化日志包:slog,提供结构化日志记录,其中日志记录包括消息、日志级别以及以键值对属性。
结构化信息是指文本或内容按照一定的规则或格式进行组织,以使计算机能够理解和处理它。例如,XML(可扩展标记语言)和 JSON是用于表示结构化信息的常见格式。结构化信息使得信息可以轻松地在不同系统之间传递和解释
一、概述
Go标准库的log
包提供的功能相对有限,不支持更高级的日志功能,如日志级别、结构化日志、异步日志等。对于更复杂的项目,通常建议使用第三方的日志库,以满足更多高级需求。例如,logrus
和zap
等库提供了更多功能和配置选项,slog的设计之初对社区目前的一些应用广泛的log包进行了详细调研,尤其是 uber zap。
slog 从逻辑上分为前端和后端
slog 前端就是 slog 提供给使用者的API,抽象为 slog.Logger 结构体
type Logger struct {
// contains filtered or unexported fields
}
func (l *Logger) Debug(msg string, args ...any)
func (l *Logger) Debug(msg string, args ...any)
func (l *Logger) Info(msg string, args ...any)
func (l *Logger) InfoContext(ctx context.Context, msg string, args ...any)
slog将后端抽象为slog.Handler接口
type Handler interface {
Enabled(context.Context, Level) bool
Handle(context.Context, Record) error
WithAttrs(attrs []Attr) Handler
WithGroup(name string) Handler
}
一条日志记录由时间、日志级别、消息和一组键值对组成,其中键是字符串,值可以是任意类型。
slog 支持 四个级别——Debug
、Info
, Warn
和 Error
package main
import (
"log/slog"
)
func main() {
slog.Debug("hello") // 不会输出,默认Level=INFO
slog.Info("hello") // 2023/09/13 21:21:40 INFO hello
slog.Warn("hello") // 2023/09/13 21:21:40 WARN hello
slog.Error("hello") // 2023/09/13 21:21:40 ERROR hello
}
将多个键值对放到同一个分组,即前缀相同
slog.Info(
"http_call",
slog.Group(
"req",
slog.String("method", "GET"),
slog.String("url", "/api/v1")
),
slog.Int("status", http.StatusOK),
slog.Duration("duration", time.Second)
)
// 2023/09/13 22:16:14 INFO http_call req.method=GET req.url=/api/v1 status=200 duration=1s
日志级别作为参数传入
slog.LogAttrs(
context.Background(),
slog.LevelInfo,
"hello",
slog.Int("month", 9),
)
// 2023/09/13 21:44:49 INFO hello month=9
打印键值对
slog.Info("hello", "month", 9)
// 2023/09/13 21:34:45 INFO hello month=9
使用 text 模式输出日志
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
logger.Info("hello", "month", 9)
// time=2023-09-13T21:39:38.746+08:00 level=INFO msg=hello month=9
使用 json 模式输出日志
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Info("hello", "month", 9)
// {"time":"2023-09-13T21:40:07.043688+08:00","level":"INFO","msg":"hello","month":9}
var programLevel = new(slog.LevelVar)
programLevel.Set(slog.LevelDebug)
h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel})
slog.SetDefault(slog.New(h))
slog.Debug("hello")
// {"time":"2023-09-13T22:05:38.83539+08:00","level":"DEBUG","msg":"hello"}
总体看下来,slog 相比 log 方便了不少,新项目推荐使用 slog
最后给自己的原创 Go 面试小册打个广告,如果你从事 Go 相关开发,欢迎扫码购买,目前 10 元买断,加下面的微信发送支付截图额外赠送一份自己录制的 Go 面试题讲解视频
如果对你有帮助,帮我点一下在看或转发,欢迎关注我的公众号