日志过量优化
背景
有两个B端服务,因为不好的日志习惯,无效日志量过大,日志经常被自动覆盖,只能存几天,导致排查问题困难,针对此,做了下无效日志的清理优化, 本身没什么技术含量,但是操作起来比较恶心。
这个问题的关键是对于一个复杂的B端项目,每天百G的文件里量,如何找到无效日志。
首先, 查看日志文件,平均每天上百G的日志文件,docker的容量有成本
分析
打日志固然是个好习惯,但是往往我们的一些非关键日志会因为使用不当,或者通过调用含有日志的方法导致日志过多,带来两个影响,一是排查问题困难,二是无效日志会导致磁盘爆炸而不得不缩短日志保存周期。针对次总结了几种方法来处理
- 针对性处理
- 日志频次过高
- 单条日志过长且无用
- 特殊场景
- 高频定时任务
- 全局处理、切面(Java Spring下)等
- 通用性处理
- 日志环境分级打印
- 关键高频日志打印开关配置化
- 日志截断
日志频次过高
查询日志出现频次
// 查询高频日志
awk -F'[][]' '{print $6}' app.log | sort | uniq -c | sort -rn | head -n 20
根据此我们可以找到哪些高频日志,去看下是否真的需要以及合理,比如在我们这个场景下,每个小时的日志文件里有100多万次记录,排查发现是历史堆砌逻辑循环套循环的使用,大部分是不合理的。
单条日志过长且无用
// 显示日志文件里最长的10条日志,倒序排序
awk '{ print length, $0 }' app.log | sort -nr | head -n 10
查询有没有打印字节流、或者图片base64、或者size超长的list比如定时的缓存,getAll诸如此类。
高频定时任务日志
搜索项目代码里的高频定时任务、切面、全局处理等
日志环境分级打印
这个就不说了,需要的是日常开发中要规范些,不要随手打印,对写下的每一行代码负责。
关键高频日志打印开关配置化
对于量大、高频且用到的频次较低的日志,可以增加Apollo控制开关,控制是否开启。
比如我们有一个ETL服务,会将十几种上游数据,经过n层转换,以获取我们系统用到的归一化数据,整个上游数据是十几个库,如果全打印,必然会造成存储爆炸。
做法是,在入口和出口出保留完整日志,其他中间转换层,保留配置化的日志开关
if (AoplloConfig.getWorksheetTransOpen()) {
log.info("worksheetTransMsg={}", worksheetMsg);
}
日志截断
以Java logback为例,可以添加全局的日志截断操作,对于过长日志做截断操作处理。
可以通过继承ClassicConverter类重写convert方法来实现全局的日志输出前处理操作
参考logback下日志输出前处理操作——以日志脱敏为例