源码:https://github.com/yulc-coding/java-note/tree/master/log4j2
相关文章: Spring Boot Logback 日志简单使用
功能点
- 不同级别生成不同日志文件;
- 设置单个日志文件的大小;
- 按日期生成日志文件;
- 生成自定义类别日志文件;
- 设置指定包或者类的日志输出级别;
- 异步记录日志(需要引入 LMAXDisruptor)
开始
- Log4j2配置和Logback类似
- Spring Boot 默认使用了Logback作为日志框架,所以要在pom中去除对Logback的引用
- 如果需要实现异步日志功能,需要在pom中引入LMAXDisruptor
- 在 src/main/resources 下新建XML文件 log4j2.xml
pmx文件
<!--使用 log4j2 Spring-boot中去掉logback的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 使用log4j2进行日志输出-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- 异步日志支持 -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>
基本结构
<!--
status 表示log4j2本身打印日志的级别
monitorInterval:自动检测修改配置文件和重新配置本身的时间,单位秒
-->
<Configuration status="INFO" monitorInterval="60">
<!--变量配置,通过${name} 来引用-->
<Properties>
<property name="" value="" />
</Properties>
<!-- 配置日志输出格式 -->
<Appenders>
<!-- 控制台打印 -->
<Console name="" target="SYSTEM_OUT">
<!-- 格式化输出 -->
<PatternLayout pattern=""/>
</Console>
<!--将日志输出到文件,append为true,则在日志文件中追加日志,为false则每次项目启动清空文件重新生成,实际作用不大-->
<File name="" fileName="" append="true">
<!-- 日志级别过滤 -->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="" />
</File>
<!--滚动的方式生成文件 fileName最新的文件名,filePattern 归档的文件名格式 -->
<RollingFile name="" fileName="" filePattern="">
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}" />
<Policies>
<!--
interval属性用来指定多久滚动一次,默认是1,这里配合filePattern
如果 filePattern 为 yyyy-MM-dd,则按天生成归档日志
如果 filePattern 为 yyyy-MM-dd HH-mm,则按分钟生成归档日志
-->
<TimeBasedTriggeringPolicy interval="1"/>
<!--单个文件的大小-->
<SizeBasedTriggeringPolicy size="5M"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
<DefaultRolloverStrategy fileIndex="max" max="15"/>
</RollingFile>
</Appenders>
<!-- 配置要输出的日志 -->
<Loggers>
<!-- 自定义输出 -->
<logger name="" level="" additivity="">
<AppenderRef ref="" />
</logger>
<!-- AsyncRoot - 异步记录日志 - 需要LMAXDisruptor的支持 -->
<AsyncLogger name="" level="" additivity="">
<AppenderRef ref=""/>
</AsyncLogger>
<!-- 指定项目的根日志 -->
<Root level="info">
<AppenderRef ref=""/>
<AppenderRef ref=""/>
</Root>
</Loggers>
</Configuration>
Properties 自定义变量
<Properties>
<!--
格式化输出:
%d表示日期;
%X打印自定义的数据,通过 org.sl4j.MDC 设置,ex: MDC.put("user", "aaa");
%thread表示线程名;
%-5level:级别从左显示5个字符宽度;
%logger{50} 表示logger名字最长50个字符,否则按照句点分割
%msg:日志消息;
%n是换行符
-->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{user}]-[%X{args}] [%thread] %-5level %logger{50} - %msg%n" />
<!-- 定义日志存储的路径-->
<property name="LOG_HOME" value="./logs/" />
</Properties>
Appenders 配置日志输出格式
- Console:控制台打印
<!-- 控制台打印 -->
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
- File:普通日志文件输出
<!--文件会打印出所有信息,append为true,则在日志文件中追加日志,为false则每次项目启动清空文件重新生成,实际作用不大-->
<File name="FileLog" fileName="${LOG_HOME}/file.log" append="true">
<!-- 只输出info及以上级别的信息(info、warn、error)(onMatch),其他的直接拒绝(onMismatch) -->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}" />
</File>
- RollingFile:按照配置的规则滚动式输出日志文件
<!-- 常规info,
fileName为最新的日志文件,
每当大小超过size,则会以 filePattern 的格式重新生成一个归档文件
这里设置每天会生成一个归档文件
-->
<RollingFile name="RollingFileInfo" fileName="${LOG_HOME}/info.log" filePattern="${LOG_HOME}/info-%d{yyyy-MM-dd}-%i.log">
<!-- 只打印info级别日志 注意先后顺序,优先排除不需要的级别-->
<Filters>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}" />
<Policies>
<!--
interval属性用来指定多久滚动一次,默认是1,这里配合filePattern
如果 filePattern 为 yyyy-MM-dd,则按天生成归档日志
如果 filePattern 为 yyyy-MM-dd HH-mm,则按分钟生成归档日志
-->
<TimeBasedTriggeringPolicy interval="1"/>
<!-- 指定单个日志文件的大小 -->
<SizeBasedTriggeringPolicy size="5M"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
<DefaultRolloverStrategy fileIndex="max" max="7"/>
</RollingFile>
Loggers 设置要打印的日志
包含 Logger 和 Root
Logger自定义设置,可以设置指定包活着类的日志级别,方便与调试、可以设置指定包或者类或者指定logger输出到单独的文件、可以一步输出日志(需要LMAXDisruptor的支持)
Root 根日志设置,所有Logger
<Loggers>
<!--设置指定包或类的日志级别,ex: 过滤掉spring和mybatis的一些无用的DEBUG信息-->
<logger name="org.springframework" level="INFO"></logger>
<logger name="org.mybatis" level="INFO"></logger>
<!-- 指定具体的包或者类生成单独的文件 additivity 为false 日志不会向上传递,为true,在对应的root日志里面也会打印-->
<Logger name="org.ylc.note.log4j2.service" level="info" additivity="false">
<AppenderRef ref="RollingFileMyService" />
</Logger>
<!-- 指定logger为 schedule 的日志生成单独的文件 这里的name 和 LoggerFactory.getLogger("schedule") 中的属性一样-->
<Logger name="schedule" level="info" additivity="false">
<AppenderRef ref="RollingFileSchedule" />
</Logger>
<!-- AsyncRoot - 异步记录日志 - 需要LMAXDisruptor的支持 -->
<AsyncLogger name="asyncLog" level="info" additivity="false">
<AppenderRef ref="RollingFileAsync"/>
</AsyncLogger>
<!-- 指定项目的根日志 -->
<Root level="info">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="FileLog"/>
<AppenderRef ref="RollingFileInfo"/>
<AppenderRef ref="RollingFileError"/>
</Root>
</Loggers>
单元测试
@SpringBootTest
class Log4j2ApplicationTests {
/**
* 普通类日志
*/
private final Logger normalLogger = LoggerFactory.getLogger(Log4j2ApplicationTests.class);
/**
* 定时任务类日志,这里的name必须和XML中logger 的name一致,这里为 schedule
*/
private final Logger scheduleLogger = LoggerFactory.getLogger("schedule");
/**
* 异步处理日志
*/
private final Logger asyncLogger = LoggerFactory.getLogger("asyncLog");
@Autowired
private MyService myService;
/**
* 普通日志测试
*/
@Test
void normalLogTest() {
normalLogger.debug("this is a debug log with out args");
normalLogger.info("this is a info log with out args");
normalLogger.error("this is a error log with out args");
}
/**
* 带参数的日志测试
*/
@Test
void argsLogTest() {
MDC.put("user", "鱼大仙");
MDC.put("args", "参数");
normalLogger.debug("this is a debug log with args");
normalLogger.info("this is a info log with args");
normalLogger.error("this is a error log with args");
}
/**
* 独立日志测试
* 1、指定日志名称
* 2、指定包或者类
*/
@Test
void independentLogTest() {
// 指定名称
scheduleLogger.debug("this is a schedule debug log");
scheduleLogger.info("this is a schedule info log");
scheduleLogger.error("this is a schedule error log");
// 指定包或者类
myService.myLog();
}
/**
* 异步日志
*/
@Test
void asyncLogTest() {
asyncLogger.debug("this is a async log -- debug");
asyncLogger.info("this is a begin async log -- info");
asyncLogger.error("this is a begin async log -- error");
}
}