日志门面、实现框架和桥接器及实际使用
之前总是在项目中使用现成的日志框架,用着方便就不会去思考它的框架、发展和组成,别人怎么用我也怎么用。感觉就是很模糊不清楚,说不知道也知道点,说知道又讲不明白,看了不少文章,决定把这一块梳理一下。
1、现有日志的组成
可能说到日志,大家都知道一部分,什么slf4j、logback等等,其实现有的日志体系经过很长时间的发展,主要呈现三部分:
- 日志门面(只定义接口,不提供实现)
- 日志实现(日志框架)
- 适配器和桥接器(用于连通门面和实现)
一开始都是自己提供API接口,自己实现,如左边这种;慢慢的由于一些原因,同时方便将抽象的接口和具体的实现分离,对外的API接口是固定了,然后根据自己的需要去选择日志的具体实现,中间通过桥接器去连接适配。大致的关系图如下:
常见的日志门面如下:
JCL停止更新,Spring5.0后由Spring-jcl接入;SLF4J目前是被使用最多的,认可度最高的日志门面
常见的日志框架如下:
log4j目前已经停止更新,结合了logback的优点重新写了log4j2;jul(java.util.logging)是JDK自带的日志实现。
2、具体搭配使用
2.1、SLF4J绑定具体日志实现
下图是SLF4J官网的日志框架图,给出了SLF4J绑定到具体日志实现时,需要引入的jar包。
图最下方给出的不同颜色的含义,分别是抽象接口、原生支持SLF4J的实现、适配层、非原生支持SLF4J的实现。
- 抽象接口层都是slf4j-api,很好理解,因为slf4j主要就是做日志门面。
- 原生支持SLF4J的实现:有logback、slf4j-simple.jar、slf4j-nop.jar。
- 非原生支持SLF4J的实现,有log4j和jul,因为这两个在SLF4J之前就出现了,后面SLF4j出现后,大家觉得这个日志门面很优秀,所以出现了适配SLF4J和log4j、jul的桥接包,也就是下图中的slf4j-reload4j.jar和slf4j-jdk14.jar
- log4j2是最后出现的,可以说吸取了前面一些日志框架的优点,它既做日志门面,也做日志实现,自成一体,所以未在下面的图中出现。当然SLF4J和log4j2也可以搭配,使用log4j-slf4j-impl的桥接包。
注:logback、slf4j-simple.jar、slf4j-nop.jar之所以能天然支持SLF4J的接口是有原因的,slf4j-simple.jar、slf4j-nop.jar都是slf4j自带的实现框架,本身就是按slf4j-api的接口开发的。logback之所以也天然适配SLF4J,有两个原因,一是出现的先后原因,log4j ->JUL->JCL-> SLF4J -> logback -> log4j2,logback在SLF4J后面出现,第二个是因为这两个都是同一个作者写的。
上面的图来源于官网:https://www.slf4j.org/manual.html
2.2、从其他的日志实现/门面到SLF4J
其实大致的实现就是两步,一是选择SLF4J和具体实现,二是兼容旧的日志实现/门面到SLF4J。
例如我之前是用的JCL的API,不可能因为要换一个日志框架,把原先的日志代码都改掉吧(API的方法不一样,入参和使用方法也不一样),这个代价太大,我希望的是,原有的日志代码可以不动,后续的代码可以用新的SLF4J的API,桥接包就是为了达到这样的效果。
具体操作就三步:
1、移除掉旧的日志依赖
2、引入SLF4J提供的桥接依赖
3、项目中引入SLF4J和新的日志实现
上图来自于SLF4J官网:https://www.slf4j.org/legacy.html
3、实际应用
下面的举两个实际使用的例子,一是Springboot中的直接引入spring-boot-starter-logging(本质也是SLF4j+logback,内部添加了相关依赖);二是SLF4J+log4j2
3.1、spring-boot-starter-logging
- 依赖引入
如果是Springboot的项目,可以直接引入spring-boot-starter-logging依赖即可,自行选择对应的版本引入依赖,如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>2.7.8</version>
</dependency>
也可以单独引入slf4j、logback依赖,版本自行指定,如下:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.11</version>
</dependency>
- 增加日志的配置文件
配置文件放到resource目录下,文件名称为logback-spring.xml,则springboot来加载,如果是logback.xml,则由日志框架来加载,完整的日志文件配置如下,按日志级别分为多个文件,配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<!-- 引入spirng boot默认的logback配置文件 -->
<contextName>logback</contextName>
<!--日志输出路径-->
<property name="logDir" value="logs/test"/>
<!--日志输出格式-->
<property name="CONSOLE_LOG_PATTERN"
value="%d{HH:mm:ss.SSS} [%highlight(%thread)] %highlight(%-5level) %logger{20} - [%blue(%method),%line] - %msg%n"/>
<!--输出到控制台-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<!--先将今天的日志保存在这个文件中-->
<file>${logDir}/log_debug.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logDir}/debug/log-debug-%d{yyyy-MM-dd_HH-mm}.%i.log</fileNamePattern>
<!--单个日志文件最大15M-->
<maxFileSize>15MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大100MB,超过就会删除旧的日志-->
<totalSizeCap>100MB</totalSizeCap>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>NEUTRAL</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${logDir}/log_info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logDir}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--单个日志文件最大15M-->
<maxFileSize>15MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大100MB,超过就会删除旧的日志-->
<totalSizeCap>100MB</totalSizeCap>
</rollingPolicy>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${logDir}/log_warn.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logDir}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--单个日志文件最大15M-->
<maxFileSize>15MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大100MB,超过就会删除旧的日志-->
<totalSizeCap>100MB</totalSizeCap>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${logDir}/log_error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logDir}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--单个日志文件最大15M-->
<maxFileSize>15MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大100MB,超过就会删除旧的日志-->
<totalSizeCap>100MB</totalSizeCap>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--root配置必须在appender下边-->
<!--root节点是对所有appender的管理,添加哪个appender就会打印哪个appender的日志-->
<!--root节点的level是总的日志级别控制,如果appender的日志级别设定比root的高,会按照appender的日志级别打印日志,-->
<!--如果appender的日志级别比root的低,会按照root设定的日志级别进行打印日志-->
<!--也就是说root设定的日志级别是最低限制,如果root设定级别为最高ERROR,那么所有appender只能打印最高级别的日志-->
<root level="debug">
<appender-ref ref="STDOUT"/>
<appender-ref ref="DEBUG_FILE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="WARN_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
<!--配置多环境日志输出 可以在application.properties中配置选择哪个profiles : spring.profiles.active=dev-->
<!--生产环境:输出到文件,多个环境用英文逗号隔开-->
<springProfile name="prod">
<root level="info">
<appender-ref ref="DEBUG_FILE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
<appender-ref ref="WARN_FILE"/>
</root>
</springProfile>
<!--开发环境:打印控制台-->
<springProfile name="local">
<root level="debug">
<appender-ref ref="STDOUT"/>
</root>
</springProfile>
</configuration>
如果想要所有的日志打在一个文件里面,可以只增加一个RollingFileAppender,配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<!-- 引入spirng boot默认的logback配置文件 -->
<contextName>logback</contextName>
<!--日志输出路径-->
<property name="logDir" value="logs/test"/>
<!--日志输出格式-->
<property name="CONSOLE_LOG_PATTERN"
value="%d{HH:mm:ss.SSS} [%highlight(%thread)] %highlight(%-5level) %logger{20} - [%blue(%method),%line] - %msg%n"/>
<!--输出到控制台-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="LOG_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<!--先将今天的日志保存在这个文件中-->
<file>${logDir}/log_all.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logDir}/debug/log-debug-%d{yyyy-MM-dd_HH-mm}.%i.log</fileNamePattern>
<!--单个日志文件最大15M-->
<maxFileSize>50MB</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
<!--所有的日志文件最大100MB,超过就会删除旧的日志-->
<totalSizeCap>100MB</totalSizeCap>
</rollingPolicy>
</appender>
<!--root配置必须在appender下边-->
<!--root节点是对所有appender的管理,添加哪个appender就会打印哪个appender的日志-->
<!--root节点的level是总的日志级别控制,如果appender的日志级别设定比root的高,会按照appender的日志级别打印日志,-->
<!--如果appender的日志级别比root的低,会按照root设定的日志级别进行打印日志-->
<!--也就是说root设定的日志级别是最低限制,如果root设定级别为最高ERROR,那么所有appender只能打印最高级别的日志-->
<root level="debug">
<appender-ref ref="STDOUT"/>
<appender-ref ref="LOG_ALL"/>
</root>
<!--配置多环境日志输出 可以在application.properties中配置选择哪个profiles : spring.profiles.active=dev-->
<!--生产环境:输出到文件,多个环境用英文逗号隔开-->
<springProfile name="dev">
<!--单独指定包路径下的日志级别,和Root的日志级别取高者,即Root配置的日志级别是error,此处配置info,也是按error生效-->
<logger name="org.springframework.web" level="ERROR"/>
<root level="info">
<appender-ref ref="LOG_ALL"/>
</root>
</springProfile>
<!--开发环境:打印控制台-->
<springProfile name="local">
<root level="debug">
<appender-ref ref="STDOUT"/>
</root>
</springProfile>
</configuration>
- 两种方式使用,一种是类上加@Slf4j注解的方式,一种是通过日志工厂的方式,如下
@Slf4j注解的方式,这种方式需要配合Lombok插件使用:
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@Slf4j
@SpringBootApplication(scanBasePackages = {"org.example.*"})
public class Main {
public static void main(String[] args) {
log.info("这是info日志");
log.debug("这是debug日志");
log.warn("这是warn日志");
log.error("这是error日志");
log.trace("这是trace日志");
try {
SpringApplication.run(Main.class, args);
} catch (Exception e) {
log.error("errorInfo", e);
}
System.out.println("Hello world!");
}
}
日志工厂的方式:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = {"org.example.*"})
public class Main {
final static Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
logger.info("这是info日志");
logger.debug("这是debug日志");
logger.warn("这是warn日志");
logger.error("这是error日志");
logger.trace("这是trace日志");
try {
SpringApplication.run(Main.class, args);
} catch (Exception e) {
logger.error("errorInfo", e);
}
System.out.println("Hello world!");
}
}
3.2、Slf4j+Log4j2
- 依赖引入
最新的log4j-slf4j2-impl已经引了slf4j-api、log4j-api、log4j-core依赖,不需要重复引入。(此处引入jul-to-slf4j的目的是将日志统一,因为可能部分日志打印还是走的JUL)
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>2.0.7</version>
</dependency>
- 配置文件
配置文件可以灵活设置存储位置、日志格式、日志文件存储、删除以及指定包路径下的日志级别等等
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL,每60秒自动刷新读取配置-->
<Configuration status="WARN" monitorInterval="60">
<!-- 自定义一些变量 -->
<Properties>
<!-- 日志存储路径,注意路径开头加斜线,会无法输出日志文件-->
<Property name="log_base_dir">logs/test</Property>
<!-- 日志格式化配置-->
<Property name="log_pattern">[%d{yyyy-MM-dd HH:mm:ss.SSS}][%-5p][%T][%c.%M:%L] %msg%xEx%n</Property>
<!-- 单个日志文件最大大小,单位可以是KB, MB or GB -->
<Property name="max_single_file_size">10MB</Property>
</Properties>
<Appenders>
<!-- Console Appender常用于将日志输出到System.out,一般用在开发环境 -->
<Console name="Console" target="SYSTEM_OUT">
<!-- 只接受程序中DEBUG级别的日志进行处理-->
<filters>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
</filters>
<!-- 在大多数情况下,Appender将格式化LogEvent的责任委托给Layout -->
<PatternLayout pattern="${log_pattern}"/>
</Console>
<!-- 输出日志到DEBUG文件 -->
<RollingFile name="DebugLogRollingFile" fileName="${log_base_dir}/debug.log"
filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/debug_%d{yyyy_MM_dd_HH}_%i.log.gz">
<!--第一个过滤器,丢掉INFO及以上的日志,INFO以下的日志进入下一个过滤器,第二个过滤器保存DEBUG及以上的日志,Debug以下的日志丢掉,所以只保存debug级别的日志-->
<filters>
<ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
</filters>
<PatternLayout pattern="${log_pattern}" charset="UTF-8"/>
<!-- Policies内部的任意一个TriggeringPolicy满足触发条件,都会滚动日志 -->
<Policies>
<!-- 用于按时间滚动日志-->
<TimeBasedTriggeringPolicy interval="1" modulate="false"/>
<!-- 用于按文件大小滚动日志 -->
<SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
</Policies>
<!-- 同一天内的日志文件序号返回,超过就会删除 -->
<DefaultRolloverStrategy min="1" max="10"/>
</RollingFile>
<!-- 输出日志到INFO文件 -->
<RollingFile name="InfoLogRollingFile" fileName="${log_base_dir}/info.log"
filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/info_%d{yyyy_MM_dd_HH}_%i.log.gz">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<!-- 用于按时间滚动日志-->
<TimeBasedTriggeringPolicy interval="1" modulate="false"/>
<!-- 用于按文件大小滚动日志 -->
<SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
</Policies>
<!-- 同一天内的日志文件序号返回,超过就会删除 -->
<DefaultRolloverStrategy min="1" max="50" fileIndex="nomax"/>
</RollingFile>
<!-- 输出日志到WARN文件 -->
<RollingFile name="WarnLogRollingFile" fileName="${log_base_dir}/warn.log"
filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/warn_%d{yyyy_MM_dd_HH}_%i.log.gz">
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
</Policies>
<!-- 同一天内的日志文件序号返回,超过就会删除 -->
<DefaultRolloverStrategy min="1" max="50" fileIndex="nomax"/>
</RollingFile>
<!-- 输出日志到ERROR文件 -->
<RollingFile name="ErrorLogRollingFile" fileName="${log_base_dir}/error.log"
filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/error_%d{yyyy_MM_dd_HH}_%i.log.gz">
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
</Policies>
<!-- 同一天内的日志文件序号返回,超过就会删除 -->
<DefaultRolloverStrategy min="1" max="50" fileIndex="nomax"/>
</RollingFile>
<!-- 记录druid的SQL语句 -->
<RollingFile name="DruidSqlRollingFile" fileName="${log_base_dir}/druid.log"
filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/druid_%d{yyyy_MM_dd_HH}_%i.log.gz">
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
</Policies>
<DefaultRolloverStrategy fileIndex="nomax">
<Delete basePath="${log_base_dir}" maxDepth="2" testMode="true">
<IfFileName glob="*/druid_*.log.gz">
<IfAny>
<IfAccumulatedFileSize exceeds="300M"/>
<IfAccumulatedFileCount exceeds="100"/>
<IfLastModified age="30d"/>
</IfAny>
</IfFileName>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<!--定义logger,只有定义了logger并引入的appender,appender才会生效-->
<Loggers>
<Root level="ALL">
<AppenderRef ref="Console"/>
<AppenderRef ref="InfoLogRollingFile"/>
<AppenderRef ref="WarnLogRollingFile"/>
<AppenderRef ref="DebugLogRollingFile"/>
<AppenderRef ref="ErrorLogRollingFile"/>
</Root>
<!--记录druid-sql的记录-->
<Logger name="druid.sql.Statement" level="debug" additivity="false">
<appender-ref ref="DruidSqlRollingFile"/>
</Logger>
<!--指定不同包名下的日志级别,用于过滤不重要的日志-->
<Logger name="org.springframework" level="INFO"/>
<Logger name="org.mybatis" level="INFO"/>
<!--log4j2 自带过滤日志-->
<Logger name="org.apache.catalina.startup.DigesterFactory" level="error"/>
<Logger name="org.apache.catalina.util.LifecycleBase" level="error"/>
<Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn"/>
<Logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
<Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn"/>
<Logger name="org.crsh.plugin" level="warn"/>
<Logger name="org.crsh.ssh" level="warn"/>
<Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error"/>
<Logger name="org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration" level="warn"/>
<Logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
<Logger name="org.thymeleaf" level="warn"/>
<Logger name="org.hibernate.validator" level="warn"/>
</Loggers>
</Configuration>
Tips:
1、onMatch表示匹配当前级别日志和更高级别日志,onMismatch表示匹配低于当前级别的日志。
2、onMatch和onMismatch可以设置三个值:ACCEPT,DENY,NEUTRAL,依次表示接受(在当前过滤器处理)、拒绝(当前过滤器直接拒绝,不会到达下一个过滤器)和中立(表示当前过滤器不做处理,交由下一个过滤器处理)
3、应用多个过滤器需要加<fliters/>标签,只应用单个过滤器,可以直接使用<ThresholdFilter/>即可,这两种方式在上面完整的配置文件中均有使用。
4、灵活的采用多个过滤器,可以达到处理指定一个或几个日志级别的目的。
举个例子,加入我只想处理DEBUG级别的日志,可以如下配置:
<filters>
<ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
</filters>
第一个过滤器,onMatch="DENY"表示:对于INFO及以上的日志直接拒绝;onMismatch="NEUTRAL":只有DEBUG和更低级别的日志可以到下一个过滤器处理
第二个过滤器,onMatch="ACCEPT"表示:接受DEBUG及以上的日志; onMismatch="DENY":DEBUG级别以下的日志直接拒绝。
经过了第一个过滤器的处理,达到第二个过滤器的只有DEBUG及以下的日志,而第二个过滤器又只接受DEBUG及以上的日志,两者取交集,所以达到的效果就是只处理DEBUG级别的日志。
当然也可以如下配置:
第一个过滤器让DEBUG及以上的日志到达下一个过滤器,然后第二个过滤器只处理DEBUG及以下的日志,两者取交集,所以也可以达到只处理DEBUG日志的目的。
<filters>
<ThresholdFilter level="DEBUG" onMatch="NEUTRAL" onMismatch="DENY"/>
<ThresholdFilter level="INFO" onMatch="DENY" onMismatch="ACCEPT"/>
</filters>
- 使用方式
由于门面都是slf4j,所以使用方式和上面相同,一种是类上加@Slf4j注解的方式,一种是通过日志工厂的方式,不再赘述。