spring-boot使用log4j2

1.在 Spring Boot 应用中集成 Log4j2

首先在项目pom文件中引入Log4j的依赖,排除掉默认的logging

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--log4j2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<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>

在当前项目的resource目录下增加文件 log4j2.xml

img

下面介绍配置文件中各个节点,感兴趣的小伙伴也可以去官网查看

2.配置节点

2.1 根节点configuration

有两个属性:status,monitorinterval,两个子节点:Appenders和Loggers表名可以定义多个Appender和Logger

  • status,用来指定log4j本身的打印日志级别 OFF>FATAL>ERROR>WARN>INFO>DEBUG>TRACE>ALL
  • monitorinterval 重新读取配置文件的监测间隔时间,单位是s,最小是5s.

2.2 Properties

​ 属性(可选),用来定义常量(例如日志打印的模版),之后在其他配置项中通过${变量名}引用

2.3 Appenders

​ 常见的有三种子节点:Console、RollingFile、File

2.3.1 Console

​ 用来定义输出到控制台的Appender两个属性:name、target,一个节点:PatternLayout

  • name(属性):指定Appender的名字
  • target(属性):SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT.
  • PatternLayout(节点):指定输出日志的格式,可以使用pattern属性与Properties中定义的日志打印模板常量相结合,控制日志输出的模版,不设置则默认为:%m%n
2.3.2 File

​ 文件输出源,用于将日志写入到指定的文件,需要配置输入到哪个位置(例如:D:/logs/info.log)

  • name(属性)::指定Appender的名字.
  • fileName(属性):指定输出日志的目的文件带全路径的文件名.
  • PatternLayout(节点):输出格式,不设置默认为:%m%n.
2.3.3 RollingFile

​ 也是写入到文件,不同的是比File更加强大,可以指定当文件达到一定大小(如20MB)时,另起一个文件继续写入日志,另起一个文件就涉及到新文件的名字命名规则,因此需要配置文件命名规则
​ 这种方式更加实用,因为你不可能一直往一个文件中写,如果一直写,文件过大,打开就会卡死,也不便于查找日志。

  • name(属性):指定Appender的名字.
  • fileName(属性):指定输出日志的目的文件带全路径的文件名
  • PatternLayout(节点):输出格式,不设置默认为:%m%n
  • filePattern:指定新建日志文件的名称格式.
  • Policies(节点):指定滚动日志的策略,就是什么时候进行新建日志文件输出日志.
    • TimeBasedTriggeringPolicy(节点):Policies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am..而不是7am.
    • SizeBasedTriggeringPolicy(节点):Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小.
    • DefaultRolloverStrategy(节点):用来指定同一个文件夹下最多有几个日志文件时开始删除最l旧的,创建新的(通过max属性);可以指定压缩级别(通过compressionLevel属性),compressionLevel的值通常是一个介于0到9之间的整数,其中:0表示无压缩,1表示最快的压缩速度(但压缩率最低),9表示最高的压缩率(但压缩速度最慢)
      • Delete:清理旧日志文件的策略;basePath指定了日志文件所在的基目录;maxDepth用于指定清理或删除日志文件时搜索的目录深度,值是一个整数,表示从basePath开始向下搜索的目录层级数
      • IfFileName:Delete子节点,用于匹配要删除的文件名模式。glob接受一个通配符模式,用来匹配文件名。
        • IfLastModified:Delete子节点,用于检查文件的最后修改时间,并基于该时间点决定文件是否应该被清理或删除;age指定了文件最后修改时间与当前时间之间最大允许的时间差
          • 如果maxDepth=”0”,则只会考虑basePath所指向的目录本身,不包括任何子目录。
          • 如果maxDepth=”1”,则会考虑basePath所指向的目录及其直接子目录。
          • 如果maxDepth=”2”,则会考虑basePath所指向的目录、其直接子目录以及这些子目录下的子目录(即二级子目录)。

2.4 Logger

​ Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。level:日志输出级别,共有8个级别,按照从低到高为: All < Trace < Debug < Info < Warn < Error < Fatal < OFF

  • root :设定根日志的日志级别
  • name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点.
  • AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.如果指定了,那么会在指定的这个- Appender和Root的Appender中都会输出。
  • additivity:是否继承root节点,默认是true继承。默认情况下子Logger会继承父Logger的appender,也就是说子Logger会在父Logger的appender里输出。若是additivity设为false,则子Logger只会在自己的appender里输出,而不会在父Logger的appender里输出。

