Golang 结构化日志包 log/slog 详解(三):属性字段和日志级别

上一篇文章讲解了 log/slog 包中的 Handler 的使用方法,通过不同的 Handler 可以输出不同格式的日志。接下来看一下如何自定义日志的属性字段和日志级别。

属性字段(attribute)

许多日志都有一些通用的的字段,例如日志级别 level、日志记录时间 time、日志信息 msg 等,这些字段就是属性字段。log/slog 包自带了有属性字段的日志输出功能,而不需要自己在日志内容里面添加。可以通过 With 函数来设置属性字段,看个简单的例子:

复制代码
package main

import "log/slog"

func main() {
	logger := slog.With("host", "xxx.com")
	logger.Info("hello", "标题", "路多辛的博客")
}

运行看下效果:

复制代码
2023/09/12 21:11:35 INFO hello host=xxx.com 标题=路多辛的博客

可以看到输出的日志里面有了 host 字段。With 函数的参数会以键值对的形式出现在日志中,返回一个新的 Logger,使用新的 Logger 输出日志时,每次输出中都会出现新增的属性字段。log/slog 包内置的几个属性字段如下:

  • time,日志记录时间
  • level,日志级别
  • msg,日志信息
  • source,源文件信息

日志级别(Levels)

slog.Level 是整数类型,表示日志记录的事件的重要程度或严重程度。级别越高,事件越严重。log/slog 包定义了如下几个常用的级别:

复制代码
const (
    LevelDebug Level = -4
    LevelInfo  Level = 0
    LevelWarn  Level = 4
    LevelError Level = 8
)

在应用程序中,一般只记录某个级别或更高级别的日志。常用的做法是在非生产环境将日志设置为 Info 级别,在生产环境将日志设置为 Warn 或者 Error 级别,并且可以通过配置文件动态调整日志级别,遇到比较难以排查的问题时,临时将日志设置为 Debug 级别,定位到问题后再调整回去。

内置的 Handler 可以通过通过 HandlerOptions.Level 参数来设置日志级别,默认为 Info 级别。要动态地改变整个程序的级别,首先需要初始化一个全局的 LevelVar,然后使用 LevelVar 来构造一个 Handler,并将其设为默认值,示例代码如下:

复制代码
package main

import (
	"log/slog"
	"os"
)

func main() {
	var programLevel = new(slog.LevelVar)
	h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel})
	slog.SetDefault(slog.New(h))
	slog.Debug("hello", "标题", "路多辛的博客")
}

运行代码,是不会输出任何内容的,因为日志级别设置的是 Info,所以不会输出 Debug 级别的日志。更改日志级别为 Debug 后,再使用 Debug 函数输出一次:

复制代码
package main

import (
	"log/slog"
	"os"
)

func main() {
	var programLevel = new(slog.LevelVar)
	h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel})
	slog.SetDefault(slog.New(h))
	slog.Debug("hello", "标题", "路多辛的博客")

	programLevel.Set(slog.LevelDebug)
	slog.Debug("hello2", "标题2", "路多辛的博客")
}

运行代码,输入了如下内容:

复制代码
{"time":"2023-09-12T21:41:59.960653+08:00","level":"DEBUG","msg":"hello2","标题2":"路多辛的博客"}

可以看出,日志级别被成功更改为了 Debug 并输出了相关日志。

相关推荐
名字还没想好☜24 分钟前
Go 的 io.Reader/Writer 组合实战:io.Copy、TeeReader、MultiWriter 优雅处理数据流
开发语言·后端·golang·go·iphone
郝学胜-神的一滴36 分钟前
Qt 高级编程 042:进度条从入门到自定义美化
开发语言·c++·qt·软件开发·用户界面
鸿芯微控科技1 小时前
压电纳米定位分辨率怎么测?噪声、带宽、最小可检测位移与Python分析
开发语言·python·噪声分析·压电执行器·纳米定位·位移测量
喵个咪1 小时前
GoWind Shop 架构剖析:一个 REST 请求穿越三服务 BFF 的七环链路
vue.js·后端·go
喵个咪1 小时前
GoWind Shop 安全设计:JWT 鉴权、Ent 行级隔离、防篡改审计与四个真实漏洞修复
vue.js·后端·go
喵个咪1 小时前
GoWind Shop:一个 proto 文件如何生成后端、前端、文档、校验六路代码
vue.js·后端·go
用户7783366132111 小时前
从 0 搭一个关键词排名监控:核心思路 + 可运行代码
后端·python·api
喵个咪1 小时前
GoWind Shop 出海实战:多语言商品内容怎么存、怎么录、怎么按 locale 取
vue.js·后端·go
@小匠1 小时前
Spring Boot Nacos绑定 Map 时中文 key 导致启动失败:一次从复现到源码的排查实录
java·开发语言·前端
Knight_AL1 小时前
Lombok @Builder 踩坑:build() 前后对象类型不一样
android·java·开发语言