找回密码
 立即注册
查看: 582|回复: 0

[后端] Go 统一日志处理

[复制链接]

279

主题

0

回帖

964

积分

超级版主

积分
964
发表于 2024-5-19 14:19:05 | 显示全部楼层 |阅读模式
本帖最后由 Shaw0xyz 于 2024-5-19 14:20 编辑

在现代应用开发中,日志处理是非常重要的一环。统一的日志处理不仅可以帮助我们更好地调试和监控应用,还可以为后期的维护提供有力的支持。本文将介绍如何在Go语言项目中实现统一的日志处理,涵盖日志库的选择、配置和使用。


为什么需要统一日志处理?

- 调试方便:通过统一的日志格式和级别,方便快速定位问题。
- 监控便捷:统一的日志输出方便接入监控系统(如ELK、Prometheus)。
- 维护简单:一致的日志管理方式降低了代码复杂度,提升可维护性。

日志库的选择

Go语言有多种日志库可以选择,常用的有标准库`log`、`logrus`、`zap`等。本文将重点介绍如何使用`zap`库,因为它具有高性能、结构化日志等优点,非常适合生产环境。

安装zap库

首先,使用以下命令安装`zap`库:

  1. go get -u go.uber.org/zap
复制代码

初始化日志器

在项目中创建一个独立的日志管理包`logger`,并在其中初始化`zap`日志器:

  1. // logger/logger.go
  2. package logger

  3. import (
  4.     "go.uber.org/zap"
  5.     "go.uber.org/zap/zapcore"
  6.     "os"
  7. )

  8. var Logger *zap.Logger

  9. func InitLogger() {
  10.     config := zap.Config{
  11.         Encoding:         "json",
  12.         Level:            zap.NewAtomicLevelAt(zap.InfoLevel),
  13.         OutputPaths:      []string{"stdout", "./logs/app.log"},
  14.         ErrorOutputPaths: []string{"stderr"},
  15.         EncoderConfig: zapcore.EncoderConfig{
  16.             TimeKey:        "time",
  17.             LevelKey:       "level",
  18.             NameKey:        "logger",
  19.             CallerKey:      "caller",
  20.             MessageKey:     "msg",
  21.             StacktraceKey:  "stacktrace",
  22.             LineEnding:     zapcore.DefaultLineEnding,
  23.             EncodeLevel:    zapcore.LowercaseLevelEncoder,
  24.             EncodeTime:     zapcore.ISO8601TimeEncoder,
  25.             EncodeDuration: zapcore.StringDurationEncoder,
  26.             EncodeCaller:   zapcore.ShortCallerEncoder,
  27.         },
  28.     }

  29.     var err error
  30.     Logger, err = config.Build()
  31.     if err != nil {
  32.         panic(err)
  33.     }
  34.     defer Logger.Sync()
  35. }
复制代码

以上代码配置了`zap`日志器,将日志输出到控制台和文件,并使用JSON格式进行日志编码。

配置日志级别

日志级别在日志处理中非常重要,常见的级别有:Debug、Info、Warn、Error和Fatal。可以根据项目需求设置不同的日志级别。

在初始化`zap`日志器时,我们通过`zap.NewAtomicLevelAt`函数设置了日志级别为`InfoLevel`,即只有Info及以上级别的日志会被记录。如果需要在运行时动态调整日志级别,可以使用以下代码:

  1. func SetLogLevel(level zapcore.Level) {
  2.     atomicLevel := zap.NewAtomicLevel()
  3.     atomicLevel.SetLevel(level)
  4.     Logger = Logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
  5.         return core.With([]zapcore.CoreOption{
  6.             zapcore.AddSync(os.Stdout),
  7.             zapcore.AddSync(&lumberjack.Logger{
  8.                 Filename:   "./logs/app.log",
  9.                 MaxSize:    100, // megabytes
  10.                 MaxBackups: 3,
  11.                 MaxAge:     28, // days
  12.             }),
  13.         }...)
  14.     }))
  15. }
复制代码

通过调用`SetLogLevel`函数,可以动态调整日志级别。

使用日志器

在项目的其他部分使用日志器时,可以通过`logger.Logger`进行日志记录。例如:

  1. // main.go
  2. package main

  3. import (
  4.     "myproject/logger"
  5. )

  6. func main() {
  7.     logger.InitLogger()

  8.     logger.Logger.Info("This is an info message")
  9.     logger.Logger.Warn("This is a warning message")
  10.     logger.Logger.Error("This is an error message")
  11. }
复制代码

这样,日志将统一按照指定的格式和级别输出。

高级功能

结构化日志

`zap`支持结构化日志,可以非常方便地记录带有上下文信息的日志。例如:

  1. logger.Logger.Info("User logged in",
  2.     zap.String("username", "johndoe"),
  3.     zap.Int("userID", 123),
  4.     zap.Time("loginTime", time.Now()))
复制代码

这样输出的日志更易于解析和分析。

日志轮转

日志文件可能会随着时间增长而变大,我们可以使用`lumberjack`库来实现日志轮转。需要安装`lumberjack`库:

  1. go get -u gopkg.in/natefinch/lumberjack.v2
复制代码

并在`logger/logger.go`中进行如下修改:

  1. import "gopkg.in/natefinch/lumberjack.v2"

  2. // 在InitLogger中设置lumberjack日志轮转
  3. config.OutputPaths = []string{"stdout", "./logs/app.log"}
  4. config.ErrorOutputPaths = []string{"stderr"}
  5. config.EncoderConfig = zapcore.EncoderConfig{
  6.     ...
  7. }
  8. logWriter := zapcore.AddSync(&lumberjack.Logger{
  9.     Filename:   "./logs/app.log",
  10.     MaxSize:    100, // megabytes
  11.     MaxBackups: 3,
  12.     MaxAge:     28, // days
  13. })
  14. core := zapcore.NewCore(
  15.     zapcore.NewJSONEncoder(config.EncoderConfig),
  16.     zapcore.NewMultiWriteSyncer(logWriter, zapcore.AddSync(os.Stdout)),
  17.     zap.NewAtomicLevelAt(zap.InfoLevel),
  18. )
  19. Logger = zap.New(core)
复制代码

以上配置实现了日志文件轮转,每个日志文件最大100MB,最多保留3个备份,日志文件保存时间为28天。

结语

通过上述步骤,我们成功在Go项目中实现了统一的日志处理。使用`zap`日志库不仅可以提升日志记录的性能,还能让日志更加结构化和易于管理。

荔枝学姐爱吃荔枝!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

联系站长|Archiver|手机版|小黑屋|主机论坛

GMT+8, 2025-4-4 13:44 , Processed in 0.063713 second(s), 24 queries .

Powered by 主机论坛 HostSsss.Com

HostSsss.Com

快速回复 返回顶部 返回列表