3.日志输出模板参数介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 格式化输出:
%date{yyyy-MM-dd HH:mm:ss.SSS}: 简写为%d 日期 2023-08-12 15:04:30,123
%thread: %t 线程名, main
%-5level:%p 日志级别,从左往右至少显示5个字符宽度,不足补空格 INFO
%msg:%m 日志消息 info msg
%n: 换行符
{cyan}: 蓝绿色(青色)
%logger{36}: %c 表示 Logger 名字最长36个字符
%C: 类路径 com.qq.demolog4j2.TestLog4j2
%M: 方法名 main
%F: 类名 TestLog4j2.java
%L: 行号 12
%l: 日志位置, 相当于 %C.%M(%F.%L) com.qq.demolog4j2.TestLog4j2.main(TestLog4j2.java:16)
%highlight:高亮显示,%highlight{%-5level}

如果控制台输出的日志级别没有高亮显示,Log4j2默认关闭了Jansi:一个支持输出ANSI颜色的类库 IDEA中,点击右上角->Edit+Configurations,在VM+options中添加-Dlog4j.skipJansi=false

下面就是我在开发中使用的一些配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF">

<properties>
<!-- 日志打印级别 -->

<property name="LOG_LEVEL">INFO</property>
<!-- APP名称 -->
<property name="APP_NAME" value="framework-project"/>
<!-- 日志文件存储路径 -->
<property name="LOG_HOME">./logs/</property>
<!-- 存储天数 -->
<property name="LOG_MAX_HISTORY" value="60d"/>
<!-- 单个日志文件最大值, 单位 = KB, MB, GB -->
<property name="LOG_MAX_FILE_SIZE" value="10 MB"/>
<!-- 每天每个日志级别产生的文件最大数量 -->
<property name="LOG_TOTAL_NUMBER_DAILY" value="10"/>
<!-- 压缩文件的类型,支持zip和gz,建议Linux用gz,Windows用zip -->
<property name="ARCHIVE_FILE_SUFFIX" value="zip"/>
<!-- 日志文件名 -->
<property name="LOG_FILE_NAME" value="${LOG_HOME}"/>
<property name="FILE_NAME_PATTERN" value="${LOG_HOME}%d{yyyy-MM-dd}"/>

<!--
格式化输出:
%date{yyyy-MM-dd HH:mm:ss.SSS}: 简写为%d 日期 2023-08-12 15:04:30,123
%thread: %t 线程名, main
%-5level:%p 日志级别,从左往右至少显示5个字符宽度,不足补空格 INFO
%msg:%m 日志消息 info msg
%n: 换行符
{cyan}: 蓝绿色(青色)
%logger{36}: %c 表示 Logger 名字最长36个字符
%C: 类路径 com.qq.demolog4j2.TestLog4j2
%M: 方法名 main
%F: 类名 TestLog4j2.java
%L: 行号 12
%l: 日志位置, 相当于 %C.%M(%F.%L) com.qq.demolog4j2.TestLog4j2.main(TestLog4j2.java:16)
-->
<!-- %d: 日期
%-5level: 日志级别,显示时占5个字符不足
[%t]: 线程名
%c{1.}: 显示调用者,只显示包名最后一截及方法名,前面的只取首字母
.%M(代码行号%L):
%msg%n": 需要打印的日志信息,换行:INFO>[MsgToMP:99]
Bright: 加粗 -->
<!--日志输出格式-控制台彩色打印-->
<property name="ENCODER_PATTERN_CONSOLE">%blue{%d{yyyy-MM-dd HH:mm:ss.SSS}} | %highlight{%-5level}{ERROR=Bright RED, WARN=Bright Yellow, INFO=Bright Green, DEBUG=Bright Cyan, TRACE=Bright White} | %yellow{%t} | %cyan{%c{1.}} : %white{%msg%n}</property>
<!--日志输出格式-文件-->
<property name="ENCODER_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %5pid --- [%15.15t] %c{1.} [%L] : %m%n</property>
<!--日志输出格式-控制台彩色打印-->
<property name="DEFAULT_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-5level} %style{%5pid}{bright,magenta} --- [%15.15t] %cyan{%c{1.} [%L]} : %m%n</property>
</properties>

