log4j2相信大家非常常见了,以前基本去了项目每个都有,然后也都直接用,很少有时间研究过它,这不这两天稍微空了点,学习了下,然后写下了这篇文章记录。
1.springboot有个默认的日志框架,首先我们要在Maven依赖中移除它:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
exclusion>
exclusions>
dependency>
2.加入log4j2的依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-log4j2artifactId>
dependency>
3.灵活配置。我们知道springboot的配置,可以用spring.profiles.active去灵活配置开发环境和线上环境,日志配置也有相同的实现方法。
只需要在application.properties中去指定配置的文件名就好
logging.config=classpath:log4j2.xml
所以log4j2.xml的命名可以多个,比如log4j2-dev.xml,log4j2-release.xml等,然后在这里灵活切换。我这里因为就单一环境,所以直接用log4j2.xml。
4.添加一个启动类(启动类命名为了偷懒,就用以前的demo),加入测试代码,就可以进行下一步了。
@SpringBootApplication
public class LeetcodeTestApplication{
private static final Logger logger = LoggerFactory.getLogger(LeetcodeTestApplication.class);
public static void main(String[] args) {
SpringApplication.run(LeetcodeTestApplication.class, args);
logger.trace("test:{}",1);
logger.debug("test:{}",2);
logger.info("test:{}",3);
logger.warn("test:{}",4);
logger.error("test:{}",5);
}
}
<configuration>
<Properties>
<property name="FILE_PATH" value="./logs"/>
<property name="FILE_NAME" value="Log4j2Test"/>
Properties>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<Filters>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
Filters>
<PatternLayout
pattern="%style{%d{ISO8601}}{bright,green} %highlight{%-5level} [%style{%t}{bright,blue}] %style{%C{}}{bright,yellow}: %msg%n%style{%throwable}{red}"
disableAnsi="false" noConsoleNoAnsi="false"/>
Console>
<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log"
filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="10MB"/>
Policies>
<DefaultRolloverStrategy max="15"/>
RollingFile>
<RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log"
filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="10MB"/>
Policies>
<DefaultRolloverStrategy max="15"/>
RollingFile>
<RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log"
filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="10MB"/>
Policies>
<DefaultRolloverStrategy max="15"/>
RollingFile>
appenders>
<loggers>
<root level="info">
<appender-ref ref="Console" level="info"/>
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileWarn"/>
<appender-ref ref="RollingFileError"/>
root>
loggers>
configuration>
运行我们刚刚的测试代码,效果图如下:


由于本文第二大点的xml文件中设置了info、error、warn三个,所以这里会分别出现三个gz文件。当然我们这里还可以设置文件夹名,让他通过时间来创建不同的文件夹:filePattern=“logs/$${date:yyyy-MM}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_-%i.log.gz”>
<loggers>
<root level="trace">
<appender-ref ref="Console" level="trace"/>
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileWarn"/>
<appender-ref ref="RollingFileError"/>
root>
loggers>
<Logger name="com.alibaba.cloud.dubbo" level="error"/>
高级扩展,异步日志:使用下面标签需要加入 disruptor依赖。
常用日志级别排序:trace
日志level层级关系
在目录二中的log4j2.xml文件中,我们可以看到很多地方都在用level字段,到底依哪个为准?下面就将给你说说,按照层级顺序:
第一:root标签上的level,最高标准(排除configuration),下面的appender-ref标签,如果不指定level的话,默认使用root标签上的level,如果某个日志消息的级别低于此级别,它将被忽略。
第二:appender-ref标签上的level,它只能设置比root的level高,不然会被忽略。
第三:ThresholdFilter标签上的level,它只能设置比appender-ref的level高,不然会被忽略。
ThresholdFilter详解:
(1)属性详解
onMatch="ACCEPT"匹配该级别及以上级别;
onMatch="DENY"不匹配该级别及以上级别;
onMismatch=“ACCEPT” 表示匹配该级别以下的级别;
onMismatch=“DENY” 表示不匹配该级别以下的级别;
“NEUTRAL”:中立策略,不讨论。
(2). 单一应用
匹配INFO级别以及以上级别,不匹配INFO级别以下级别,即: 匹配 >= INFO的级别
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
不匹配WARN级别以及以上级别,匹配WARN级别以下级别,即: 匹配 < WARN的级别
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT"/>
几个例子总结一下:
1.root的level为error,ppender-ref为info,ThresholdFilter为info,最后只输出error。
2.root的level为info,ppender-ref为warn,ThresholdFilter为info,最后只输出大于等于warn的。
2.root的level为info,ppender-ref为info,ThresholdFilter为warn,最后只输出大于等于warn的。
最后一句话,root最高优先级,appender-ref第二优先级,ThresholdFilter最低优先级。