slog 简介:用于 Go 的结构化日志

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: slog 简介:用于 Go 的结构化日志

日志是任何软件的重要组成部分,Go 提供了一个内置日志包(slog)。然而,随着应用的复杂性不断增加,对结构化日志的需求也越来越明显。结构化日志允许开发人员以结构化格式记录数据,便于日志聚合工具进行解析和分析,目前业界使用比较多的是:zap。


在本文中,我将简单介绍 slog 包、它的功能以及如何在 Go 应用程序中使用它。


什么是 slog?


slog 提供结构化日志记录,其中的日志记录包括一条消息、level 和其他各种以键值对表示的属性。


使用


最新的1.21版本引入了slog。要在 Go 项目中使用slog,可以通过以下方式导入它:


import "log/slog"


这里写一个非常简单的例子:


func main() {
 slog.Info("hello, world!", "coding", "happy")
}


输出:


2023/09/15 13:42:27 INFO hello, world! coding=happy

功能


slog 提供了许多有用的功能,使其成为 Go 的强大日志包。以下是其中的一些主要功能:


  • 结构化日志
  • 严重级别日志
  • 分组日志
  • 自定义处理

结构化日志


slog 默认提供两种方式:


  • TextHandler
  • JSONHandler


我们写一下使用这两个方式的例子:


func main() {
 textHandler := slog.NewTextHandler(os.Stdout, nil)
 textLogger := slog.New(textHandler)
 textLogger.Info("TextDemo",
  slog.String("app-version", "v0.0.1"),
  slog.Int("release-version", 1),
 )
 jsonHandler := slog.NewJSONHandler(os.Stdout, nil)
 jsonLogger := slog.New(jsonHandler)
 jsonLogger.Info("JsonDemo",
  slog.String("app-version", "v0.0.1"),
  slog.Int("release-version", 1),
 )
}


输出为:


time=2023-09-15T13:48:37.424+08:00 level=INFO msg=TextDemo app-version=v0.0.1 release-version=1
{"time":"2023-09-15T13:48:37.4647782+08:00","level":"INFO","msg":"JsonDemo","app-version":"v0.0.1","release-version":1}


从上面我们可以看到,代码中使用了类似slog.String的方法,slog提供了指定属性的功能。有多种类型的属性可供选择:


  • slog.String:字符串属性。
  • slog.Int:整数属性。
  • slog.Float64:浮点属性。
  • slog.Bool:布尔属性。
  • slog.Duration:持续时间属性。
  • slog.Time:时间属性。
  • slog.Group:组属性,可用于将相关属性分组
func main() {
 jsonHandler := slog.NewJSONHandler(os.Stdout, nil)
 jsonLogger := slog.New(jsonHandler)
 jsonLogger.Info(
  "attributes",
  slog.String("version", "1.0.0"),
  slog.Int("app-version", 1),
  slog.Float64("point-value", 1.2),
  slog.Bool("status", true),
  slog.Duration("duration", time.Hour*1),
  slog.Time("time", time.Now()),
  slog.Group(
   "request",
   slog.String("path", "<https://example.com>"),
   slog.String("method", "get"),
  ),
 )
}


对应的输出,我已经将其格式化了:


{
  "time": "2023-09-15T13:53:43.8848272+08:00",
  "level": "INFO",
  "msg": "attributes",
  "version": "1.0.0",
  "app-version": 1,
  "point-value": 1.2,
  "status": true,
  "duration": 3600000000000,
  "time": "2023-09-15T13:53:43.8848272+08:00",
  "request": {
    "path": "<https://example.com>",
    "method": "get"
  }
}


严重级别日志


这允许我们记录不同严重程度的信息。slog 默认提供四个日志级别,每个级别都有一个整数值:


  • DEBUG(-4)
  • INFO(0)
  • WARN(4)
  • ERROR(8)

例子:


func main() {
 jsonHandler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
  Level: slog.LevelDebug,
 })
 jsonLogger := slog.New(jsonHandler)
 jsonLogger.Debug("Hello, world!")
 jsonLogger.Info("Hello, world!")
 jsonLogger.Warn("Hello, world!")
 jsonLogger.Error("Hello, world!")
}


NOTE: 记得在NewHandler时设置级别。


分组日志


分组日志指的是将日志信息归类为逻辑组或类别的做法。Slog 通过使用与日志记录相关联的属性或键值对来支持分组日志记录。


例子:


