接触过一定数量的业务系统,大部分系统线上维护都是要你命3000,越老越要命。本文仅从软件工程角度给出一个合理的建议。
常见的让大家诟病的三个问题:
1. 日志文件太过简单,error一个日志,info一个日志,打开文件会发现一堆与业务无关的中间件日志,和组件心跳日志
2. 异常信息打印不规范,一个异常被多次抛出,多次打印同一条信息的异常栈,有效信息被大量的冗余日志冲散,不利于线上问题排查,这不属于本文章要讨论的问题,这是代码规范,要严格控制异常栈的打印。
3. logger 是有继承关系的!!!你生的孩子要管你爸叫爷爷,但是他可以选择不认祖宗。有些开发者搞不清楚logger继承关系,导致同一日志在不同文件下多次输出,维护系统的人看着累,日志也累啊,它见谁都要认祖归宗,其实搞清楚继承关系可以让我们日志输出孑然一身轻。
注:一些聪明但是神经大条的人确实不会对这些问题敏感,反正再乱的线团他们都能找到线头,这正促使了一堆牛人留下了一堆足以让接盘的新人头大的维护工作。但是显然业务系统中遗留这样完全不必要的问题,不利于业务系统的工作流水线标准化,造成新人工作交接上岗到熟练的周期不必要延长。
最近工作中再一次涉及到了日志整理的问题,虽然简单,但很少有人总结并留下思路,特录此文,希望大家对自己的接班人都温柔一些,干活的时候一时兴起,乱七八糟的操作不要太猛。
log4j 和 logback 区别是有的,本文仅以log4j 为示例,logback的配置不如log4j 灵活
log4j 日志配置的两个关键要素:
1. logger。如果把每一个类比作自然人,每一个自定义名称的logger比作法人,logger就可以是泛指的人,即logger 既可以以一个完整类名作为标识,也可以以开发者自定义的名称作为标识。要做精确控制的时候只要按照完整类名定义logger即可。
2. appender 。日志输出到不同的文件。建议的做法:
系统所有的error日志输出到error.log , 对输出到这个文件的日志严格控制
系统其他级别的日志统一按照业务模块,组件角色其中一个维度(注意是其中一个,按照自己的需求,不要多维度组合)将非error日志区分文件输出。
log4j的输出日志级别的四个关键属性:
<logger name="*****" additivity="false">
<level value="INFO"/>
</logger>
1. level标签里值是设定本logger的最低级别,即该类日志可以输出的最低级别的日志记录
2. additivity:表示Logger不会在父Logger的appender里输出,默认为true。配置additivity="false", 就能确保该日志记录只会在一个文件中输出,当然根据开发者对业务系统的掌握程度,这个字段应该灵活设置,让日志更简洁,分类更清晰。
<appender name="console" class="*******">
<param name="file" value="${log4j_dir}/***/monitor-error.log" />
....
<param name="threshold" value="info" />
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMax" value="error"/>
<param name="LevelMin" value="info"/>
</filter>
</appender>
3. threshold 属性, 在appender指定日志输出的最低级别,默认为DEBUG。
4. filter 子域, 这就是一个可以展开的内容,具体参见https://www.cnblogs.com/yulinlewis/p/10152875.html
只要明确上面的这些概念,就可以让那个我们的系统日志变得更加清晰明了,采用本文推荐的日志设计一定会减轻日常的系统维护工作。从而减轻不必要的脑力负担,也让应用维护能够有一个相对标准的流程。
网友评论