关于生产环境打日志的一些思考

Posted 泰 戈 尔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于生产环境打日志的一些思考相关的知识,希望对你有一定的参考价值。

文章目录


一说起日志,就好比是应了那句话。

一千个读者,就有一千个哈姆雷特。

相信,每位 RD 兄台都有自己的一套观点。我亦如此,就着最近遇到的一些经历,谈谈自己对日志的一些看法。

首先是日志的重要性,没有日志,服务就无从谈起,它是一个系统不可缺少的一个重要组成部分,一般分为两个大类:

  • 系统日志:记录系统中硬件、软件和系统问题的信息,同时还可以监视系统中发生的事件。
    • 系统日志
    • 应用程序运行日志
    • 安全日志
  • 服务日志:主要是代码运行日志、网站请求等日志

可能有人会觉得这两类中有部分内容重合,这不重要。本文主要就是写点关于**“代码运行日志”**的内容。

为什么要打代码运行日志呢?
关于这个问题,大部分人的答案估计都是大同小异的,不外乎有以下几种。

  • 程序执行链路长,定位问题成本高
  • 业务止损,用以回复某些不可控因素导致的资损
  • 溯源,可能你也听说过公司被 WXB 要求,日志文件至少要保存多久

量级

上文书既然说到,日志是如此的重要,那我们就打呗。全给它打喽,打爆它。

但事实上,这还真是个难题,首当其冲的便是日志量。拿我当前在做的一个业务来说,每秒 5W 的 QPS,每次请求涉及到的日志记录从 3-N 不等。我们都知道打日志实际上是很耗时的 IO 操作,频繁打印日志对于服务平响或者说稳定性都会带来一定的影响。所以这种情况下并不能把全量日志都打印出来。

根据日志量级估算出每天可能产生的日志文件大小,对照自己业务机器的空间存储,做好 rotate 切割、丢弃。不然,你可能也会像我在上家公司一样,经常大半夜收到磁盘报警的短信,然后爬起来,冒着删库跑路(rm -rf /)的风险睡眼惺忪地处理警报。

合理计算业务所产生的的日志输出,规划好日志存储的容量。

等级

写代码的时候,相比都见过DEBUG、VERBOSE、INFO、WARNING、ERROR 等形式的日志。这边是日志的“LEVEL”,加个引号,就是字面上的意思。

日志等级本身没有高低贵贱之分,只是应了那句话。

在的最合适的时间,遇到了最对的你。

通常,我们都会在服务中以配置文件来过滤业务日志的输出。

这样,便可以做到。开发环境的时候打最详细的日志,生产环境便可以缩减日志输出,减少无谓的性能消耗。

前段时间,部门有位同事搞出了一套 trace 系统,针对白名单用户开启全链路日志追溯,以协助定位、解决大客户反馈的问题。说白了,这其实也是另一种日志等级的过滤,不过是相比于 DEBUG、INFO 这种,粒度更细,也更加精准。当然,也可以说是对量级的一种权衡,毕竟 VIP 用户充了钱了,给人家多点特权也在乎情理之中嘛。

常规参考:https://reflectoring.io/logging-levels/

格式

这一个观点有些笼统,每个公司甚至每个项目组都有自己的一套规范。

没有那个最好,只有哪个适合。

通常日志打印格式应包含[系统来源] 错误描述 [关键信息],日志信息要能打印出能看懂的信息,有前因和后果。方法的入参和出参也要考虑打印出来。

说到这里,不得不吐槽一下我自己,先前做一个业务的时候,打过如下形式的日志:

WARNING: 2020-11-19 16:38:58 /home/disk2/ferry4/ONLINE_SERVICE/other/ferry/task_workspace/7d223742c6f116932efc77c2e0cd72d0/xxx/models/logic/activity_game.go:167 GetStrategyInfo for nshead-ral-err, err=json unpack error: struct  FeedList []api.GameFeedListItem "json:\\"feed_list\\""; Errno int "json:\\"errno\\""; ErrMsg string "json:\\"err_msg\\""; Num int "json:\\"num\\"" .FeedList: []api.GameFeedListItem: api.GameFeedListItem.DisplayStrategy: struct  Mark int "json:\\"mark\\""; Type int "json:\\"type\\""; Title string "json:\\"title\\"" .Category: QRatio: strconv.ParseFloat: parsing "3.5953483383199374e308": value out of range


看完这条日志,不知道你有啥想法。反正对我自己来说,内心的想法就是:laji,这跟没打有什么区别啊。

可以说这条日志除了告诉我:“喂,你写的代码出错了!”之外,啥也没了。

那怎么针对这一个问题,作出改进呢?我觉得不妨从以下几点入手:

  • 位置
    • 逻辑分界处
    • 外部服务调用结果处
  • 内容
    • 格式,按照组内规范来。通常组内一般都会封装好的,实在不行 log4j、logus 等优秀的开源日志组件也是不错的选择。
    • 日志中是否包含关键过滤点,能否通过日志中某个参数唯一过滤出该条日志

本来想就着每一条,写点代码做个详细的剖析。但还是被懒惰打败,没能写出点demo瞅瞅。

中午和同事吃饭的时候,给我看了一个视频,画面中,一个男生在大雪纷飞之中,用力朝着一棵落满了雪的树踹去,顿时落了一身的雪。文案写的有一点伤感:

他朝若是同淋雪,此生也算共白头。

写的还怪带劲儿咧,哈哈哈。

以上是关于关于生产环境打日志的一些思考的主要内容,如果未能解决你的问题,请参考以下文章

MyBatisPlus 日志的两个坑:生产环境不打日志多数据源日志配置等

MyBatisPlus 日志的两个坑:生产环境不打日志多数据源日志配置等

生产环境上 “全链路压测体系” 建设方案的思考与实践

关于前端错误监控日志系统

关于微服务技术架构的思考

oracle 11g生产环境清理归档日志脚本