专栏首页腾讯技术工程官方号的专栏【Go API 开发实战 7】基础 3:记录和管理 API 日志

【Go API 开发实战 7】基础 3:记录和管理 API 日志

记录和管理 API 日志

本节核心内容

  • Go 日志包数量众多,功能不同、性能不同,本教程介绍一个笔者认为比较好的日志库,并给出原因
  • 介绍如何初始化日志包
  • 介绍如何调用日志包
  • 介绍如何转存(rotate)日志文件

本小节源码下载路径:demo03 可先下载源码到本地,结合源码理解后续内容,边学边练。 本小节的代码是基于 demo02 来开发的。

日志包介绍

apiserver 所采用的日志包 lexkong/log 是笔者根据开发经验,并调研 GitHub 上的 开源log 包后封装的一个日志包,也是笔者所在项目使用的日志包。它参考华为 paas-lager,做了一些便捷性的改动,功能完全一样,只不过更为便捷。相较于 Go 的其他日志包,该日志包有如下特点:

  • 支持日志输出流配置,可以输出到 stdout 或 file,也可以同时输出到 stdout 和 file
  • 支持输出为 JSON 或 plaintext 格式
  • 支持彩色输出
  • 支持 log rotate 功能
  • 高性能

初始化日志包

conf/config.yaml中添加 log 配置

config/config.go中添加日志初始化代码

package configimport (
    ....    "github.com/lexkong/log"
    ....
)
....func Init(cfg string) error {
    ....    // 初始化配置文件
    if err := c.initConfig(); err != nil {        return err
    }    // 初始化日志包
    c.initLog()
    ....
}func (c *Config) initConfig() error {
    ....
}func (c *Config) initLog() {
    passLagerCfg := log.PassLagerCfg {
        Writers:        viper.GetString("log.writers"),
        LoggerLevel:    viper.GetString("log.logger_level"),
        LoggerFile:     viper.GetString("log.logger_file"),
        LogFormatText:  viper.GetBool("log.log_format_text"),
        RollingPolicy:  viper.GetString("log.rollingPolicy"),
        LogRotateDate:  viper.GetInt("log.log_rotate_date"),
        LogRotateSize:  viper.GetInt("log.log_rotate_size"),
        LogBackupCount: viper.GetInt("log.log_backup_count"),
    }

    log.InitWithConfig(&passLagerCfg)
}  

// 监控配置文件变化并热加载程序func (c *Config) watchConfig() {
    ....
}

这里要注意,日志初始化函数c.initLog()要放在配置初始化函数

c.initConfig()之后,因为日志初始化函数要读取日志相关的配置。

func (c *Config) initLog()是日志初始化函数,会设置日志包的各项参数,参数为:

  • writers:输出位置,有两个可选项 —— file 和 stdout。选择 file 会将日志记录到 logger_file 指定的日志文件中,选择 stdout 会将日志输出到标准输出,当然也可以两者同时选择
  • logger_level:日志级别,DEBUG、INFO、WARN、ERROR、FATAL
  • logger_file:日志文件
  • log_format_text:日志的输出格式,JSON 或者 plaintext,true 会输出成非 JSON 格式,false 会输出成 JSON 格式
  • rollingPolicy:rotate 依据,可选的有 daily 和 size。如果选 daily 则根据天进行转存,如果是 size 则根据大小进行转存
  • log_rotate_date:rotate 转存时间,配 合rollingPolicy: daily 使用
  • log_rotate_size:rotate 转存大小,配合 rollingPolicy: size 使用
  • log_backup_count:当日志文件达到转存标准时,log 系统会将该日志文件进行压缩备份,这里指定了备份文件的最大个数

调用日志包

日志初始化好了,将 demo02 中的 log 用 lexkong/log 包来替换。替换前(这里 grep 出了需要替换的行,读者可自行确认替换后的效果):

$ grep log * -R
config/config.go:    "log"
config/config.go:        log.Printf("Config file changed: %s", e.Name)
main.go:    "log"
main.go:            log.Fatal("The router has no response, or it might took too long to start up.", err)
main.go:        log.Print("The router has been deployed successfully.")
main.go:    log.Printf("Start to listening the incoming requests on http address: %s", viper.GetString("addr"))
main.go:    log.Printf(http.ListenAndServe(viper.GetString("addr"), g).Error())
main.go:        log.Print("Waiting for the router, retry in 1 second.")

