Golang 结构化日志包 log/slog 详解(四):分组、上下文和属性值类型

上一篇文章讲解了 log/slog 包中的自定义日志属性字段和日志级别,本文讲解下分组、上下文和属性值类型

分组输出

slog 支持将字段放在组中并且可以给分组指定名称。如何展示分组的内容,取决于使用的 handler,例如 TextHandler 使用点号分隔组名和属性,JSONHandler 将每个组视为单独的 JSON 对象,并以组名作为键。分别看下 TextHandler 和 JSONHandler 的示例。

TextHandler:

package main

import (
	"log/slog"
	"os"
)

func main() {
	h := slog.NewTextHandler(os.Stdout, nil)
	logger := slog.New(h)
	logger = logger.WithGroup("request")
	logger.Info("路多辛的博客", "method", "post", "url", "xxx.com/post")
}

输出内容如下:

time=2023-09-24T18:17:45.642+08:00 level=INFO msg=路多辛的博客 request.method=post request.url=xxx.com/post

JSONHandler:

package main

import (
	"log/slog"
	"os"
)

func main() {
	h := slog.NewJSONHandler(os.Stdout, nil)
	logger := slog.New(h)
	logger = logger.WithGroup("request")
	logger.Info("路多辛的博客", "method", "post", "url", "xxx.com/post")
}

输出内容如下:

{"time":"2023-09-24T18:19:39.025697+08:00","level":"INFO","msg":"路多辛的博客","request":{"method":"post","url":"xxx.com/post"}}

上下文(contexts)支持

一些 handler 或者自定义的 handlers 可能希望得到包含上下文(context.Context)的信息,例如链路追踪的场景,需要从上下文中获取到当前的 span 信息。slog 包提供了对这种场景的支持,Logger.log 和 Logger.LogAttrs 方法将 context.Context 类型的参数作为第一个参数,还有记录几种级别日志的方法,都同时提供了带上下文的方法,对应的方法就是后面跟上 Context。简单示例如下:

package main

import (
	"context"
	"log/slog"
)

func main() {
	slog.InfoContext(context.Background(), "路多辛的博客")
}

属性和值

属性是一个键值对,日志输出方法接受交替出现的属性和值,例如:

package main

import (
	"log/slog"
)

func main() {
	slog.Info("路多辛的博客", "count", 3)
}

也可写为如下形式:

package main

import (
	"log/slog"
)

func main() {
	slog.Info("路多辛的博客", slog.Int("count", 3))
}

这里的 slog.Int 返回一个 slog.Attr 类型的值,slog.Attr 用来表示一个键值对。 slog 还提供了生成其他类型的键值对的函数,例如 float、string 和 Bool 等,属性的值是 slog.Value 类型,像 any 一样,Value 可以保存任何值。要获得最高效的日志输出,可以使用 Logger.LogAttrs,只接受 slog.Attr 类型的日志内容,不接受键值交替出现的值。例如:

package main

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

func main() {
	h := slog.NewTextHandler(os.Stdout, nil)
	logger := slog.New(h)
	logger = logger.WithGroup("request")
	logger.LogAttrs(context.Background(), slog.LevelInfo, "路多辛的博客", slog.Int("count", 3))
}

输出效果和如下的代码是一样的:

package main

import (
	"log/slog"
)

func main() {
	slog.Info("路多辛的博客", "count", 3)
}

猜你喜欢

转载自blog.csdn.net/luduoyuan/article/details/133250760
今日推荐