golang新一代标准日志库slog
golang新一代标准日志库slog
原创 jufeng1988 CloudNative云原生技术
2024年12月08日 22:37 吉林 2人
golang新一代日志库slog
log/slog 是 Go 1.21 引入的一个新的日志记录包,旨在提供比传统 log 包更灵活和现代化的日志功能。它支持结构化日志、可配置的日志级别、灵活的日志输出格式等功能,弥补了旧版 log 包的不足。
• 对比旧版 log 包
特性
log
slog
日志级别支持
无
内置支持(Debug、Info 等)
结构化日志
无
支持键值对记录
日志格式
简单文本
文本或 JSON 格式
可扩展性
无
支持自定义处理器
性能和灵活性
低
高
使用方法
1. 创建日志记录器
slog 的核心是 Logger,可以通过默认记录器或自定义记录器来记录日志
使用默认日志记录器示例
func main() {
// 使用默认日志记录器,此模式日志输出格式为text文本型,且不会输出Debug级别日志
logger := slog.Default()
// 输出结构化日志
logger.Debug("This is a debug message")
logger.Info("Starting qkp platform log","version","v3.2.2")
logger.Warn("Low disk space","remaining","500MB")
logger.Error("Failed to connect to ETCD cluster","error","connection timeout")
}
2024/12/08 21:55:08 INFO Starting qkp platform log version=v3.2.2
2024/12/08 21:55:08 WARN Low disk space remaining=500MB
2024/12/08 21:55:08 ERROR Failed to connect to ETCD cluster error="connection timeout"
2. 日志级别控制
slog 支持以下日志级别
• slog.LevelDebug
• slog.LevelInfo
• slog.LevelWarn
• slog.LevelError
HandlerOptions 是 log/slog 提供的一种配置结构,用于自定义日志处理器的行为。通过配置 HandlerOptions,可以实现日志的源位置跟踪、日志级别动态调整,以及对日志属性的定制化处理,参数包括如下:
• AddSource:启用源代码位置记录,便于定位日志位置
• Level:控制日志级别,可静态或动态调整
• ReplaceAttr:修改、移除或过滤属性,支持灵活的日志定制
按照日志级别控制,并输出JSON格式
package main
import(
"log/slog"
"os"
)
func main(){
handler := slog.NewJSONHandler(os.Stdout,&slog.HandlerOptions{
Level: slog.LevelDebug,
})
logger := slog.New(handler)
// 输出结构化日志
logger.Debug("This is a debug message")
logger.Info("Starting qkp platform log","version","v3.2.2")
logger.Warn("Low disk space","remaining","500MB")
logger.Error("Failed to connect to ETCD cluster","error","connection timeout")
}
{"time":"2024-12-08T22:04:02.194775+08:00","level":"DEBUG","msg":"This is a debug message"}
{"time":"2024-12-08T22:04:02.195138+08:00","level":"INFO","msg":"Starting qkp platform log","version":"v3.2.2"}
{"time":"2024-12-08T22:04:02.195144+08:00","level":"WARN","msg":"Low disk space","remaining":"500MB"}
{"time":"2024-12-08T22:04:02.195149+08:00","level":"ERROR","msg":"Failed to connect to ETCD cluster","error":"connection timeout"}
3. 自定义日志处理器(Handler)
slog.Handler 是日志输出的核心接口,允许自定义日志处理行为 内置处理器
• slog.NewTextHandler: 以文本形式输出日志(默认格式)
• slog.NewJSONHandler: 以 JSON 格式输出日志
4. 使用上下文记录器
slog 支持通过上下文管理附加信息
package main
import(
"log/slog"
"os"
)
func main(){
handler := slog.NewJSONHandler(os.Stdout,&slog.HandlerOptions{
Level: slog.LevelDebug,
})
logger := slog.New(handler).With("platform","qkp","version","v3.2.2")
// 输出结构化日志
logger.Debug("This is a debug message")
logger.Info("Starting qkp platform log","version","v3.2.2")
logger.Warn("Low disk space","remaining","500MB")
logger.Error("Failed to connect to ETCD cluster","error","connection timeout")
}
{"time":"2024-12-08T22:09:02.400349+08:00","level":"DEBUG","msg":"This is a debug message","platform":"qkp","version":"v3.2.2"}
{"time":"2024-12-08T22:09:02.400673+08:00","level":"INFO","msg":"Starting qkp platform log","platform":"qkp","version":"v3.2.2","version":"v3.2.2"}
{"time":"2024-12-08T22:09:02.400678+08:00","level":"WARN","msg":"Low disk space","platform":"qkp","version":"v3.2.2","remaining":"500MB"}
{"time":"2024-12-08T22:09:02.400682+08:00","level":"ERROR","msg":"Failed to connect to ETCD cluster","platform":"qkp","version":"v3.2.2","error":"connection timeout"}
5. 集成lumberjack进行日志切片和归档
package main
import(
"gopkg.in/natefinch/lumberjack.v2"
"log/slog"
)
func main(){
// 配置 lumberjack 日志归档
lumberjackLogger :=&lumberjack.Logger{
Filename:"/tmp/app.log",// 日志文件路径
MaxSize:10,// 单个日志文件最大大小(单位:MB)
MaxBackups:5,// 保留的旧日志文件个数
MaxAge:30,// 保留的旧日志文件最大天数(单位:天)
Compress:true,// 是否压缩旧日志文件
}
handler := slog.NewJSONHandler(lumberjackLogger,&slog.HandlerOptions{
AddSource:true,// 如果设置为 true,日志输出中将包含源代码的位置(文件名和行号),默认值:false(不记录源位置)
Level: slog.LevelDebug,
})
logger := slog.New(handler).With("platform","qkp","version","v3.2.2")
// 输出结构化日志
logger.Debug("This is a debug message")
logger.Info("Starting qkp platform log","version","v3.2.2")
logger.Warn("Low disk space","remaining","500MB")
logger.Error("Failed to connect to ETCD cluster","error","connection timeout")
在/tmp目录下查询app.log日志
cat /tmp/app.log
{"time":"2024-12-08T22:17:46.720471+08:00","level":"DEBUG","source":{"function":"main.main","file":"/Users/hurricane/github/test01/main.go","line":42},"msg":"This is a debug message","platform":"qkp","version":"v3.2.2"}
{"time":"2024-12-08T22:17:46.720688+08:00","level":"INFO","source":{"function":"main.main","file":"/Users/hurricane/github/test01/main.go","line":43},"msg":"Starting qkp platform log","platform":"qkp","version":"v3.2.2","version":"v3.2.2"}
{"time":"2024-12-08T22:17:46.720696+08:00","level":"WARN","source":{"function":"main.main","file":"/Users/hurricane/github/test01/main.go","line":44},"msg":"Low disk space","platform":"qkp","version":"v3.2.2","remaining":"500MB"}
{"time":"2024-12-08T22:17:46.720702+08:00","level":"ERROR","source":{"function":"main.main","file":"/Users/hurricane/github/test01/main.go","line":45},"msg":"Failed to connect to ETCD cluster","platform":"qkp","version":"v3.2.2","error":"connection timeout"}
6. 结合归档日志级别以及替换关键字格式化日志
package main
import(
"gopkg.in/natefinch/lumberjack.v2"
"log/slog"
)
func main(){
// 配置 lumberjack 日志归档
lumberjackLogger :=&lumberjack.Logger{
Filename:"/tmp/app.log",// 日志文件路径
MaxSize:10,// 单个日志文件最大大小(单位:MB)
MaxBackups:5,// 保留的旧日志文件个数
MaxAge:30,// 保留的旧日志文件最大天数(单位:天)
Compress:true,// 是否压缩旧日志文件
}
handler := slog.NewJSONHandler(lumberjackLogger,&slog.HandlerOptions{
AddSource:true,// 如果设置为 true,日志输出中将包含源代码的位置(文件名和行号),默认值:false(不记录源位置)
Level: slog.LevelDebug,
ReplaceAttr:func(groups []string, a slog.Attr) slog.Attr{
// 替换关键字platform 的值从qkp变成kubernetes
if a.Key=="platform"{
return slog.Attr{Key: a.Key,Value: slog.StringValue("kubernetes")}
}
return a
},
})
logger := slog.New(handler).With("platform","qkp","version","v3.2.2")
// 输出结构化日志
logger.Debug("This is a debug message")
logger.Info("Starting qkp platform log","version","v3.2.2")
logger.Warn("Low disk space","remaining","500MB")
logger.Error("Failed to connect to ETCD cluster","error","connection timeout")
}
输出结果:
{"time":"2024-12-08T22:28:49.965694+08:00","level":"DEBUG","source":{"function":"main.main","file":"/Users/hurricane/github/test01/main.go","line":49},"msg":"This is a debug message","platform":"kubernetes","version":"v3.2.2"}
{"time":"2024-12-08T22:28:49.966204+08:00","level":"INFO","source":{"function":"main.main","file":"/Users/hurricane/github/test01/main.go","line":50},"msg":"Starting qkp platform log","platform":"kubernetes","version":"v3.2.2","version":"v3.2.2"}
{"time":"2024-12-08T22:28:49.966243+08:00","level":"WARN","source":{"function":"main.main","file":"/Users/hurricane/github/test01/main.go","line":51},"msg":"Low disk space","platform":"kubernetes","version":"v3.2.2","remaining":"500MB"}
{"time":"2024-12-08T22:28:49.966259+08:00","level":"ERROR","source":{"function":"main.main","file":"/Users/hurricane/github/test01/main.go","line":52},"msg":"Failed to connect to ETCD cluster","platform":"kubernetes","version":"v3.2.2","error":"connection timeout"}
阅读 510