利用logback 设置不同包下的日志级别
1、实现效果:项目的整体的日志打印级别为error,但在某个包下或某个类想打印info级别的日志。
2、配置:
file是error级别日志打印;
special 是info级别日志打印;
file与special唯一不同是日志保存路径不同,其它策略相同;
通过 logger标签指定包路径或类路径并引用special;
<?xml version="1.0" encoding="utf-8"?> <configuration> <contextname>test</contextname> <appender name="file" class="ch.qos.logback.core.rolling.rollingfileappender"> <rollingpolicy class="ch.qos.logback.core.rolling.timebasedrollingpolicy"> <filenamepattern>${catalina.home}/logs/test/test.%d.%i.log</filenamepattern> <maxhistory>30</maxhistory> <timebasedfilenamingandtriggeringpolicy class="ch.qos.logback.core.rolling.sizeandtimebasedfnatp"> <maxfilesize>10mb</maxfilesize> </timebasedfilenamingandtriggeringpolicy> </rollingpolicy> <encoder> <pattern>%d %p (%file:%line\)- %m%n -[%x{x-b3-traceid:-},%x{x-b3-spanid:-}]</pattern> <charset>utf-8</charset> </encoder> </appender> <appender name="special" class="ch.qos.logback.core.rolling.rollingfileappender"> <rollingpolicy class="ch.qos.logback.core.rolling.timebasedrollingpolicy"> <filenamepattern>${catalina.home}/logs/test/special/special.%d.%i.log</filenamepattern> <maxhistory>30</maxhistory> <timebasedfilenamingandtriggeringpolicy class="ch.qos.logback.core.rolling.sizeandtimebasedfnatp"> <maxfilesize>10mb</maxfilesize> </timebasedfilenamingandtriggeringpolicy> </rollingpolicy> <encoder> <pattern>%d %p (%file:%line\)- %m%n -[%x{x-b3-traceid:-},%x{x-b3-spanid:-}]</pattern> <charset>utf-8</charset> </encoder> </appender> <appender name="stdout" class="ch.qos.logback.core.consoleappender"> <encoder> <pattern>%d %p (%file:%line\)- %m%n </pattern> <charset>utf-8</charset> </encoder> </appender> <!--打印sql--> <logger name="daolog" level="error" /> <!-- 记录special操作日志 --> <logger name="aaa.bbb.ccc.demoservice" level="info" > <appender-ref ref="special"/> </logger> <root level="error"> <appender-ref ref="file"/> <appender-ref ref="stdout"/> </root> </configuration>
补充知识:logback框架使用误区 如何将所有包的error级别日志集中打印到一个日志文件中
早就想写这个事情了,起因是自己想写一个东西,其中使用logback日志框架记录日志
打算 将所有包的error及以上级别日志打到一个文件中,各个包下的日志打到对应包的文件中。
起初写的xml配置类似于这样:
<!-- 其中一个appender,其他appender与其相同 ,只有name、file和filenamepattern不同--> <appender name="all-error" class="ch.qos.logback.core.rolling.rollingfileappender"> <file>all-error.log</file> <rollingpolicy class="ch.qos.logback.core.rolling.sizeandtimebasedrollingpolicy"> <filenamepattern> ${log_dir}/all-error.%d{yyyy-mm-dd}.%i.log </filenamepattern> <maxfilesize>100mb</maxfilesize> <maxhistory>60</maxhistory> <totalsizecap>20gb</totalsizecap> </rollingpolicy> <encoder> <pattern> %d{yyyy-mm-dd hh:mm:ss.sss} [%thread] %-5level %logger - %msg%n </pattern> </encoder> </appender> <logger name="com.some.package1" level="info" additivty="true"> <appender-ref ref="appender-1"/> </logger> <logger name="com.some.package2" level="info" additivty="true"> <appender-ref ref="appender-2"/> </logger> <logger name="com.some" level="error" additivty="true"> <appender-ref ref="all-error"/> </logger>
然而运行后却发现,这样配置后的,并没有达到预期目标。
反而,所有info及以上的信息,不仅在appender appender-1和appender-2对应的日志文件中有,在appender为all-error对应的日志文件中也都有,这是为何?
追踪了一下断点,发现如下代码片段:
/** * invoke all the appenders of this logger. * * @param event * the event to log */ public void callappenders(iloggingevent event) { int writes = 0; for (logger l = this; l != null; l = l.parent) { writes += l.appendlooponappenders(event); if (!l.additive) { break; } } // no appenders in hierarchy if (writes == 0) { loggercontext.noappenderdefinedwarning(this); } }
这段代码来自logback的 ch.qos.logback.classic.logger文件,是最终决定日志内容输出在哪里的代码。
从这段代码我们可以发现:
1. logback会找到第一个符合日志级别要求的logger,然后将日志内容输入到这个logger下配置的appender中。举例来说:如果有一个com.some.package1内的类的info级别日志,那么首先会找到logger com.some.package1,然后找到logger下配置的appender appender-1;最后根据appender-1的配置,将日志内容输出到appender-1配置的文件中。
2. 之后,logback根据additivty检查logger是否允许继承,如果配置为true(默认为true),则查找上一级logger(实际是按照以包名为name查找上一层包的logger),找到logger后,不再判断logger配置是否符合日志级别要求,直接找到对应的appender,将日志内容输出。
这就带来了一个问题,位于低层次包的logger,在接收到日志后,不仅会把它输出到自身的appender中,还会将其传递给位于高层次包logger的appender中,无论高层次包logger配置的日志级别是什么。正因为如此,所以我打算将所有包的error级别 日志输出到一个文件的目的没有实现,反而所有info及以上级别的日志都输出了。
按照这个思路,如果logger com.some.package1和com.some.package2日记级别为error,而logger com.some日志级别为info的话,是否所有info及以上级别的日志都可以记入logger com.some对应的appender下,而error及以上级别的日志会记入logger com.some.package1和com.some.package2呢?测试证明,是这样。
知道了为什么上面的配置达不到目的,接下来要考虑的是,借助什么方式实现这个需求呢?
logback提供了实现需求的方式:借助filter来做:
既然logger无法判断日志级别,那我们可以在对应的appender里判断日志级别。
logback的过滤器使用起来可以达到对每一条日志的deny、accept和neutral。
根据文章开始提出的需求,我们需要的是一个绑定appender的,过滤日志等级的filter,那么ch.qos.logback.classic.filter.thresholdfilter正好是我们需要的。通过加入如下配置,appender all-error将只能接受error及以上的日志:
<filter class="ch.qos.logback.classic.filter.thresholdfilter"> <level>info</level> </filter>
完整的xml配置如下,仅改变了filter的部分,就实现了需求:
<!-- 其中一个appender,其他appender与其相同 ,只有name、file和filenamepattern不同,并且没有filter的标签--> <appender name="all-error" class="ch.qos.logback.core.rolling.rollingfileappender"> <file>all-error.log</file> <filter class="ch.qos.logback.classic.filter.thresholdfilter"> <level>error</level> </filter> <rollingpolicy class="ch.qos.logback.core.rolling.sizeandtimebasedrollingpolicy"> <filenamepattern> ${log_dir}/all-error.%d{yyyy-mm-dd}.%i.log </filenamepattern> <maxfilesize>100mb</maxfilesize> <maxhistory>60</maxhistory> <totalsizecap>20gb</totalsizecap> </rollingpolicy> <encoder> <pattern> %d{yyyy-mm-dd hh:mm:ss.sss} [%thread] %-5level %logger - %msg%n </pattern> </encoder> </appender> <logger name="com.some.package1" level="info" additivty="true"> <appender-ref ref="appender-1"/> </logger> <logger name="com.some.package2" level="info" additivty="true"> <appender-ref ref="appender-2"/> </logger> <logger name="com.some" level="error" additivty="true"> <appender-ref ref="all-error"/> </logger>
更多关于logback的filter的讲解,请见
以上这篇利用logback 设置不同包下的日志级别就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。