<Appenders>
<!-- 控制台的输出配置 -->
<Console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="${DEFAULT_PATTERN}" />
</Console>
<!-- 打印出所有的info及以下级别的信息,每次大小超过size进行压缩,作为存档-->
<RollingFile name="RollingFileAll" fileName="${LOG_FILE_NAME}/${date:yyyy-MM-dd}/info.log" filePattern="${FILE_NAME_PATTERN}/info.log">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="${LOG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY" />
<!--输出日志的格式-->
<PatternLayout pattern="${ENCODER_PATTERN}" />
<Policies>
<!-- 归档每天的文件 -->
<TimeBasedTriggeringPolicy />
<!-- 限制单个文件大小 -->
<SizeBasedTriggeringPolicy size="${LOG_MAX_FILE_SIZE}" />
</Policies>
<!-- 限制每天文件个数 -->
<DefaultRolloverStrategy compressionLevel="9" max="${LOG_TOTAL_NUMBER_DAILY}">
<Delete basePath="${LOG_HOME}" maxDepth="1">
<IfFileName glob=".info.*.log" />
<IfLastModified age="${LOG_MAX_HISTORY}" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>

<RollingFile name="RollingFileDebug"
fileName="${LOG_FILE_NAME}/${date:yyyy-MM-dd}/debug.log"
filePattern="${FILE_NAME_PATTERN}/debug.log">
<Filters>
<ThresholdFilter level="DEBUG" />
<ThresholdFilter level="INFO" onMatch="DENY"
onMismatch="NEUTRAL" />
</Filters>
<PatternLayout pattern="${ENCODER_PATTERN}" />
<Policies>
<!-- 归档每天的文件 -->
<TimeBasedTriggeringPolicy />
<!-- 限制单个文件大小 -->
<SizeBasedTriggeringPolicy size="${LOG_MAX_FILE_SIZE}" />
</Policies>
<!-- 限制每天文件个数 -->
<DefaultRolloverStrategy compressionLevel="9"
max="${LOG_TOTAL_NUMBER_DAILY}">
<Delete basePath="${LOG_HOME}" maxDepth="1">
<IfFileName glob="*.debug.*.log" />
<IfLastModified age="${LOG_MAX_HISTORY}" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>

<RollingFile name="RollingFileWarn" fileName="${LOG_FILE_NAME}/${date:yyyy-MM-dd}/warn.log"
filePattern="${FILE_NAME_PATTERN}.warn.log">
<Filters>
<ThresholdFilter level="WARN" />
<ThresholdFilter level="ERROR" onMatch="DENY"
onMismatch="NEUTRAL" />
</Filters>
<PatternLayout pattern="${ENCODER_PATTERN}" />
<Policies>
<!-- 归档每天的文件 -->
<TimeBasedTriggeringPolicy />
<!-- 限制单个文件大小 -->
<SizeBasedTriggeringPolicy size="${LOG_MAX_FILE_SIZE}" />
</Policies>
<!-- 限制每天文件个数 -->
<DefaultRolloverStrategy compressionLevel="9"
max="${LOG_TOTAL_NUMBER_DAILY}">
<Delete basePath="${LOG_HOME}" maxDepth="1">
<IfFileName glob="*.warn.*.log" />
<IfLastModified age="${LOG_MAX_HISTORY}" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>

<RollingFile name="RollingFileError"
fileName="${LOG_FILE_NAME}/${date:yyyy-MM-dd}/error.log"
filePattern="${FILE_NAME_PATTERN}.error.log">
<Filters>
<ThresholdFilter level="ERROR" />
</Filters>
<PatternLayout pattern="${ENCODER_PATTERN}" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="${LOG_MAX_FILE_SIZE}" />
</Policies>
<DefaultRolloverStrategy compressionLevel="9" max="${LOG_TOTAL_NUMBER_DAILY}">
<Delete basePath="${LOG_HOME}" maxDepth="1">
<IfFileName glob="*.error.*.log" />
<IfLastModified age="${LOG_MAX_HISTORY}" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>

<!--只有定义了logger并引入以上Appenders,Appender才会生效-->

<Loggers>
<Logger name="com.example" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFileAll"/>
<AppenderRef ref="RollingFileDebug"/>
<AppenderRef ref="RollingFileWarn"/>
<AppenderRef ref="RollingFileError"/>
</Logger>
<root level="${LOG_LEVEL}">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFileAll"/>
<appender-ref ref="RollingFileDebug"/>
<appender-ref ref="RollingFileWarn"/>
<appender-ref ref="RollingFileError"/>
</root>
</Loggers>
</configuration>