Go 1.21 结构化日志包 slog

大家好,我是木川

Go 1.21 引入了 Go 官方结构化日志包:slog,提供结构化日志记录,其中日志记录包括消息、日志级别以及以键值对属性。

结构化信息是指文本或内容按照一定的规则或格式进行组织,以使计算机能够理解和处理它。例如,XML(可扩展标记语言)和 JSON是用于表示结构化信息的常见格式。结构化信息使得信息可以轻松地在不同系统之间传递和解释

一、概述

Go标准库的log包提供的功能相对有限,不支持更高级的日志功能,如日志级别、结构化日志、异步日志等。对于更复杂的项目,通常建议使用第三方的日志库,以满足更多高级需求。例如,logruszap等库提供了更多功能和配置选项,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 支持 四个级别——DebugInfo, WarnError

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

使用 TextHandler

使用 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

使用 JsonHandler

使用 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 面试题讲解视频


Go 1.21 结构化日志包 slog_第1张图片

Go 1.21 结构化日志包 slog_第2张图片

如果对你有帮助,帮我点一下在看或转发,欢迎关注我的公众号

你可能感兴趣的:(golang,状态模式,开发语言,后端)