替换后的源码文件见 demo03

编译并运行

  1. 下载 apiserver_demos 源码包(如前面已经下载过,请忽略此步骤)
$ git clone https://github.com/lexkong/apiserver_demos
  1. apiserver_demos/demo03复制为 $GOPATH/src/apiserver
$ cp -a apiserver_demos/demo03/ $GOPATH/src/apiserver
  1. 在 apiserver 目录下编译源码
$ cd $GOPATH/src/apiserver
$ gofmt -w .
$ go tool vet .
$ go build -v .
  1. 启动 apiserver
$ ./apiserver

启动后,可以看到 apiserver 有 JSON 格式的日志输出:

管理日志文件

这里将日志转存策略设置为size,转存大小设置为 1 MB

  rollingPolicy: size
  log_rotate_size: 1

并在main函数中加入测试代码:

启动 apiserver 后发现,在当前目录下创建了 log/apiserver.log 日志文件:

$ ls log/ apiserver.log

程序运行一段时间后,发现又创建了 zip 文件:

$ ls log/ apiserver.log apiserver.log.20180531134509631.zip

该 zip 文件就是当 apiserver.log 大小超过 1MB 后,日志系统将之前的日志压缩成 zip 文件后的文件。

小结

本小节通过具体实例讲解了如何配置、使用和管理日志。

本系列文章转载自公众号:腾讯游戏存储与计算技术 微信号: game_infra

本文分享自微信公众号 - 腾讯技术工程(Tencent_TEG),作者:孔令飞

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-04-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 腾讯iOA零信任安全——IT变革下的新一代企业网

    ? 导语:2019年5月21日,腾讯全球数字生态大会在春城昆明盛大开幕。大会中TEG作为腾讯的内部技术支撑平台,在展区展出30余个技术应用。共分为资源层,资源...

    腾讯技术工程官方号
  • 如何用keras实现deepFM

    ? 一些前面说明 实现基本完全基于文末列出的deepFM 原文(还有几处或者更多地方可以优化,比如二次项多值输入的处理,样本编码等等) 文末参考的文章用Ker...

    腾讯技术工程官方号
  • 熊本熊之父来鹅厂啦!这是一场关于设计和体验的有趣之旅!

    2018年1月31日,腾讯CDC TALK在深圳腾讯大厦拉开了帷幕。CDC作为腾讯用户体验设计界的“黄埔军校”,成立至今12年,CDC的氛围其实更像个学校,大家...

    腾讯技术工程官方号
  • [AWR报告]log file sync等待事件

    当用户提交(commit)语句时,一个进程会建立一个redo 记录并把它拷贝至SGA中的log buffer中,然后这个进程会通知LGWR进程再将log buf...

    bsbforever
  • 【MySQL (六) | 详细分析MySQL事务日志redo log】

    为了最大程度避免数据写入时 IO 瓶颈带来的性能问题,MySQL 采用了这样一种缓存机制:

    周三不加班
  • MySQL 日志(redo log 和 undo log) 都是什么鬼?

    innodb事务日志包括redo log和undo log。redo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作。

    Java技术栈
  • MySQL不会丢失数据的秘密,就藏在它的 7种日志里

    记住! 记住! 记住! 上边这张图,她是MySQL更新数据的基础流程,其中包括redo log、bin log、undo log三种日志间的大致关系,好了闲话少...

    程序员内点事
  • MySQL 中的 DML 语句执行流程,你理解的跟我一样吗?

    在DML语句执行的过程中,主要会涉及到两个日志——redo log和bin log,而这两个日志是数据库 WAL (Write Ahead Logging,先写...

    Java程序猿阿谷
  • shell脚本快速入门之-----函数

    函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高。像其他编程语言一样,shell也支持函数。shell函数必须先定义后使用

    不吃小白菜
  • Python_列表解析【i for循环 if i】

    瑞新

扫码关注云+社区

领取腾讯云代金券