golang学习(zap二次封装, 支持动态修改日志级别)

golang到现在还没出现一款类似log4j这么强大的日志打印工具, 在调研了一番之后发现,现在用的最多的是logrus跟zap, github上的star也比较多, logrus使用起来比较简单, 不需要做过多的设置, 导入就能使用, 非常方便, 而zap则侧重在高性能方面, 基本所有的参数都可配置,不过需要的代码比logrus多.

对于日志打印工具的需求其实非常简单, 日志轮转,多点打印, json格式就可以了, logrus跟zap这些都支持, 如果是从易用性上来, 优先会选择logrus, 因为基本不需要写代码.

但是当看到zap支持在运行时动态修改日志级别这个功能时, 我眼前一亮, 而且在看完zap的性能比logrus高一个数量级时, 果断地选择了zap.

因为zap是高度可配置的, 文档也不是很完善, 做个简单的二次封装是个不错的选择

这样在不需要重启应用的情况下就能修改日志级别, 还是很爽的.

源码

Demo在这里

当然封装的也比较简单, 有些参数是可以抽离出来的

下载下来后直接运行go run main.go

测试

启动时默认的日志级别被设置为info,因此不会打印debug日志

可以通过以下接口查看: curl localhost:9090/handle/level 代码中已改成curl localhost:9090/change/level

把日志级别修改为debug(向下修改)

查看日志, 发现debug日志打印出来了, 说明动态修改生效

再把日志级别修改为error(向上修改)

查看日志, 只有error的日志打印出来

最后把日志级别修改为panic

发现不打印日志了,因为main中最高级别为warn

总结: 现在很多成熟的日志工具都支持在运行时通过http接口修改日志级别,比如Log4j, 不过log4j一般都会使用在java的项目上,golang下zap也原生提示了这个能力, 还是挺有用的, 生产环境下可以设置一个比较高的打印级别, 比如warn,这样可以节省大量磁盘空间同时提高效率, 如果发现问题,只需要通过http接口把日志级别调低, 很方便的可以不停应用排查问题,非常方便.

问题

在测试时发现出现有以下的打印格式, 发现msg字段的格式有点诡异, 这样不太利于做日志分析.

1
{"level":"info","time":"2020-03-04T16:41:12.828+0800","caller":"github/demo.go:29","msg":"无法获取网址{url 15 0 http://www.baidu.com <nil>} {attempt 11 3  <nil>} {backoff 8 1000000000  <nil>}","serviceName":"main"}

在main.go中对应的代码

1
2
3
4
5
logger.Info("无法获取网址",
zap.String("url", "http://www.baidu.com"),
zap.Int("attempt", 3),
zap.Duration("backoff", time.Second),
)

原因在于, 现在的logger对象是一个zap.SugaredLogger, 而不是logger对象(最开始测试时用的是Logger对象), 因此在这里不能使用zap.String这种格式, 当然, zap.SugaredLogger跟zap.Logger是可以很方便地进行转换的, 可参考这里

参考文章: