SpringBoot 使用 log4j2

仅个人记录使用!!

1. 如何使用

在 SpringBoot 中使用 log4j2:

SpingBoot 中默认的日志框架是 logback。

1.1 移除 SpringBoot 默认日志框架

根据引用的依赖中是否包含 sef4j,来决定是剔除 spring-boot-starter-logging 还是 logback-classic。

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
	<!-- 去掉springboot默认日志 -->
	<exclusions>
		<exclusion>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
		</exclusion>
	</exclusions>
</dependency>

<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-log4j12</artifactId>
</dependency>

1.2 配置文件位置

如果使用的是 spring-boot-starter-log4j2,默认识别 classpath 下的 log4j2-spring.xml

或者,也可以在application.properties 或 yml 中 指定日志配置文件位置

logging.config=classpath:log4j2.xml

2. 配置文件示例

<?xml version="1.0" encoding="UTF-8"?>
<!--
status          log4j2自身内部的日志级别
monitorInterval Log4j2自动检测配置更新间隔秒数
-->
<configuration status="WARN" monitorInterval="30">
	<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
	
	<!--变量配置-->
	<properties>
		<!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
		<!-- %logger{36} 表示 Logger 名字最长36个字符 -->
		<property name="LOG_PATTERN" value="%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"/>
		<!-- 定义日志存储的路径 -->
		<property name="FILE_PATH" value="logs"/>
	</properties>
	
	<appenders>
		
		<!--控制台输出-->
		<console name="Console" target="SYSTEM_OUT">
			<!--输出日志的格式-->
			<PatternLayout pattern="${LOG_PATTERN}"/>
			<!--过滤器 只统计 level 及其以上级别的信息(onMatch),其他的顺序处理(onMismatch)-->
			<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
		</console>
		
		<!--简单的日志文件 用于测试,不追加-->
		<File name="SimpleLog" fileName="${FILE_PATH}/simple.log" append="false">
			<PatternLayout pattern="${LOG_PATTERN}"/>
		</File>
		
		<!-- 日志输出到文件,按照每个小时归档,每100M拆分一次-->
		<!--RollingFile RandomAccessFile RollingRandomAccessFile-->
		<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log"
					 filePattern="${FILE_PATH}/${date:yyyyMMdd}/info-%d{yyyyMMdd-HH}-%i.log">
			
			<!--过滤器 只统计 level 及其以上级别的信息(onMatch),其他的顺序处理(onMismatch)-->
			<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
			<!--日志信息 格式-->
			<PatternLayout pattern="${LOG_PATTERN}"/>
			<!--指定规则-->
			<Policies>
				<!--在系统启动时,对之前日志触发策略,产生一个新的日志文件-->
				<OnStartupTriggeringPolicy />
				<!--interval属性用来指定多久滚动一次,跟filePattern有关-->
				<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
				<!--按照日志大小进行拆分-->
				<SizeBasedTriggeringPolicy size="100 KB"/>
			</Policies>
			<!--同一目录下最大文件编号,超过则重头开始覆盖。即%i,默认7-->
			<DefaultRolloverStrategy max="30">
				<!--要删除的路径以及目录深度-->
				<Delete basePath="${FILE_PATH}/${date:yyyyMMdd}/" maxDepth="1">
					<!--匹配指定文件-->
					<IfFileName glob="*.log">
						<!--删除超过指定时间的日志-->
						<IfLastModified age="10s">
							<!--<IfAny>-->
							<!--	<IfAccumulatedFileSize exceeds="300 KB" />-->
							<!--	<IfAccumulatedFileCount exceeds="10" />-->
							<!--</IfAny>-->
						</IfLastModified>
					</IfFileName>
				</Delete>
			</DefaultRolloverStrategy>
		</RollingFile>
	</appenders>
	
	<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
	<loggers>
		<!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
		<logger name="org.apache" level="ERROR"/>
		<logger name="org.mybatis" level="ERROR"/>
		<logger name="org.hibernate" level="ERROR"/>
		<logger name="tk.mybatis.mapper" level="ERROR"/>
		<logger name="com.alibaba.druid" level="ERROR"/>
		<logger name="org.springframework" level="ERROR"/>
		
		<root level="INFO">
			<appender-ref ref="Console"/>
			<appender-ref ref="SimpleLog"/>
			<appender-ref ref="RollingFileInfo"/>
		</root>
	</loggers>
</configuration>

3. 日志级别

  • All: 最低等级的,用于打开所有日志记录.
  • Trace: 是追踪,就是程序推进以下,你就可以写个 trace 输出,所以 trace 应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出.
  • Debug: 指出细粒度信息事件对调试应用程序是非常有帮助的.
  • Info: 消息在粗粒度级别上突出强调应用程序的运行过程.
  • Warn: 输出警告及 warn 以下级别的日志.
  • Error: 输出错误信息日志.
  • Fatal: 输出每个严重的错误事件将会导致应用程序的退出的日志.
  • OFF: 最高等级的,用于关闭所有日志记录.

4. pattern 参数

%d{HH:mm:ss.SSS} 表示输出到毫秒的时间
%t 输出当前线程名称
%-5level 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
%logger 输出logger名称,因为Root Logger没有名称,所以没有输出
%msg 日志文本
%n 换行

其他常用的占位符有:
%F 输出所在的类文件名,如Log4j2Test.java
%L 输出行号
%M 输出所在方法名
%l 输出语句所在的行数, 包括类名、方法名、文件名、行数qi

5. 滚动策略

5.1 SizeBasedTriggeringPolicy

按照日志大小来拆分:KB、MB、GB

5.1 TyiimeBasedTriggeringPolicy

每隔一段时间进行归档,需要和filePattern 一起使用;

filePattern 的配置:filePattern="${FILE_PATH}/${date:yyyyMMdd}/info-%d{yyyyMMdd-HH}-%i.log">

可在结尾处指定压缩。

TimeBasedTriggeringPolicy 根据 filePattern 的最小粒度进行归档。

5.3 SizeBasedTriggeringPolicy 和 TimeBasedTriggeringPolicy 混用

两者一起用时,SizeBasedTriggeringPolicy 在 TimeBasedTriggeringPolicy 的周期内正常进行日志拆分,在周期结束时 TimeBasedTriggeringPolicy 把剩下的日志再归档进行归档。

例如:每隔1分钟归档一次,日志按照1M拆分一个文件

如果在这一分钟内,有3.2M的日志进来。

SizeBasedTriggeringPolicy 会把日志拆分为info-1.log、info-2.log 和 info-3.log 放在指定目录

然后在这分钟结束的时候,TimeBasedTriggeringPolicy 把剩余的0.2M日志归档为 info-4.log ,与之前的三个文件放在一起

5.4 OnStartupTriggeringPolicy

在启动时,对之前存在文件触发滚动策略,产生一个新的日志文件。

直接表现为,重启时存在之前的日志。会将之前的日志生成一个新的文件,进行归档。

不开启这个,重启时会清空之前没有归档的日志。

如果重启时,触发配置删除策略,会把之前归档的日志删除,注意删除过期日志的时间。

在没有日志进来的时间段,是不会进行归档的,后续有日志进来才会触发之前周期的日志归档。

5.5 删除过期日志
<!--同一目录下最大文件编号,超过则重头开始覆盖。即%i,默认7-->
<DefaultRolloverStrategy max="30">
	<!--要删除的路径以及目录深度-->
	<Delete basePath="${FILE_PATH}/${date:yyyyMMdd}/" maxDepth="1">
		<!--匹配指定文件-->
		<IfFileName glob="*.log">
			<!--删除超过指定时间的日志-->
			<IfLastModified age="10s">
				<!--<IfAny>-->
				<!--	<IfAccumulatedFileSize exceeds="300 KB" />-->
				<!--	<IfAccumulatedFileCount exceeds="10" />-->
				<!--</IfAny>-->
			</IfLastModified>
		</IfFileName>
	</Delete>
</DefaultRolloverStrategy>

网上说,这里的粒度要跟 filePattern 设置的最小粒度匹配,不然不生效。

但是,经尝试 filePattern 的最小粒度时H,这里设置删除超过10s的日志是可以。

不知道是不是跟版本有关,还是理解有问题,需注意。

上一篇:springboot中使用log4j2日志框架


下一篇:如何让ubuntu启动时打印字符信息----字符启动