Go日志框架slog使用入门与结构化日志解析-实战技巧与实践

2025-05-02 27

Image

Go日志框架slog使用入门与结构化日志解析

slog是Go 1.21版本引入的标准库结构化日志包(log/slog),它提供了结构化日志记录功能,比传统的log包更强大和灵活。

1. slog基础使用

1.1 快速开始

package main

import (
	"log/slog"
	"os"
)

func main() {
	// 默认的文本处理器
	slog.Info("hello world")
	slog.Error("oops", "status", 500, "err", "file not found")
	
	// 创建JSON格式的日志处理器
	logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
	logger.Info("hello world", "user", "John")
}

1.2 日志级别

slog定义了以下日志级别:

const (
	LevelDebug Level = -4
	LevelInfo  Level = 0
	LevelWarn  Level = 4
	LevelError Level = 8
)

使用示例:

logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Debug("debug message")  // 默认不显示
logger.Info("info message")
logger.Warn("warning message")
logger.Error("error message")

2. 结构化日志

2.1 添加属性

logger.Info(
	"user login",
	"user_id", 12345,
	"ip", "192.168.1.1",
	"success", true,
)

2.2 使用slog.Attr

更高效的方式是使用slog.Attr

logger.LogAttrs(
	context.Background(),
	slog.LevelInfo,
	"user login",
	slog.Int("user_id", 12345),
	slog.String("ip", "192.168.1.1"),
	slog.Bool("success", true),
)

2.3 分组属性

logger.Info(
	"request completed",
	slog.Group("request",
		slog.String("method", "GET"),
		slog.String("path", "/api/users"),
	),
	slog.Group("response",
		slog.Int("status", 200),
		slog.Duration("duration", 123*time.Millisecond),
	),
)

3. 处理器(Handler)配置

3.1 文本处理器

handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
	Level: slog.LevelDebug, // 设置日志级别
	AddSource: true,       // 添加源文件位置
})

logger := slog.New(handler)

3.2 JSON处理器

handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
	Level: slog.LevelInfo,
})

logger := slog.New(handler)

3.3 自定义处理器

type CustomHandler struct {
	slog.Handler
}

func (h *CustomHandler) Handle(ctx context.Context, r slog.Record) error {
	// 自定义处理逻辑
	fmt.Printf("[%s] %s\n", r.Level, r.Message)
	return nil
}

func main() {
	handler := &CustomHandler{
		Handler: slog.NewJSONHandler(os.Stdout, nil),
	}
	logger := slog.New(handler)
	logger.Info("custom handler message")
}

4. 上下文集成

func handleRequest(w http.ResponseWriter, r *http.Request) {
	logger := slog.FromContext(r.Context())
	logger.Info("request handled", "path", r.URL.Path)
}

func main() {
	handler := slog.NewJSONHandler(os.Stdout, nil)
	logger := slog.New(handler)
	
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		ctx = slog.NewContext(ctx, logger.With("request_id", "12345"))
		handleRequest(w, r.WithContext(ctx))
	})
	
	http.ListenAndServe(":8080", nil)
}

5. 日志解析

由于slog输出的是结构化日志,解析起来非常方便:

5.1 JSON日志解析示例

type LogEntry struct {
	Time    time.Time `json:"time"`
	Level   string    `json:"level"`
	Message string    `json:"msg"`
	UserID  int       `json:"user_id,omitempty"`
	IP      string    `json:"ip,omitempty"`
}

func parseLogLine(line string) (*LogEntry, error) {
	var entry LogEntry
	err := json.Unmarshal([]byte(line), &entry)
	if err != nil {
		return nil, err
	}
	return &entry, nil
}

5.2 使用日志收集系统

结构化日志可以轻松集成到日志收集系统如ELK、Loki、Splunk等。

6. 实践

  1. 始终使用结构化日志:避免使用fmt.Sprintf构建日志消息
  2. 合理设置日志级别:生产环境通常使用Info级别
  3. 添加有用的上下文:请求ID、用户ID等有助于追踪问题
  4. 避免敏感信息:不要在日志中记录密码、令牌等
  5. 性能考虑:对于高频日志,使用LogAttrs比传递键值对更高效

7. 与第三方日志库比较

| 特性 | slog | logrus | zap |
|------------|------|--------|-----|
| 结构化日志 | ✅ | ✅ | ✅ |
| 标准库 | ✅ | ❌ | ❌ |
| 高性能 | 中等 | 低 | 高 |
| 上下文支持 | ✅ | ✅ | ✅ |
| 日志级别 | ✅ | ✅ | ✅ |

slog作为标准库,虽然性能不如zap,但提供了良好的平衡性和未来兼容性。

slog为Go带来了现代化的结构化日志记录能力,是未来Go日志记录的标准方式。通过合理使用slog,可以大大提高日志的可读性和可维护性,同时为日志分析和监控提供更好的支持。

(本文地址:https://www.nzw6.com/6819.html)

1. 本站所有资源来源于用户上传和网络,因此不包含技术服务请大家谅解!如有侵权请邮件联系客服!cheeksyu@vip.qq.com
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!
4. 如果您也有好的资源或教程,您可以投稿发布,成功分享后有积分奖励和额外收入!
5.严禁将资源用于任何违法犯罪行为,不得违反国家法律,否则责任自负,一切法律责任与本站无关