Log4j2配置文件&描述

Log4j2 配置文件及描述

前面介绍Java Log的总体情况,以及两个日志框架和具体日志实现框架间的桥接。本章主要介绍日常工作中用的比较多的Log4j2的配置信息以及解释。

1. 配置文件解析

1. 同步模式

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
<?xml version="1.0" encoding="UTF-8"?>
<!--
全局配置
status : 这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,会看到log4j2内部各种详细输出
monitorInterval : Log4j能够自动检测修改配置文件和重新配置本身, 设置间隔秒数。
-->
<Configuration status="WARN" monitorInterval="1000">
<Properties>
<!-- 配置日志目录 -->
<Property name="LOG_HOME">./logs</Property>
</Properties>
<!--日志输出地址-->
<Appenders>
<!--输出控制台-->
<Console name="Console" target="SYSTEM_OUT">
<!-- 日志格式 -->
<PatternLayout pattern="[%level][%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread][%class][%method][%line]:%message%n"/>
</Console>

<RollingRandomAccessFile name="infoLog" fileName="${LOG_HOME}/info.log"
filePattern="${LOG_HOME}/info.%d{yyyy-MM-dd}.log.gz" append="true"><!--压缩文件名-->
<PatternLayout pattern="[%level][%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread][%class][%method][%line]:%message%n"/>
<!--
%c{precision} | %logger{precision} : name of the logger
%class{precision} | %C{precision}: class name of the caller
%date{pattern} | %d{pattern} :the date of the logging event
%L | %line:line number
%level : the level of the logging event
%m{nolookups}{ansi} | %msg{nolookups}{ansi} | %message{nolookups}{ansi}:application supplied message
%method | %M: method name where the logging request
%t | %tn | %thread | %threadName :name of the thread
%n :
-->
<Filters>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<Policies>
<!--
TimeBased Triggering Policy: The policy to use to determine if a rollover should occur.
interval单位与filePattern相关 yyyy-MM-dd 一天一个文件, yyyy-MM-dd-HH 每小时一个文件
基于时间的触发策略。该策略主要是完成周期性的log文件封存工作。有两个参数:
interval,integer型,指定两次封存动作之间的时间间隔。单位:以日志的命名精度来确定单位
modulate,boolean型,说明是否对封存时间进行调制。若modulate=true,则封存时间将以0点为边界进行偏移计算。
-->
<SizeBasedTriggeringPolicy size="100 MB" />
</Policies>
</RollingRandomAccessFile>
<RollingRandomAccessFile name="errorLog" fileName="${LOG_HOME}/error.log"
filePattern="${LOG_HOME}/error.%d{yyyy-MM-dd}.log.gz" append="true">
<Filters>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="[%level][%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread][%class][%method][%line]:%message%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingRandomAccessFile>
</Appenders>

<!--日志配置-->
<Loggers>
<logger name="experiment" level="info" additivity="false">
<appender-ref ref="infoLog"/>
<appender-ref ref="errorLog"/>
<appender-ref ref="Console"/>
</logger>
<logger name="experiment.test" level="warn" additivity="false">
<appender-ref ref="infoLog"/>
<appender-ref ref="errorLog"/>
<appender-ref ref="Console"/>
</logger>
<logger name="algorithm" level="info" additivity="false">
<appender-ref ref="infoLog"/>
<AppenderRef ref="Console"/>
</logger>

<!-- 配置日志的根节点 -->
<Root level="warn" includeLocation="true">
<AppenderRef ref="errorLog"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>

</Configuration>

2. 全异步模式

  1. 只需要将系统属性Log4jContextSelector设置为AsyncLoggerContextSelector
  2. 在配置属性文件log4j2.component.properties中配置Log4jContextSelectorAsyncLoggerContextSelector

3.混合模式

todo 修改
不需要改系统属性或者引入属性配置文件,只需要将相应的Loger换成AsyncLoger

1
2
3
4
5
<logers>
<AsyncLogger name="experiment.test" level="trace" includeLocation="true">
<AppenderRef ref="warnLog"/>
</AsyncLogger>
</logers>

##2. 同步、异步以及混合模式的比较
虽然异步日志有很大的优势,但是它并不是适合于所有应用场景。如下将通过分析异步日志的优劣来比较同步日志和异步日志:

  1. 优势

    • 更高的峰值吞吐量,相同场景下,异步日志的能打印的日志量是同步的6-58倍
    • 更快的响应时间,调用后立即返回,而不用等到appender执行完成。
  2. 缺点

    • 错误处理方便,如果在打印日志的过程中抛了异常,对于异步日志来说很难记录。即使通过ExceptionHander可以减轻这种情况,但是并不能解决所有的情况。因此,当日志是业务逻辑的一部分(比如讲Log4j作为审计日志框架)时,则推荐使用同步日志;
    • 在某些极端的情况下,打印的日志对象,可能会有变化。如:MapMessageStructuredDataMessage,用户有可能会看到非触发打印时的对象快照
    • 如果应用CPU资源吃紧的话,不适合于异步。因为它的速度是以牺牲CPU为代价的。
    • 当应用打日志的速率比底层追加器的最大速率都要快,最后队列会被打满,最终也会以最慢追加器的速率打日志

主要工作流程:

  1. LogManager.getLogger(xx.class) 会根据class文件的具体类名来获取最匹配的LogConfig
  2. 会遍历所有Appender,打印日志;
  3. 当LoggerConfig配置了additivity=”true” 会将日志事件传递给父节点LoggerConfig

LogerConfig会根据name来建立一个关系树,root是根节点。如下图:
additivity(是否可叠加) 用于控制:子LogConfig里的日志事件是否往父LogConfig中传递。

3. LogConfig继承关系图

set up-w400

参考:

  1. Layouts
  2. Appenders
  3. Log4j2使用总结
  4. Log4j架构解析
  5. 并发框架Disruptor
您的支持是我创作源源不断的动力