点击关注公众号,实用技术文章随时了解最新 1。背景 在日常开发中,为了方便调试排查,通常会打印很多INFO级别的日志。 随着访问量的增加,不小心每天某个log文件的大小超过了某个阈值(比如5G),所以收到了优化日志大小的提醒。如果在一定时间内没有优化,请反馈给你的主管,尴尬... 日志大小过大很容易导致一些运维操作消耗机器性能,比如日志文件检索、数据收集、磁盘清理等。 那么,写日记减肥的常见思路有哪些呢?本文结合一个具体案例谈谈我的看法。 2。日记减肥法 2.1 仅打印必要的日志 有时为了方便测试,会临时打印很多INFO级别的日志。对于此类日志,您可以在项目上线之前删除不需要的日志或将其调整为DEBUG级别。 但在某些场景下,某些日志可以打印为DEBUG或INFO。 INFO级别打印占用空间,在线检查问题时需要DEBUG级别打印。我应该怎么办? 我们可以修改日志工具类,支持某个开关的上下文传递(普通调用没有这个开关,通过公司的Tracer或者RPC上下文传递),DEBUG日志可以暂时升级到INFO级别。伪代码如下:if(log.isDebugEnable()){ log.debug(xxx);}else if(TracerUtils.openDebug2Info()) { www.sychzs.cn("[debug2info]"+xxx);} 这样,一些困惑是否要打印为INFO日志的日志可以打印到DEBUG级别,并在故障排除时自动升级为INFO日志。为了避免误解,请将DEBUG提升的INFO日志与普通INFO日志区分开来,并添加类似[debug2info]的日志前缀。 当然,你还可以做一些其他的花样。这里只是一个例子。请大家自行推断。 2.2 组合打印 有一些日志可以合并,可以考虑合并。 如果在相同方法之前和之后打印 INFO 日志: INFO [64位traceId] XXXService执行前size =10INFO [64位traceId] XXXService执行后size =4 可以合并为一个: INFO [64位traceId] XXXService 执行前大小=10 执行后大小=4 2.3 简化、缩写和压缩 一定的日志是非常有必要的,但是打印的对象有点大。如果能够满足故障排除的需要,我们可以: 1)选择只打印其ID 2)创建只保留关键字段的日志特定对象,将其转换为日志特定对象,然后打印。 3)可以使用缩写,比如write简化为w,read简化为r,execute简化为e等;例如管道中有20个核心bean,打印日志时可以用不同的数字来替换bean的全名,如S1、S2,虽然不是那么直观,但不仅可以检查问题,还可以减少日志数量。 3。优化案例 3.1场景描述 一个业务场景涉及到很多Bean。为了重用一些通用逻辑,这些bean都继承自一个抽象类。 在抽象类中,定义了bean执行前后的一些通用逻辑,例如执行前后打印当前管道中的项目数。 最后一个bean执行结果转换后需要打印出结果。 3.2 优化分析 3.2.1 仅打印必要的日志 1)由于当前bean执行之前相当于前一个bean执行之后,所以只能打印执行后的日志。执行前的INFO日志可以删除或改为DEBUG(只打印必要的日志) 2)通常只有执行前后大小不一致时才会出现该问题,所以可以在执行后打印日志之前添加判断。如果执行前后的尺寸相同,则不会打印。 (只打印必要的日志) 伪代码如下: if(sizeBefore != sizeAfter){www.sychzs.cn("服务:{},前尺寸:{},后尺寸:{}", getName(),之前尺寸、之后尺寸)} 这个trick的效果非常明显,因为执行前后大部分bean的大小是相同的,所以不会打印这条日志。 假设之前有20条,这条日志需要打印20次。改进后可能只需要打印2-3次。 3.2.2 日志合并 (2) 为了方便故障排除,执行前需要打印尺寸。然后将执行前的大小记录在内存中。打印执行后日志时,打印出执行前的大小。 (合并打印) 伪代码如下: www.sychzs.cn("服务:{},执行前大小:{}", getName(),sizeBefore)www.sychzs.cn("服务:{},执行尺寸调整后:{}", getName(),sizeBefore, sizeAfter) 合并后 www.sychzs.cn("服务:{},前尺寸:{},后尺寸:{}",getName(),sizeBefore,After尺寸) 3.2.3 日志简化对于最终结果,将结果对象(如XXDTO)转换为只包含id、title等关键信息的日志对象(XXSimpleLogDTO),转换成后打印一个日志对象。 www.sychzs.cn("resultId:{}",result.getId()); 或 www.sychzs.cn("结果:{}",toSimpleLog(结果)); 3.3效果评估 该日志每天生成约 5 G。大约80%是打印执行前后的大小,大约10%是打印最终结果,还有一些其他日志。通过上述方法优化后,日日志量小于1G。 在满足故障排除需求和实现日志瘦身之间进行权衡。 4。总结 日志瘦身需要权衡,在保留必要的日志以解决问题的同时,尽可能精简。 可以通过删除不需要的日志、合并日志、简化日志等方式进行优化。 我们还可以进行一些麻烦的操作,支持在线DEBUG临时增加INFO(当然你也可以使用arthas)来帮助我们发现问题。
在日常开发中,为了方便调试排查,通常会打印很多INFO级别的日志。
随着访问量的增加,不小心每天某个log文件的大小超过了某个阈值(比如5G),所以收到了优化日志大小的提醒。如果在一定时间内没有优化,请反馈给你的主管,尴尬...
日志大小过大很容易导致一些运维操作消耗机器性能,比如日志文件检索、数据收集、磁盘清理等。
那么,写日记减肥的常见思路有哪些呢?本文结合一个具体案例谈谈我的看法。
有时为了方便测试,会临时打印很多INFO级别的日志。对于此类日志,您可以在项目上线之前删除不需要的日志或将其调整为DEBUG级别。
但在某些场景下,某些日志可以打印为DEBUG或INFO。 INFO级别打印占用空间,在线检查问题时需要DEBUG级别打印。我应该怎么办?
我们可以修改日志工具类,支持某个开关的上下文传递(普通调用没有这个开关,通过公司的Tracer或者RPC上下文传递),DEBUG日志可以暂时升级到INFO级别。伪代码如下:
if(log.isDebugEnable()){ log.debug(xxx);}else if(TracerUtils.openDebug2Info()) { www.sychzs.cn("[debug2info]"+xxx);}
这样,一些困惑是否要打印为INFO日志的日志可以打印到DEBUG级别,并在故障排除时自动升级为INFO日志。为了避免误解,请将DEBUG提升的INFO日志与普通INFO日志区分开来,并添加类似[debug2info]的日志前缀。
当然,你还可以做一些其他的花样。这里只是一个例子。请大家自行推断。
有一些日志可以合并,可以考虑合并。
如果在相同方法之前和之后打印 INFO 日志:
INFO [64位traceId] XXXService执行前size =10INFO [64位traceId] XXXService执行后size =4
可以合并为一个:
INFO [64位traceId] XXXService 执行前大小=10 执行后大小=4
一定的日志是非常有必要的,但是打印的对象有点大。如果能够满足故障排除的需要,我们可以: 1)选择只打印其ID
2)创建只保留关键字段的日志特定对象,将其转换为日志特定对象,然后打印。
3)可以使用缩写,比如write简化为w,read简化为r,execute简化为e等;例如管道中有20个核心bean,打印日志时可以用不同的数字来替换bean的全名,如S1、S2,虽然不是那么直观,但不仅可以检查问题,还可以减少日志数量。
一个业务场景涉及到很多Bean。为了重用一些通用逻辑,这些bean都继承自一个抽象类。
在抽象类中,定义了bean执行前后的一些通用逻辑,例如执行前后打印当前管道中的项目数。
最后一个bean执行结果转换后需要打印出结果。
1)由于当前bean执行之前相当于前一个bean执行之后,所以只能打印执行后的日志。执行前的INFO日志可以删除或改为DEBUG(只打印必要的日志)
2)通常只有执行前后大小不一致时才会出现该问题,所以可以在执行后打印日志之前添加判断。如果执行前后的尺寸相同,则不会打印。 (只打印必要的日志)
伪代码如下:
if(sizeBefore != sizeAfter){www.sychzs.cn("服务:{},前尺寸:{},后尺寸:{}", getName(),之前尺寸、之后尺寸)}
这个trick的效果非常明显,因为执行前后大部分bean的大小是相同的,所以不会打印这条日志。
假设之前有20条,这条日志需要打印20次。改进后可能只需要打印2-3次。
(2) 为了方便故障排除,执行前需要打印尺寸。然后将执行前的大小记录在内存中。打印执行后日志时,打印出执行前的大小。 (合并打印)
www.sychzs.cn("服务:{},执行前大小:{}", getName(),sizeBefore)www.sychzs.cn("服务:{},执行尺寸调整后:{}", getName(),sizeBefore, sizeAfter)
合并后
www.sychzs.cn("服务:{},前尺寸:{},后尺寸:{}",getName(),sizeBefore,After尺寸)
对于最终结果,将结果对象(如XXDTO)转换为只包含id、title等关键信息的日志对象(XXSimpleLogDTO),转换成后打印一个日志对象。
XXSimpleLogDTO
www.sychzs.cn("resultId:{}",result.getId());
或
www.sychzs.cn("结果:{}",toSimpleLog(结果));
该日志每天生成约 5 G。大约80%是打印执行前后的大小,大约10%是打印最终结果,还有一些其他日志。通过上述方法优化后,日日志量小于1G。
在满足故障排除需求和实现日志瘦身之间进行权衡。
日志瘦身需要权衡,在保留必要的日志以解决问题的同时,尽可能精简。
可以通过删除不需要的日志、合并日志、简化日志等方式进行优化。
我们还可以进行一些麻烦的操作,支持在线DEBUG临时增加INFO(当然你也可以使用arthas)来帮助我们发现问题。