文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

三个实用细节,让Zap在Go项目中变得更好用

2024-11-29 17:40

关注

从本节开始我们先用两节为我们的Go项目定制日志组件,让它足够好用。

未来我们会用这个组件一步步完善项目的应用日志规范,让项目框架能为我们把关键的上下文信息记录到日志中,保证我们即使自己忘记打日志的情况下框架依然能为我们记录下一些关键日志。

图片

本节项目的所有源码和测试接口都单独封存了Git版本, 方便大家在自己机器上快速调试和学习。

图片

安装 Zap 和相关配置信息准备

Zap是Uber开源的Go日志组件,它的优势什么的我就不过多介绍了,这两节介绍的内容更多地是关注怎么给自己的项目框架定制一个比较好用日志组件,其中介绍的方法思路换做其他的Go开源日志组件也同样适用

我们首先来安装一下 Zap ,这个时候可以打开你自己新建的项目来跟着操作

go get go.uber.org/zap@v1.21.0

把日志写入文件,同时完成日志文件的切割归档需要借助另外一个开源库 lumberjack,我们把它也安装一下

go get gopkg.in/natefinch/lumberjack.v2@v2.0.0

安装完成后我们先添加几个与日志相关的配置,好能通过配置控制日志文件的路径和文件大小等选项

打开项目开发环境的配置文件 config/application.dev.yaml, 我们在app原配置基础上,加了log相关的三个配置。

app:
  env: dev
  name: go-mall
  log:
    path: "/tmp/applog/go-mall.log"
    max_size: 100
    max_age: 60

这里注意一下,开发环境日志文件放在/tmp目录下主要是为了避免在电脑上很多目录的权限限制比较严格程序没办法写日志的问题。测试环境和生存环境的日志文件路径建议设置成 /home/applog/go-mall/go-mall.log 这样的路径。

配置文件加好后,相应的我们的配置对象也要根据新增配置进行调整。

type appConfig struct {
    Name string `mapstructure:"name"`
    Env  string `mapstructure:"env"`
    Log  struct {
        FilePath         string `mapstructure:"path"`
        FileMaxSize      int    `mapstructure:"max_size"`
        BackUpFileMaxAge int    `mapstructure:"max_age"`
    }
}

初始化日志组件

接下来我们先初始化Zap, 把它做为我们日志组件的基础Logger,配置完后我们会在其上封装一个门面,让Logger 变得更好用一些,通过这个门面除了能简化我们使用Zap打日志的操作方式外,还会给日志自动追加一些追踪和定位信息便于我们追踪日志和定位程序问题,这个下个章节再讲,本节先把基础的东西做好。

接下里,先在项目中新建一个 common 目录

.
|-- common
|   |-- enum
|   |-- logger
|-- main.go
|-- go.mod
|-- go.sum

logger目录中先新建 zap.go 在文件中对Zap进行初始化相关的操作。

func init() {
 encoderConfig := zap.NewProductionEncoderConfig()
 encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
 encoder := zapcore.NewJSONEncoder(encoderConfig)
 fileWriteSyncer := getFileLogWriter()

 var cores []zapcore.Core
    ......
 core := zapcore.NewTee(cores...)
 _logger = zap.New(core)
}

因为Zap我们只会把它当作基础Logger,所以把它的变量定义成了只能在 logger 包内访问的全局变量

var _logger *zap.Logger

我们都知道针对不同的运行环境,日志的最低级别不太一样,比如说在开发环境中我们会打很多Debug日志,这个日志到生产环境上应该被自动过滤掉,如果不支持这个功能的话就得每次在代码里把自己写过的Debug日志的代码行删掉,这个相信谁都办不到。

所以我们从底层Logger下手让程序运行在服务器上时不收集Debug日志

var cores []zapcore.Core
 switch config.App.Env {
 case enum.ModeTest, enum.ModeProd:
  // 测试环境和生产环境的日志输出到文件中
  cores = append(cores, zapcore.NewCore(encoder, fileWriteSyncer, zapcore.InfoLevel))
 case enum.ModeDev:
  // 开发环境同时向控制台和文件输出日志, Debug级别的日志也会被输出
  cores = append(
   cores,
   zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel),
   zapcore.NewCore(encoder, fileWriteSyncer, zapcore.DebugLevel),
  )

 }

通过上面这几行代码的设置让 Zap 在开发环境中可以写Debug级别的日志,并且除了向文件里写日志外,还同时向终端控制台写日志,这样我们打的日志就能出现在程序运行的控制台中,方便我们快速Debug

日志文件的管理

Zap没有自动管理和切割日志文件的功能,这个功能我们要借助 lumberjack 这个库。

func getFileLogWriter() (writeSyncer zapcore.WriteSyncer) {
 // 使用 lumberjack 实现 logger rotate
 lumberJackLogger := &lumberjack.Logger{
  Filename:  config.App.Log.FilePath,
  MaxSize:   config.App.Log.FileMaxSize,      // 文件最大 100 M
  MaxAge:    config.App.Log.BackUpFileMaxAge, // 旧文件最多保留90天
  Compress:  false,
  LocalTime: true,
 }

 return zapcore.AddSync(lumberJackLogger)
}

创建 LumberJack 的 Logger 然后把它设置成 Zap 的 WriteSyncer ,这样使用 Zap 打的日志就会写到文件中

...
fileWriteSyncer := getFileLogWriter()

...
cores = append(cores, zapcore.NewCore(encoder, fileWriteSyncer, zapcore.InfoLevel))

创建LumberJack时可以定义日志文件的几个选项

效果测试

日志文件Writer初始化并设置给Zap 后我们可以测试下是否有效果,我测试的时候是先把MaxSize 改成1 , 即最大1M,随便写个测试方法在里面写日志,疯狂刷了一会儿接口让日志文件大小超过1M。

来源:网管叨bi叨内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