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


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

    分组输出

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

    TextHandler:

    1. package main
    2. import (
    3. "log/slog"
    4. "os"
    5. )
    6. func main() {
    7. h := slog.NewTextHandler(os.Stdout, nil)
    8. logger := slog.New(h)
    9. logger = logger.WithGroup("request")
    10. logger.Info("路多辛的博客", "method", "post", "url", "xxx.com/post")
    11. }

    输出内容如下:

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

    JSONHandler:

    1. package main
    2. import (
    3. "log/slog"
    4. "os"
    5. )
    6. func main() {
    7. h := slog.NewJSONHandler(os.Stdout, nil)
    8. logger := slog.New(h)
    9. logger = logger.WithGroup("request")
    10. logger.Info("路多辛的博客", "method", "post", "url", "xxx.com/post")
    11. }

    输出内容如下:

    {"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。简单示例如下:

    1. package main
    2. import (
    3. "context"
    4. "log/slog"
    5. )
    6. func main() {
    7. slog.InfoContext(context.Background(), "路多辛的博客")
    8. }

    属性和值

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

    1. package main
    2. import (
    3. "log/slog"
    4. )
    5. func main() {
    6. slog.Info("路多辛的博客", "count", 3)
    7. }

    也可写为如下形式:

    1. package main
    2. import (
    3. "log/slog"
    4. )
    5. func main() {
    6. slog.Info("路多辛的博客", slog.Int("count", 3))
    7. }

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

    1. package main
    2. import (
    3. "context"
    4. "log/slog"
    5. "os"
    6. )
    7. func main() {
    8. h := slog.NewTextHandler(os.Stdout, nil)
    9. logger := slog.New(h)
    10. logger = logger.WithGroup("request")
    11. logger.LogAttrs(context.Background(), slog.LevelInfo, "路多辛的博客", slog.Int("count", 3))
    12. }

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

    1. package main
    2. import (
    3. "log/slog"
    4. )
    5. func main() {
    6. slog.Info("路多辛的博客", "count", 3)
    7. }

  • 相关阅读:
    2022年全球市场光储充一体化总体规模、主要企业、主要地区、产品和应用细分研究报告
    nginx网站服务概述
    移动端JDtoolbar
    linux 清理垃圾文件
    hadoop的日志知识点
    配电房能源监测系统
    关于缓存和数据库一致性问题的深入研究
    DP20 计算字符串的编辑距离
    【磐河旅行】之酒店API接口对接实录
    【论文浅尝】Phi-3-mini:A Highly Capable Language Model Locally on Your Phone
  • 原文地址:https://blog.csdn.net/luduoyuan/article/details/133250760