注
本文是使用 Maven + springMVC + slf4j + log4j2(v2.7) 示例,并不是纯粹的 log4j2 ,如果执行不使用 slf4j,只需要在调用的地方,修改 loggerFactory 即可。
一般情况下,不做特殊配置,是会打印出很多spring的日志信息,所以文章后续在讲解配置文件时,会提到如何为指定的类做特定配置。
一、Maven pom.xml 添加依赖
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.7</version>
</dependency>
注:若未使用 slf4j,则不需要引入 log4j-slf4j-impl。
二、添加 Log4j2.xml
添加位置: ${project}/src/main/resources 根目录
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别 trace, debug, info, warn, error, fatal -->
<!-- status:log4j相关的日志的打印级别,OFF即不打印,其他则按照标准级别配置即可,如 debug -->
<Configuration status="OFF">
<!-- 定义日志存放目录(相对路径) -->
<properties>
<property name="logPath">logs</property>
</properties>
<!-- 定义所有的输出器 -->
<Appenders>
<!-- 输出到控制台,下面分别是 debug、info、error 级别的配置 -->
<Console name="ConsoleDebugLog" target="SYSTEM_OUT">
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" />
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%xEx%n" />
</Console>
<Console name="ConsoleInfoLog" target="SYSTEM_OUT">
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" />
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%xEx%n" />
</Console>
<Console name="ConsoleErrorLog" target="SYSTEM_OUT">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" />
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%xEx%n" />
</Console>
<!-- INFO级别日志 按天输出到文件,归类到年月目录 -->
<RollingFile name="InfoRollingFileLog" fileName="${logPath}/heyvgou.log" filePattern="${logPath}/$${date:yyyyMM}/heyvgou-%d{yyyy-MM-dd}.log">
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" />
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%xEx%n" />
<Policies>
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
</Policies>
</RollingFile>
<!-- ERROR级别日志 按天输出到文件,归类到年月目录 -->
<RollingFile name="ErrorRollingFileLog" fileName="${logPath}/heyvgou-error.log" filePattern="${logPath}/$${date:yyyyMM}/heyvgou-error.log-%d{yyyy-MM-dd}.log">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" />
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%xEx%n" />
<Policies>
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<!-- 项目整体默认日志配置,此处最低级别为 debug -->
<Root level="debug">
<AppenderRef ref="ConsoleDebugLog" />
<AppenderRef ref="InfoRollingFileLog" />
<AppenderRef ref="ErrorRollingFileLog" />
</Root>
<!-- 针对指定的 source package 代码配置(若比默认配置的日志级别高,则相当于忽略默认配置的级别打印,实现去除“不必要”的日志)-->
<logger name="org.springframework" level="INFO" additivity="false">
<AppenderRef ref="ConsoleInfoLog" />
<AppenderRef ref="ErrorRollingFileLog" />
</logger>
<logger name="net.sf" level="INFO" additivity="false">
<AppenderRef ref="ConsoleErrorLog" />
<AppenderRef ref="ErrorRollingFileLog" />
</logger>
</Loggers>
</Configuration>
三、Log4j2.xml 特殊配置简要分析
上面的配置中已经存有很多注释,所以简单的就不在此做解释,下面是针对一些特殊配置做一些简要的分析和描述
1、Appenders - Console、RollingFile 配置
本人是分不同级别配置 Console ,主要是为了在后面针对不同的类、代码包做配置,指定输出级别,避免“不必要”的日志输出。
2、Loggers - logger - name 属性
<logger name="org.springframework" level="INFO" additivity="false">
<AppenderRef ref="ConsoleInfoLog" />
<AppenderRef ref="ErrorRollingFileLog" />
</logger>
<logger name="net.sf" level="INFO" additivity="false">
<AppenderRef ref="ConsoleErrorLog" />
<AppenderRef ref="ErrorRollingFileLog" />
</logger>
大家可以看到,我这里分别配置了2个
-
org.springframework:INFO 级别的打印日志,ERROR 级别的文件日志
-
net.sf:ERROR 级别的打印日志,ERROR 级别的文件日志
此处我配置的都是 package,那是否可以直接指定到类呢?答案是可以的,比如说 org.springframework.beans.factory.BeanFactory
四、log4j2 plugins 插件开发
1. 什么是 log4j2 插件?
我们现在使用的 log4j2 API,都是它自带的,比如说打印的格式 %d{yyyy-MM-dd HH:mm:ss} 日期、%logger{36} 类名 等,如果我们实现了自定义的插件,比如说 %sessionId 当前的会话ID 等,实现 Converter 接口即可。
2. 开发 log4j2 插件简单吗?
一般的实现还是挺简单的
3. log4j2 插件可以做什么?
有没有同学想过,在日志文件中,默认打印出当前登录的用户信息?注意,是默认打印出来的,不是自己 logger.info("当前登录的用户名:" + user.getName()),而是 logger.info("当前登录的用户名:")
4. 如何开发 log4j2 插件?
由于本文只是简介 log4j2 的环境搭建及配置,本人会在后续的博客中陆续发布 lo4j2 的一些封装文章以及插件的开发教程,欢迎大家关注留意。
敬请期待!