func main() {
 jsonHandler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
  Level: slog.LevelDebug,
 })
 jsonLogger := slog.New(jsonHandler).WithGroup("request")
 jsonLogger.Info("",
  slog.String("url", "<https://example.com>"),
  slog.String("method", "GET"),
  slog.Int("response-code", 200),
 )
}


这里有个比较好的实践:


  • 在 http 服务的 middleware 中定义一个 request 组的 logger,会一些 4xx、5xx等请求的一些信息打印出来。
  • 而普通业务的话,我们又可以使用一个 service 组的 logger


自定义处理


slog 能够创建自定义handler,将日志信息写入不同的目的地,如文件、数据库或外部服务。


slog 提供的处理程序接口定义了自定义处理程序必须实现的方法。处理程序接口有四个方法:


type Handler interface {
    Enabled(Level) bool
    Handle(Record) error
    WithAttrs([]Attr) Handler
    WithGroup(string) Handler
}


下面举例说明如何创建一个将日志信息写入文件的自定义handler:


type FileHandler struct {
 file *os.File
}
func NewFileHandler(filename string) (*FileHandler, error) {
 file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
 if err != nil {
  return nil, err
 }
 return &FileHandler{file}, nil
}
func (h *FileHandler) Enabled(_ context.Context, level slog.Level) bool {
 return true
}
func (h *FileHandler) Handle(_ context.Context, record slog.Record) error {
 _, err := h.file.WriteString(record.Message + "\n")
 return err
}
func (h *FileHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
 return h
}
func (h *FileHandler) WithGroup(name string) slog.Handler {
 return h
}
func (h *FileHandler) Close() error {
 return h.file.Close()
}
func main() {
 fileHandler, err := NewFileHandler("log.log")
 if err != nil {
  panic(err)
 }
 defer fileHandler.Close()
 logger := slog.New(fileHandler)
 logger.Info("Hello, world!")
 logger.Debug("Debugging errors")
}


这个时候运行程序时,控制台就不会有对应的日志输出了,而是输出到对应文件上:


 slogDemo  cat .\log.log
Hello, world!
Debugging errors

总结


slog 是一个功能强大的 Go 日志包,提供结构化日志功能。它易于使用,并提供了许多有用的功能,如级别日志和自定义处理程序。如果你正在寻找一个能满足你不断增长的应用程序需求的日志包,那么 slog 绝对值得你一试。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
1月前
|
安全 Go
用 Zap 轻松搞定 Go 语言中的结构化日志
在现代应用程序开发中,日志记录至关重要。Go 语言中有许多日志库,而 Zap 因其高性能和灵活性脱颖而出。本文详细介绍如何在 Go 项目中使用 Zap 进行结构化日志记录,并展示如何定制日志输出,满足生产环境需求。通过基础示例、SugaredLogger 的便捷使用以及自定义日志配置,帮助你在实际开发中高效管理日志。
55 1
|
29天前
|
缓存 监控 前端开发
在 Go 语言中实现 WebSocket 实时通信的应用,包括 WebSocket 的简介、Go 语言的优势、基本实现步骤、应用案例、注意事项及性能优化策略,旨在帮助开发者构建高效稳定的实时通信系统
本文深入探讨了在 Go 语言中实现 WebSocket 实时通信的应用,包括 WebSocket 的简介、Go 语言的优势、基本实现步骤、应用案例、注意事项及性能优化策略,旨在帮助开发者构建高效稳定的实时通信系统。
79 1
|
4月前
|
JSON 中间件 Go
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
156 1
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
|
4月前
|
存储 JSON 前端开发
一文搞懂 Go 1.21 的日志标准库 - slog
一文搞懂 Go 1.21 的日志标准库 - slog
159 2
|
4月前
|
监控 Go 开发者
掌握Go语言中的日志管理
【8月更文挑战第31天】
42 0
|
5月前
|
SQL 安全 关系型数据库
MySQL的binlog日志的简介与查看
MySQL的binlog日志的简介与查看
726 4
|
4月前
|
数据采集 监控 Unix
性能监控之Telegraf+InfluxDB+Grafana实现结构化日志实时监控
【8月更文挑战第1天】性能监控之Telegraf+InfluxDB+Grafana实现结构化日志实时监控
348 0
|
6月前
|
监控 Go
go语言并发实战——日志收集系统(十一)基于etcd来监视配置文件的变化
go语言并发实战——日志收集系统(十一)基于etcd来监视配置文件的变化
|
1月前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
282 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
10天前
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。
下一篇
DataWorks