Logback实用技巧

396 阅读2分钟

好文分享:Java日志框架:logback详解

Logback的详细介绍在# Java日志框架:logback详解 中已经有了,这边就不再重复造轮子。就讲一下日常使用中,如何更好的使用log。

1 屏蔽日志

来了一个需求,是需要捞线上数据按某些规则统计下有多少脏数据。很简单嘛,写个脚本任务,打点log看看就行了,快速写完代码完事,但是查log的时候发现,因为数据量很大,打印了太多的日志,而公司的任务平台只保留100M左右的日志文件,导致打印的都是Mybatis的SQL日志,后面的正经日志都被截断了。处理方案大致就是两种,分别从Mybatis和Logback入手。

1.1 Mybatis的日志

Mybatis的日志就是一个个SQL语句,正常本地debug的时候其实这些SQL都是有,所以一般会在dev环境下开启这个,在线上环境一般没必要打开,原因有二:

  • log太多,影响线上问题排查,需要确保线上只有必要的log
  • log打太多是会影响QPS的,因为log需要写磁盘,比较影响性能

Mybatis日志打印的相关配置在application.yml文件中,如果要开启日志就用DEBUG,否则用OFF,或者直接删掉这个配置参数即可

logging.level:
  com.lbh.dal.mapper: DEBUG   # OFF是关闭

1.2 Logback配置

一般都会在项目中配置一个logback.xml用于控制log的打印,详细可以看看转载的那篇文章。

首先明确下我要处理的问题:BaseJdbcLogger会打印DEBUG等级的SQL日志,我要去除这些无用的日志。当前配置为

# application.yml
...
logging.level:
  com.lbh.dal.mapper: DEBUG
...
# logback.xml
<configuration scan="true" scanPeriod="10000">
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

1.2.1 根据包路径排除

一个思路是,我就不想这个包给我打印日志了,全部OFF,于是我就在logback.xml中把这个给禁用了,在configuration中增加配置:

    <logger name="com.lbh.dal.mapper" level="OFF"/>

最终效果是会仍然打印日志,这个配置完全没生效。

结果是不可行,猜测原因是logback.xml的初始化早于springboot,而springboot的配置文件中的logging配置等价于logback.xml的配置,springboot后初始化会覆盖logback.xml。

image.png

后续进行了实验验证了这个观点:

  • 实验一:<logger>配置为 TRACE,logging不配置,会打印到TRACE级别的日志
  • 实验二:<logger>配置为 TRACE,logging配置为TRACE级别日志,会打印到TRACE级别的日志
  • 实验三:<logger>配置为 TRACE,logging配置为DEBUG级别日志,会打印到DEBUG级别的日志

1.2.2 Filter排除

另一个思路就是,根据日志级别排除,一般来说,DEBUG日志与问题排查无关,所以我只需要INFO级别以上的日志即可。修改STDOUT的配置为:

# logback.xml
<configuration scan="true" scanPeriod="10000">
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
    </appender>
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

这里将过滤INFO级别以下的日志。这个配置最终是生效了,但是这个配置的问题就在于会AOE到其余的DEBUG日志,需要按需使用。