日志框架之Log4j2的使用
点击“蓝字”
常用的日志框架
a. 日志接口
- JCL(Jakarta Commons Logging)
- jboss-logging
- SLF4j(Simple Logging Facade for Java)
b. 日志实现
- JUL(java.util.logging)
- Log4j
- Logback
- Log4j2
为什么需要日志接口,直接使用具体的实现不就行了吗?
接口用于定制规范,可以有多个实现,使用时是面向接口的(导入的包都是slf4j的包而不是具体某个日志框架中的包),即直接和接口交互,不直接使用实现,所以可以任意的更换实现而不用更改代码中的日志相关代码。
比如:slf4j定义了一套日志接口,项目中使用的日志框架是logback,开发中调用的所有接口都是slf4j的,不直接使用logback,调用是 自己的工程调用slf4j的接口,slf4j的接口去调用logback的实现,可以看到整个过程应用程序并没有直接使用logback,当项目需要更换更加优秀的日志框架时(如log4j2)只需要引入Log4j2的jar和Log4j2对应的配置文件即可,完全不用更改Java代码中的日志相关的代码logger.info(“xxx”),也不用修改日志相关的类的导入的包(import org.slf4j.Logger; import org.slf4j.LoggerFactory;)
使用日志接口便于更换为其他日志框架
log4j、logback、log4j2都是一种日志具体实现框架,所以既可以单独使用也可以结合slf4j一起搭配使用。性能比较
由图可知,Log4j2的性能更好,Log4j2优越的性能在于使用了Lmax,一个无锁的线程间通讯库代替了logback、log4j之前的队列,并发性提高很多,并且log4j2丢失数据情况少,使用disruptor技术,在多线程环境下利用jdk1.5并发特性减少了死锁的发生。
使用Log4j2
pom.xml
在SSM项目下使用
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.30</version></dependency><dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.13.0</version></dependency><dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.13.0</version></dependency><dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.13.0</version></dependency>
在SpringBoot项目下使用(因为springBoot默认日志框架为LogBack,所以首先需要将其屏蔽)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!-- 去掉springboot默认配置 --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions></dependency><dependency> <!-- 引入log4j2依赖 --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId></dependency>
同时引入spring-boot-starter和spring-boot-starter-web依赖时,需要在spring-boot-starter中排除spring-boot-starter-logging依赖,因为spring-boot-starter-web依赖于spring-boot-starter,根据Maven依赖关系,在spring-boot-starter中排除spring-boot-starter-logging依赖才能排除成功。
配置文件(其中一个默认名为
log4j2.xml
,不想用这名就查log4j2配置文件的优先级)<?xml version="1.0" encoding="UTF-8"?><Configuration> <Properties> <!-- 日志存放的目录 --> <Property name="LOG_HOME" value="E:/logs/IDEA/"/> <!-- 日志存档的目录 --> <Property name="LOG_ARCHIVE" value="E:/logs/IDEA/archive"/> <!-- 模块名称 --> <Property name="LOG_MODULE_NAME" value="ssm-template-zero"/> <!-- interval属性用来指定多久滚动一次,单位根据filePattern变化 --> <Property name="LOG_TIME" value="1"/> <!-- 日志文件大小,超过这个大小将滚动一次 --> <Property name="LOG_MAX_SIZE" value="150 MB"/> <!-- 同一个文件名时(只有最后一位-%i不同),生成多少个文件后开始覆盖 --> <Property name="LOG_MAX_COVER" value="7"/> <!-- 输出日志的格式 --> <Property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/> <!-- 输出日志的格式(带颜色) --> <Property name="LOG_PATTERN_CONSOLE" value="%red{%d{yyyy-MM-dd HH:mm:ss}} %blue{[%t]} %highlight{%-5level} %green{%logger{36}} - %cyan{%msg%n}"/> </Properties> <Appenders> <!-- 控制台输出 --> <Console name="console" target="SYSTEM_OUT"> <!--输出日志的格式--> <PatternLayout pattern="${LOG_PATTERN_CONSOLE}"/> </Console> <!-- 根据上面的配置,这个会打印出所有的info\warn级别的日志, 每次大小超过 150MB 或者 每1天会滚动一次, 日志会按年月建立的文件夹,建立文件进行压缩存档 --> <!--异步日志会自动批量刷新,所以将immediateFlush属性设置为false--> <RollingRandomAccessFile name="InfoLog" fileName="${LOG_HOME}/${LOG_MODULE_NAME}-info.log" filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}/%d{yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz"> <!-- off > fatal > error > warn > info > debug > trace > all --> <!-- ACCEPT(接受),DENY(拒绝),NEUTRAL(中立) --> <Filters> <!-- 如果是error级别以上的拒绝,以下的保持中立 --> <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/> <!-- 在上一个拦截器基础上,如果是info级别以上的接受,以下的拒绝 --> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> </Filters> <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <!-- 滚动一次就是打包一次 --> <!-- interval属性:用来指定多久滚动一次, 根据当前filePattern的命名规则的时间最小单位设置 当filePattern的%d{yyyy-MM-dd HH-mm-ss} interval=1,就是1秒生成一个文件(压缩包), 当filePattern的%d{yyyy-MM-dd} interval=1,就是1天生成一个文件(压缩包), --> <!-- modulate属性:指是否应调整时间间隔以使下一次滚动发生在时间间隔边界(就是0点或者0分)上。如果项目是小时,modulate: false,当前时间是3点,间隔是4,则第一次滚动将在4点发生, 然后下一个滚动将在8点,12点,16点等发生。--> <TimeBasedTriggeringPolicy interval="${LOG_TIME}" modulate="false"/> <!-- 日志超过这个值,就会滚动一次。单位有:KB,MB,GB --> <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/> </Policies> <!-- 这里max,可以说是代表filePattern中 %i 的最大值了,默认值为7--> <DefaultRolloverStrategy max="${LOG_MAX_COVER}"/> </RollingRandomAccessFile> <!-- 只记录error级别以上的日志, 每次大小超过 150MB 或者每1天会滚动一次, 日志会按年月建立的文件夹,建立文件进行压缩存档 --> <RollingRandomAccessFile name="ErrorLog" fileName="${LOG_HOME}/${LOG_MODULE_NAME}-error.log" filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}/%d{yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz"> <Filters> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> </Filters> <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <TimeBasedTriggeringPolicy interval="${LOG_TIME}" modulate="false"/> <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/> </Policies> <DefaultRolloverStrategy max="${LOG_MAX_COVER}"/> </RollingRandomAccessFile> </Appenders> <Loggers> <!-- level="TRACE",可以查看sql语句的参数;additivity:默认值为true,配置为false可以避免日志重复打印。--> <logger name="org.apache.ibatis" level="TRACE" additivity="false"> <AppenderRef ref="console"/> </logger> <!-- 开发环境使用 --> <Root level="debug"> <AppenderRef ref="console"/> <AppenderRef ref="InfoLog"/> <AppenderRef ref="ErrorLog"/> </Root> <!-- 正式环境使用 --> <!-- <Root level="info"> <AppenderRef ref="InfoLog"/> <AppenderRef ref="ErrorLog"/> </Root> --> </Loggers></Configuration>
yaml版(官网给的模板,还没改)
Configuration: status: warn name: YAMLConfigTest properties: property: name: filename value: target/test-yaml.log thresholdFilter: level: debug appenders: Console: name: STDOUT PatternLayout: Pattern: "%m%n" File: name: File fileName: ${filename} PatternLayout: Pattern: "%d %p %C{1.} [%t] %m%n" Filters: ThresholdFilter: level: error Loggers: logger: - name: org.apache.logging.log4j.test1 level: debug additivity: false ThreadContextMapFilter: KeyValuePair: key: test value: 123 AppenderRef: ref: STDOUT - name: org.apache.logging.log4j.test2 level: debug additivity: false AppenderRef: ref: File Root: level: error AppenderRef: ref: STDOUT
测试
UserController.java
package xyz.jianzha.template.controller;import lombok.extern.log4j.Log4j2; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author Y_Kevin * @date 2020-02-14 01:30 */@RestController@Log4j2public class UserController { // 使用了lombok的@Log4j2注解来替代了 // private Logger log = LogManager.getLogger(); @GetMapping("/info") public String info() { for (int i = 0; i < 100; i++) { log.info("info message:{}={}", "line", i); } return "info日志接口调用"; } @GetMapping("/error") public String error() { for (int i = 0; i < 100; i++) { log.error("error message:{}={}", "line", i); } return "error日志接口调用"; } @GetMapping("/debug") public String debug() { for (int i = 0; i < 100; i++) { log.debug("debug message:{}={}", "line", i); } return "debug日志接口调用"; } }
配置文件参数介绍
一. 日志级别:
级别 | 说明 |
---|---|
all | 用来输出所有信息 |
trace | 用来输出追踪信息 |
debug | 用来输出调试信息 |
info | 用来输出重要信息 |
warn | 用来输出警告信息 |
error | 用来输出错误信息 |
fatal | 用来输出致命错误信息 |
off | 关闭输出 |
二. 文件结构
Configuration
1.Properties
部分
- Propertie
2.Appdenders
部分
Ⅰ.Appender
- Filter
- Layout
- Policies
- Strategy
3.Loggers
部分
- Logger
- RootLogger
三. 配置文件详解
Configuration
根节点
属性:
status:指定Log4j2自身打印级别,此属性的有效值为“ trace”,“ debug”,“ info”,“ warn”,“ error”和“ fatal”;
monitorinterval:指定Log4j2自动重新配置的监测时间,可以不重启应用的情况下修改配置。
更多属性:http://logging.apache.org/log4j/2.x/manual/configuration.html#ConfigurationSyntax
Properties
属性。使用来定义常量,以便在其他配置项中引用。
Appenders
输出源,通常仅负责将事件数据写入目标目的地。
每个Appender必须实现Appender 接口,可配多个Appender
log4j2常用的有:(括号里为标签名)
- ConsoleAppender(Console)
- AsyncAppender(Async)
- FileAppender(File)
- RandomAccessFileAppender(RandomAccessFile)
- RollingFileAppender(RollingFile)
- RollingRandomAccessFileAppender (RollingRandomAccessFile)
更多Appender:http://logging.apache.org/log4j/2.x/manual/appenders.html
ConsoleAppender
将日志打印到控制台上,开发的时候一般都会配置,以便调试。
- name:指定Appender的名字
- target:“ SYSTEM_OUT”或“ SYSTEM_ERR”。默认值为“ SYSTEM_OUT”
- PatternLayout:输出日志的格式,不设置默认为:%m%n
更多属性:http://logging.apache.org/log4j/2.x/manual/appenders.html#ConsoleAppender
AsyncAppender
异步输出。AsyncAppender接受对其他Appender的引用,并使LogEvents在单独的线程上写入它们。
默认情况下,AsyncAppender使用 java.util.concurrent.ArrayBlockingQueue ,它不需要任何外部库。请注意,在使用这种附加程序时,多线程应用程序应格外小心:阻塞队列很容易发生锁争用,并且我们的 测试表明, 当同时记录更多线程时,性能可能会变差。考虑使用无锁异步记录器以获得最佳性能。
- name:指定Appender的名字
- AppenderRef:要异步调用的Appender的名称。可配多个AppenderRef
- filter:过滤器,可使用多个过滤器。
更多属性:http://logging.apache.org/log4j/2.x/manual/appenders.html#AsyncAppender
FileAppender
文件输出,将日志写入到指定的文件。使用
FileOutputStream
实现I/O- name:指定Appender的名字
- fileName:要写入的文件名。如果该文件或其任何父目录不存在,则将创建它们
- PatternLayout:输出日志的格式,不设置默认为:%m%n
- immediateFlush:是否每次写入都要立刻刷新到硬盘中。默认true,如果使用默认值可能会影响性能。
更多属性:http://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender
RandomAccessFileAppender
与
FileAppender
相似,但它使用RandomAccessFile
实现I/O与
FileAppender
不同,在测试中,它在“ bufferedIO = true(默认是true)”时的性能提高了20-200% ,推荐使用它。- 属性和上面的差不多
更多属性:http://logging.apache.org/log4j/2.x/manual/appenders.html#RandomAccessFileAppender
RollingFileAppender
与
FileAppender
相似,但它使用FileOutputStream
实现I/O。与
FileAppender
不同:它能进行日志滚动(日志滚动就是当达到设定的条件后,日志可以按日进行切分,并且按月归档)- name:指定Appender的名字。
- fileName:指定当前日志文件的位置和文件名称
- filePattern:指定当发生Rolling时,文件的转移和重命名规则
- immediateFlush:设置为true时 - 默认值,每次写入后都会进行刷新。这将保证数据写入磁盘,但可能会影响性能。
- Policies:指定滚动日志的策略,就是什么时候进行新建日志文件输出日志。(详细看属性里的参数介绍↓)
- Strategy:指定了最大翻滚次数。(详细看属性里的参数介绍↓)
更多属性:http://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender
RollingRandomAccessFileAppender
与
RollingFileAppender
相似,但它使用RandomAccessFile
实现I/O,它也能进行日志滚动。与
RollingFileAppender
不同,在测试中,它在“ bufferedIO = true(默认是true)”时的性能提高了20-200% ,推荐使用它。- 属性和上面的差不多
更多属性:http://logging.apache.org/log4j/2.x/manual/appenders.html#RollingRandomAccessFileAppender
Appenders部分属性里的参数介绍
PatternLayout 日志格式
简单示例:
<!-- 这个是带颜色的,用于在控制台输出 --><!-- 若没效果,请在VM options添加:-Dlog4j.skipJansi=false --><PatternLayout pattern="%red{%d{yyyy-MM-dd HH:mm:ss}} %blue{[%t]} %highlight{%-5level} %green{%logger{36}} - %cyan{%msg%n}"/><!-- 不带颜色,用于写进文件输出 --><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
更多格式:http://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout
Strategy 滚动策略
指定了如何(How)进行翻滚,并且指定了最大翻滚次数(影响
%i
参数值),超过次数之后会按照相应的规则删除旧日志。DirectWriteRolloverStrategy
日志事件直接写入由文件模式表示的文件。使用此策略文件不会执行重命名。
大多数使用默认过渡策略
DefaultRolloverStrategy
DefaultRolloverStrategy
默认过渡策略
max:计数器的最大值。一旦达到此值,较旧的归档文件将在以后的转换中被删除。预设值为7。
compressionLevel:将压缩级别设置为0-9,其中0 =无,1 =最佳速度,直到9 =最佳压缩。仅针对ZIP文件实现。
如何工作的呢,官方是这样介绍:
假设将min属性设置为1,将max属性设置为3,文件名是“ foo.log”,文件名模式是“ foo-%i.log”。
不懂可以看看下面的:
先把下面的
Policies 滚动触发策略
的SizeBasedTriggeringPolicy
大致了解一下<!-- 测试使用max为2,自己根据情况调 --><!-- 这里max,可以说是代表filePattern中 %i 的最大值了,默认值为7 --><DefaultRolloverStrategy max="2"/>
</Policies> <!-- 文件超过2M时触发滚动 --> <SizeBasedTriggeringPolicy size="2 MB"/></Policies>
整合为
<?xml version="1.0" encoding="UTF-8"?><Configuration> <Appenders> <!-- 控制台输出 --> <Console name="console" target="SYSTEM_OUT"> <!--输出日志的格式--> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/> </Console> <!-- 这个会打印出所有的info\warn级别的日志,每次大小超过size或者满足TimeBasedTriggeringPolicy, 则日志会自动存入按年月日建立的文件夹下面并进行压缩,作为存档--> <!--异步日志会自动批量刷新,所以将immediateFlush属性设置为false--> <RollingRandomAccessFile name="InfoLog" fileName="E:/logs/IDEA/template-infoLog.log" filePattern="E:/logs/IDEA/archive/template/%d{yyyy-MM}/infoLog-%d{yyyy-MM-dd HH-mm}-%i.log.gz"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/> <Policies> <!-- 文件超过2M时触发滚动 --> <SizeBasedTriggeringPolicy size="2 MB"/> </Policies> <!-- 测试使用max为2,自己根据情况调 --> <!-- 这里max,可以说是代表filePattern中 %i 的最大值了 --> <DefaultRolloverStrategy min="1" max="2"/> </RollingRandomAccessFile> </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="console"/> <AppenderRef ref="InfoLog"/> </Root> </Loggers></Configuration>
接口:(为了体现超过2M的效果,把循环次数写为10000)
package xyz.jianzha.template.controller;import lombok.extern.log4j.Log4j2;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;/** * @author Y_Kevin * @date 2020-02-14 01:30 */@RestController@Log4j2public class UserController { @GetMapping("/info") public String info() { for (int i = 0; i < 10000; i++) { log.info("info message:{}={}", "line", i); } return "info日志接口调用"; } }
执行后,我们会发现:
在
E:\logs\IDEA\archive\template\2020-02\
下,可能有几个压缩包,但有max个压缩包最后一个数不同。
前面max设为2
infoLog-2020-02-14 16-40-1.log.gz infoLog-2020-02-14 16-41-1.log.gz infoLog-2020-02-14 16-41-2.log.gz
当我们把它们解压查看时:发现1.log的大概内容是:
2020-02-14 16:41:46 [http-nio-8080-exec-1] INFO xyz.jianzha.template.controller.UserController - info message:line=8501
不是包含 line=1 的了
这就说明后面的内容覆盖前面的了,是在
DefaultRolloverStrategy
设置的max参数导致。这里它根据文件名进行判断覆盖的,只有前面部分相同,后面才能覆盖
可能这里使用分钟进行命名压缩包,导致难以理解,不明白可以去掉
filePattern
的时间值,或者其它名我感觉这里也不太对
更多说明:http://logging.apache.org/log4j/2.x/manual/appenders.html#RolloverStrategies
Policies 滚动触发策略
这里就是规定了何时进行滚动,滚动一次就是打包一次,可以有多个
Policy
SizeBasedTriggeringPolicy:
基于日志文件大小的触发策略。日志超过这个值,就会滚动一次,单位有:KB,MB,GB
<SizeBasedTriggeringPolicy size="2 MB"/>
测试可以使用上面的接口,调用多几次,或者修改循环次数,
CronTriggeringPolicy:
基于
cron
表达式触发翻转。此策略由计时器控制,并且与处理日志事件异步1分 2点 3号 4月 星期5(更多搜`cron`表达式)
<CronTriggeringPolicy schedule="1 2 3 4 5 ?" />
TimeBasedTriggeringPolicy:
interval:
间隔多久滚动一次
这个需要和
filePattern
结合使用,日期格式精确到哪一位,interval也精确到哪一个单位。注意
filePattern
中配置的文件重命名规则是${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i,最小的时间粒度是ss,即秒钟。TimeBasedTriggeringPolicy默认的interval是1,结合起来就是每1分钟生成一个文件(压缩包)。如果改成%d{yyyy-MM-dd HH},最小粒度为小时,则每1小时滚动一次,生成一个文件(压缩包)。modulate:
指从启动时间开始算,还是从0秒开始算
modulate: true(默认值) // 会从启动时间开始算
modulate: false // 从 0秒开始算
指示是否应调整时间间隔以使下一次滚动发生在时间间隔边界(就是0点或者0分)上。
例如,如果项目是小时,modulate: false,当前时间是3点,间隔是4,则第一次滚动将在4点发生,然后下一个滚动将在8点,12点,16点等发生。
<Policies> <TimeBasedTriggeringPolicy interval="4" modulate="false "/></Policies>
更多说明:http://logging.apache.org/log4j/2.x/manual/appenders.html#TriggeringPolicies
Filters
拦截器。决定日志事件能否被输出
常用的两种:
TimeFilter
- start:HH:mm:ss格式的时间。
- end:HH:mm:ss格式的时间。如果指定的结束时间小于开始时间,则不会写入任何日志条目。
- timezone:与事件时间戳进行比较时使用的时区。
- onMatch:过滤器匹配时采取的措施。可以是
ACCEPT(接受)
,DENY(拒绝)
,NEUTRAL(中立)
。默认值为NEUTRAL
。 - onMismatch:过滤器不匹配时采取的措施。可以是
ACCEPT(接受)
,DENY(拒绝)
,NEUTRAL(中立)
默认值为DENY
。
一个示例配置,该配置仅允许追加程序每天使用默认时区在每天5:00至5:30写入事件:
<TimeFilter start="05:00:00" end="05:30:00" onMatch="ACCEPT" onMismatch="DENY"/>
ThresholdFilter
- level:要匹配的有效级别名称。
- onMatch:过滤器匹配时采取的措施。可以是
ACCEPT(接受)
,DENY(拒绝)
,NEUTRAL(中立)
。默认值为NEUTRAL
。 - onMismatch:过滤器不匹配时采取的措施。可以是
ACCEPT(接受)
,DENY(拒绝)
,NEUTRAL(中立)
默认值为DENY
。
大致使用:只打印info\warn级别的日志
<!-- off > fatal > error > warn > info > debug > trace > all --><!-- ACCEPT(接受),DENY(拒绝),NEUTRAL(中立) --><Filters> <!-- 如果是error级别以上的拒绝,以下的保持中立 --> <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/> <!-- 在上一个拦截器基础上,如果是info级别以上的接受,以下的拒绝 --> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/></Filters>
更多拦截器:http://logging.apache.org/log4j/2.x/manual/filters.html
Loggers部分属性里的参数介绍
Root
必须有一个,也有默认值,我找不到
level:日志输出级别,共有8个级别,按照从高到低为:off > fatal > error > warn > info > debug > trace > all。
AppenderRef:Root的子节点,用来指定该日志输出到哪个Appender。
- Filter:同上面的过滤器一样。
Logger
Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。
- name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点。一般是项目包名或者框架的包名,比如:org.apache.ibatis。
- level:日志输出级别,共有8个级别,按照从高到低为:off > fatal > error > warn > info > debug > trace > all。
- AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root。如果指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时我们可以设置Logger的additivity=”false”只在自定义的Appender中进行输出。
- additivity:日志是否重复打印。其默认值为
true
。 - Filter:同上面的过滤器一样。
重复打印问题:
如果Logger
配置的输出Appender和Root
的Appender相同,他们两个都会输出,此时我们可以设置Logger的additivity=”false”只在自定义的Appender中进行输出。
更多配置方式:http://logging.apache.org/log4j/2.x/manual/configuration.html#XML
更多用法:http://logging.apache.org/log4j/2.x/manual/usage.html
KevinCodeNotes
觉得好看,就送我小花花