一,Log4j2介绍
log4j2是log4j1.x的升级版,2015年5月,Apache宣布log4j1.x停止更新。最新版为1.2.17.
log4j2参考了logback的一些优秀的设计,并且修了一些问题,因此带来了一些重大的提升,主要有:
- 异常处理:在logback中,Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异常处理机制。
- 性能提升:log4j2相较于log4j1和logback都具有很明显的性能提升。
- 白动重载配置:参考了logback的设计,提供自动刷新参数配置,可以动态的修改日志的级别而不需要重启应用。
- 无垃圾机制:log4j2在大部分情况下,都可以使用其设计的一套无垃圾机制,避免频繁的日志收集导致的jvm gc。
log4j2.x版本不再支持像1.x中的**.properties后缀的文件配置方式,2.x版本常用.xml后缀的文件进行配置**,除此之外还包含**.json和.jsn**配 置文件
log4j2虽然采用xml风格进行配置,依然包含三个组件,分别是
-
Logger(记录器)
-
Appender(输出目的地)
-
Layout(日志布局)。
配置文件的位置::log4j2默认会在classpath目录下寻找log4j2.xml、log4j.json、log4j.jsn等名称的文件。
二,XML配置详解
-
根节点Configuration
有两个属性:
- status:指定log4j本身的打印日志的级别
- montiorinterval:log4j2新特点,自动重载配置,指定自动重新配置的监测时间间隔,单位是s,最小是5s
有两个子节点:(都可定义多个)
- Appenders
- Loggers
-
Appenders节点:常见有三种子节点:
- Console:输出到控制台
- File:输出到文件
- RollingFile:定义超过指定大小自动删除旧的创建新的文件
在子节点中加入:
<PatternLayout pattern="自定义信息格式"/>
进行日志的布局
-
Loggers节点:常见的有
- Root:用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出
- Logger:用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。
三,Log4j2快速入门
-
导包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
在导包时注意如果导入了jdbc那么就需要排除其中logging依赖要不然会出现警告
-
添加yaml配置
logging: config: classpath:logback.xml
-
创建配置文件
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <!--配置一些公共属性引用--> <properties> </properties> <!--配置所有的Appenders--> <Appenders> </Appenders> <!--配置Loggers--> </Configuration>
-
运行:
package com.ruoyi.springbootdemo; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @SpringBootTest class SpringBootDemoApplicationTests { public static final Logger LOGGER = LogManager.getLogger(SpringBootDemoApplicationTests.class); @Test void test() { // 日志消息输出 LOGGER.fatal("fatal"); LOGGER.error("error"); LOGGER.warn("warn"); LOGGER.info("inf"); LOGGER.debug("debug"); LOGGER.trace("trace"); } }
-
也可以通过搭配lombok使用
@Slf4j @SpringBootTest class SpringBootDemoApplicationTests { @Test void test() { // 日志消息输出 log.fatal("fatal"); log.error("error"); log.warn("warn"); log.info("inf"); log.debug("debug"); log.trace("trace"); } }
四,xml详解
4.1 Configuration标签
根节点Configuration
中有两个常用的属性:status和monitorterval。如:<Configuration status="WARN" monitorInterval="30">
属性:
status
:是用于指定log4j的级别;monitorterval
:是用于指定log4j自动重新检测读取配置内容的间隔时间,单位为秒(s),最小值为5秒。
4.2 Properties标签
<properties>
<property name="LOG_HOME">./service-logs</property>
</properties>
变量配置,如上述代码,配置了一个变量名为:LOG_HOME,变量值为:./service-logs的变量。
调用方法:**{LOG_HOME}`
4.3 Appenders标签
Appenders用来设置所有的appender子节点有:
-
Console:输出到控制台
-
File:输出到指定文件
-
RollingFile:基于指定策略实现日志文件滚动
4.3.1 Console
Console节点用于定义输出控制台的Appender。
属性:
name
:用于指定Appender的名称;target
:用于指定输出目标,一般是SYSTEM_OUT
或SYSTEM_ERR
,默认是SYSTEM_OUT
;
子节点:
-
PatternLayout
:用于指定输出格式,不设置的话,默认为:%m%n
-
属性:
disableAnsi
:这个参数控制是否禁用 ANSI 颜色代码。noConsoleNoAnsi
:这个参数控制是否在没有控制台的情况下禁用 ANSI 颜色代码。一般都设置为false用来配合控制台输出自定义颜色的内容
-
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout disableAnsi="false" noConsoleNoAnsi="false">
<Pattern>
%style{%d{yyyy-MM-dd hh:mm:ss}}{bright,green} %highlight{%-5level} [%style{%t}{bright,blue}] %style{%C{}}{bright,yellow}:%L -%msg%n%style{%throwable}{red}
</Pattern>
</PatternLayout>
</Console>
</Appenders>
针对pattern解析:注意的是这个只针对控制台有效,对输出到文件的内容是无效的
%style{%d{yyyy-MM-dd hh:mm:ss}}{bright,green}
- %d{yyyy-MM-dd hh:mm:ss}: 输出日志记录的时间戳,格式为 年-月-日 时:分:秒。
- %style{...}{bright,green}: 将时间戳部分设置为亮绿色(bright, green)
%highlight{%-5level}
- %-5level: 输出日志级别(例如:INFO, DEBUG),占5个字符宽度,左对齐。
- %highlight{...}: 根据日志级别自动设置颜色。不同的日志级别(如 ERROR、WARN、INFO)会有不同的颜色,默认配置为 ERROR 红色, WARN 黄色, INFO 绿色。
4.3.2 File
File节点用于将日志输出到指定文件,一般不用该节点,而使用RollingFile
节点
属性:
name
:用于指定Appender的名称;fileName
:用于指定日志文件的全路径;
子节点:
PatternLayout
:用于指定输出格式,不设置的话,默认为:%m%n
<File name="MyFile" fileName="logs/app.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</File>
4.3.3 RollingFile
RollingFile节点用于实现日志文件更动更新的Appender,当满足条件(日志大小、指定时间等)重命名或打包原日志文件进行归档,生成新日志文件用于日志写入。
属性:
name
:用于指定Appender的名称;fileName
:用于指定日志文件的全路径filePattern
:用于指定分割文件的日志全路径(命名规则)
子节点:
PatternLayout
:用于指定输出格式,不设置的话,默认为:%m%n
;Policies
:设置日志文件切割参数;SizeBasedTriggeringPolicy
:Policies的子节点,用于设置基于日志文件大小触发的滚动策略,size
属性用来指定每个分割的日志文件大小。TimeBasedTriggeringPolicy
:Policies的子节点,用于设置基于时间间隔触发的滚动策略interval
属性用于指定滚动时间间隔,默认是1小时,modulate
属性是用于对interval进行偏移调节,默认为false。若为true,则第一次触发时是第一个小时触发,后续以interval间隔触发。CronTriggeringPolicy
:Policies的子节点,用于设置基于Cron表达式触发的滚动策略。
DefaultRolloverStrategy
:设置默认策略设置。
滚动策略分为三种:
-
基于大小的滚动策略
<RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> <DefaultRolloverStrategy max="10"/> </RollingFile>
上述模板中,日志先写入
logs/app.log
中,每当文件大小达到100MB时,按照在logs/2020-09/
目录下以app-2020-09-09-1.log.gz
格式对该日志进行压缩重命名并归档,并生成新的文件app.log
进行日志写入。其中,
filePattern
属性的文件格式中%i
就类似于一个整数计数器,受到<DefaultRolloverStrategy max="10"/>
控制,要特别注意的是:当文件个数达到10个的时候会循环覆盖
前面已归档的1-10个文件。若不设置该参数,默认为7
-
基于时间的滚动策略
<RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}.log.gz"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy interval="6" modulate="true"/> </Policies> </RollingFile>
上述模板中,日志先写入
logs/app.log
中,每当文件的时间间隔到达6小时(由%d{yyyy-MM-dd-HH}
决定,也可以设置成%d{yyyy-MM-dd-HH-mm}
,则间隔为分钟级别),触发滚动操作。如上配置设置好后,10点的日志开始重启服务,则从11点触发一次rollover操作,生成
2020-09-09-10.log.gz
对该日志进行压缩重命名并归档,并生成新的文件app.log
进行日志写入;然后,每间隔6小时,则下一次是17点触发一次,生成2020-09-09-17.log.gz
对该日志进行压缩重命名并归档,并生成新的文件app.log
进行日志写入。 -
基于时间和大小的滚动策略
<RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy interval="6" modulate="true"/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> </RollingFile>
上述模板中,日志先写入
logs/app.log
中,每当文件大小达到100MB或者当时间间隔到达6小时(由%d{yyyy-MM-dd-HH}
决定),触发rollover操作,按照在logs/2020-09/
目录下以app-2020-09-09-1.log.gz
格式对该日志进行压缩重命名并归档,并生成新的文件app.log
进行日志写入。
4.4 过滤器
Filters过滤是用到上述三个标签中的子标签,用来过滤掉不需要的日志级别
log4j2存在两种过滤器:
-
ThresholdFilter
-
level: 指定日志的最低输出级别。
-
onMatch: 指定当日志级别等于或高于
level
时的行为,通常是ACCEPT
或DENY
。 -
onMismatch: 指定当日志级别低于
level
时的行为,通常是NEUTRAL
或DENY
。
<Filters> <!-- 只保留低于 WARN 级别的日志 --> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="NEUTRAL"/> </Filters>
-
-
LevelRangeFilter
- minLevel: 指定日志的最低输出级别。
- maxLevel: 指定日志的最高输出级别。
- onMatch: 指定当日志级别在指定范围内时的行为,通常是
ACCEPT
。 - onMismatch: 指定当日志级别不在指定范围内时的行为,通常是
DENY
。
<Filters> <!-- 保留 TRACE 到 INFO 级别的日志 --> <LevelRangeFilter minLevel="trace" maxLevel="info" onMatch="ACCEPT" onMismatch="DENY"/> </Filters>
ACCEPT是接受,DENY是拒绝,NEUTRAL是不做过滤让后面的过滤器做决定
4.5 指定输出类型
在上述我们输出到文件中的内容都是使用的PatternLayout但还存在其他的,常用的有:
-
JSONLayout:格式化为json
- compact: 如果设置为
true
,则输出的 JSON 将不包含空格和缩进,输出会更紧凑。 - eventEol: 如果设置为
true
,每个事件将以换行符结束,便于日志分析工具逐行处理。
<JSONLayout compact="true" eventEol="true"/>
- compact: 如果设置为
-
XMLLayout:格式化为XML
- complete: 如果设置为
true
,日志文件会包含 XML 声明和根元素的结束标签 - compact: 如果设置为
true
,输出的 XML 将不包含空格和缩进,输出会更紧凑。
<XMLLayout complete="false" compact="true"/>
- complete: 如果设置为
-
HTMLLayout:格式化为HTML
- title: HTML 页面的标题。
- locationInfo: 如果设置为
true
,则输出的日志消息将包含类和行号信息 - charset: 指定字符集编码。
<HTMLLayout title="Log4j Log Messages" locationInfo="true" charset="UTF-8"/>
-
CSVLayout:格式化为CSV
- format: 指定 CSV 格式的预定义模式,例如
Default
或Excel
.
<CSVLayout format="Default"/>
- format: 指定 CSV 格式的预定义模式,例如
4.4 Loggers标签
子节点:
Root
:用于指定项目的根日志,level
属性表示日志输出级别,子节点AppenderRef
用于指定输出到某个Appender,子节点的ref
属性也就是前面的RollingFile中指定的name名称,子节点的level
也是日志输出级别。Logger
:用于指定日志的形式,指定不同包的日志级别,level
属性表示日志输出级别,name
属性用来指定该Logger所适用的类或者类的全路径。子节点AppenderRef
用于指定日志输出到哪个Appender,若没有指定,默认集成自Root。
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
<Logger level="info" name="com.ruoyi.admin.log">
<AppenderRef ref="concoleFile"/>
</Logger>
</Loggers>
五,模板xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<!--<Configuration status="WARN" monitorInterval="30"> -->
<properties>
<property name="LOG_HOME">../logs</property>
</properties>
<Appenders>
<!--*********************控制台日志***********************-->
<Console name="consoleAppender" target="SYSTEM_OUT">
<!--设置日志格式及颜色-->
<PatternLayout
pattern="%style{%d{yyyy-MM-dd HH:mm:ss}}{bright,green} %highlight{%-5level} [%style{%t}{bright,blue}] %style{%C{}}{bright,yellow}: %msg%n%style{%throwable}{red}"
disableAnsi="false" noConsoleNoAnsi="false"/>
</Console>
<!--*********************文件日志***********************-->
<!--all级别日志-->
<RollingFile name="allFileAppender"
fileName="${LOG_HOME}/all.log"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/all-%d{yyyy-MM-dd}-%i.log.gz">
<!--设置日志格式-->
<PatternLayout>
<pattern>%d %p %C{} [%t] %m%n</pattern>
</PatternLayout>
<Policies>
<!-- 设置日志文件切分参数 -->
<!--<OnStartupTriggeringPolicy/>-->
<!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新-->
<SizeBasedTriggeringPolicy size="100 MB"/>
<!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置-->
<TimeBasedTriggeringPolicy/>
</Policies>
<!--设置日志的文件个数上限,不设置默认为7个,超过大小后会被覆盖;依赖于filePattern中的%i-->
<DefaultRolloverStrategy max="100"/>
</RollingFile>
<!--debug级别日志-->
<RollingFile name="debugFileAppender"
fileName="${LOG_HOME}/debug.log"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/debug-%d{yyyy-MM-dd}-%i.log.gz">
<Filters>
<!--只保留debug级别的日志-->
<LevelRangeFilter minLevel="debug" maxLevel="debug" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<!--设置日志格式-->
<PatternLayout>
<pattern>%d %p %C{} [%t] %m%n</pattern>
</PatternLayout>
<Policies>
<!-- 设置日志文件切分参数 -->
<!--<OnStartupTriggeringPolicy/>-->
<!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新-->
<SizeBasedTriggeringPolicy size="100 MB"/>
<!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置-->
<TimeBasedTriggeringPolicy/>
</Policies>
<!--设置日志的文件个数上限,不设置默认为7个,超过大小后会被覆盖;依赖于filePattern中的%i-->
<DefaultRolloverStrategy max="100"/>
</RollingFile>
<!--info级别日志-->
<RollingFile name="infoFileAppender"
fileName="${LOG_HOME}/info.log"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz">
<Filters>
<!--只保留info级别的日志-->
<LevelRangeFilter minLevel="info" maxLevel="info" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<!--设置日志格式-->
<PatternLayout>
<pattern>%d %p %C{} [%t] %m%n</pattern>
</PatternLayout>
<Policies>
<!-- 设置日志文件切分参数 -->
<!--<OnStartupTriggeringPolicy/>-->
<!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新-->
<SizeBasedTriggeringPolicy size="100 MB"/>
<!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置-->
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
<!--设置日志的文件个数上限,不设置默认为7个,超过大小后会被覆盖;依赖于filePattern中的%i-->
<!--<DefaultRolloverStrategy max="100"/>-->
</RollingFile>
<!--warn级别日志-->
<RollingFile name="warnFileAppender"
fileName="${LOG_HOME}/warn.log"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz">
<Filters>
<!--只保留warn级别的日志-->
<LevelRangeFilter minLevel="warn" maxLevel="warn" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<!--设置日志格式-->
<PatternLayout>
<pattern>%d %p %C{} [%t] %m%n</pattern>
</PatternLayout>
<Policies>
<!-- 设置日志文件切分参数 -->
<!--<OnStartupTriggeringPolicy/>-->
<!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新-->
<SizeBasedTriggeringPolicy size="100 MB"/>
<!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置-->
<TimeBasedTriggeringPolicy/>
</Policies>
<!--设置日志的文件个数上限,不设置默认为7个,超过大小后会被覆盖;依赖于filePattern中的%i-->
<DefaultRolloverStrategy max="100"/>
</RollingFile>
<!--error级别日志-->
<RollingFile name="errorFileAppender"
fileName="${LOG_HOME}/error.log"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz">
<!--设置日志格式-->
<PatternLayout>
<pattern>%d %p %C{} [%t] %m%n</pattern>
</PatternLayout>
<Policies>
<!-- 设置日志文件切分参数 -->
<!--<OnStartupTriggeringPolicy/>-->
<!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新-->
<SizeBasedTriggeringPolicy size="100 MB"/>
<!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置-->
<TimeBasedTriggeringPolicy/>
</Policies>
<!--设置日志的文件个数上限,不设置默认为7个,超过大小后会被覆盖;依赖于filePattern中的%i-->
<DefaultRolloverStrategy max="100"/>
</RollingFile>
</Appenders>
<Loggers>
<!-- 根日志设置 -->
<Root level="debug">
<AppenderRef ref="consoleAppender" level="info"/>
<AppenderRef ref="allFileAppender" level="all"/>
<AppenderRef ref="debugFileAppender" level="debug"/>
<AppenderRef ref="infoFileAppender" level="info"/>
<AppenderRef ref="warnFileAppender" level="warn"/>
<AppenderRef ref="errorFileAppender" level="error"/>
</Root>
</Loggers>
</Configuration>