log4j2.xml配置文件元素解析

配置文件展示

《 monitorInterval="30"作用:30秒进行一次扫描该配置文件,重新加载一次,不需要重启项目》
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="erro" monitorInterval="30">
	<Properties>
		<!-- 配置日志文件输出目录此处定义了变量,后面就可以使用${LOG_HOME}进行引用了 -->
		<Property name="LOG_HOME"> /ccx</Property>
	</Properties>

	<Appenders>
		<!-- 输出值控制台 -->
		<Console name="Console" target="SYSTEM_OUT">
			<!-- 格式化日志 -->
			<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
				charset="UTF-8" />
		</Console>

		<!-- 输出到文件中 采用这个可以将日志写到多个文件中,可以自定义日志分包、日志文件数量控制等。因此建议使用这个 -->
		<RollingRandomAccessFile name="File"
			fileName="E:/logs/app.log" filePattern="E:/logs/$${date:HH}/%d{HH}.app.%i.log"
			immediateFlush="true">
			<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
				charset="UTF-8" />
			<Policies>
				<!--5s 翻滚一次 其实就是每过5s就新建一个日志文件,如果filepattern的"E:/logs/$${date:HH}/%d{HH}.app   如果不清楚可以参照下面关于policies解释
					这部分相同,则进行增加i 1 2 3 4 5增加 -->
				<CronTriggeringPolicy schedule="0/5 * * * * ?" />
				<!-- 指单个文件最大的大小,超过这个容量就进行重新建立日志文件。 必须配合上面i使用单位 KBMBGB -->
				<SizeBasedTriggeringPolicy size="10 MB" />
			</Policies>
			<!-- 控制文件数量,根据日志名称的i值,最大到10,之后就进行覆盖,默认情况下是7 -->
			<DefaultRolloverStrategy max="10" />

			<Filters>
				<!-- 注意:配置起来比较乱,建议使用的时候单个使用,并将最后的onMismatch="DENY"这样就可以 了,做到拦截。同时LevelRangeFilter的日志输出范围为LevelRangeFilter范围与logger设置的level的交集。 -->
<!-- 只允许在每天的 8~8点半 之间输出日志 -->
				<TimeFilter start="08:00:00" end="17:29:30" onMatch="ACCEPT"
					onMismatch="NEUTRAL" />
				<!-- 从大到小:error, warn, info, debug, trace -->
				<LevelRangeFilter minLevel="error" maxLevel="info"
					onMatch="ACCEPT" onMismatch="DENY" />

			</Filters>
		</RollingRandomAccessFile>

	</Appenders>

	<Loggers>

		<Logger name="AsyncFileLogger" level="trace" additivity="false">
			<AppenderRef ref="Console" />
		</Logger>
		<!-- 以下定义两个logger,name如果是包名,那么就 com.haiyang是com.haiyang.controller的父logger,同时root是所有logger的父logger 
			此时通过在代码中Logger logger = (Logger) LogManager.getLogger(getClass().getName());如果该方法类在com.haiyang这个包内, 
			就会调用该包的方法。Logger logger = (Logger) LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);调用的是root的logger 
			Logger logger = (Logger) LogManager.getLogger("AsyncFileLogger");可以调用上面的那个日志定义 
			additivity属性作用:是否集成父类(父类也进行执行),默认是true<Logger name="com.haiyang.controller" 
			level="trace"> <AppenderRef ref="Console" /> </Logger> 
			<Logger name="com.haiyang" 
			level="trace"> <AppenderRef ref="Console" /> </Logger> -->
		<Root level="erro">
			<AppenderRef ref="File" />
		</Root>

	</Loggers>


</Configuration>
 

log4j2配置文件整体结构

  • Appdenders部分
    • Appender
      • Filter
      • Layout
      • Policies
      • Strategy
  • Loggers部分
    • Logger
    • Root

对于Appender的理解

作用:简单说Appender就是一个管道,定义了日志内容的去向(保存位置)。

配置一个或者多个Filter ,Filter的过滤机制和Servlet的Filter有些差别,下文会进行说明。(注意只是在文件输出的时候才配置 ,因为输入值控制台配置该属性没意义。)

配置Layout 来控制日志信息的输出格式。

配置Policies 以控制日志何时(When)进行滚动。通俗的解释就是控制日志如何区分。如多长时间进行新建一个文件夹存放日志,同一文件夹下多长时间生成一个log日志文件,统一名称日志文件最多存放几个,超出之后按照最新的覆盖最先的。(注意只是在文件输出的时候才配置 ,因为输入值控制台配置该属性没意义。)

配置Strategy 以控制日志如何(How)进行滚动。(这个没有做过多的了解)

对于Logger的理解

简单说Logger就是一个路由器,指定类、包中的日志信息流向哪个管道,以及控制他们的流量(日志级别) .通俗的解释就是,定义哪个名称、包下日志应当采用哪种Appender进行输出。
Appender标签的实现类
其实这些标签都是类名或者类名去掉后缀。

Appender的常用的实现类有:

其实Appender相当于是一个接口,在实际使用过程中,都是使用它的实现类,常用的是以下三个实现类。分别对应控制台输出 单文件输出 多文件输出。注意:括号内的名称为在log4j2.xml文件中的标签名。

  1. ConsoleAppender(Console)
  2. FileAppender(File)、RandomAccessFileAppender(RandomAccessFile)
  3. RollingFileAppender(RollingFile)、RollingRandomAccessFileAppender(RollingRandomAccessFile)

标签详解及可包含字标签元素

Console

该实现类会把日志输出到控制台中。
它有两种输出方式:

  1. SYSTEM_OUT(System.out) // 默认的配置
  2. SYSTEM_ERR(System.err)
    两种输出方式区别,其实就相当于调用system.out与调用system.err的区别,后置在控制台输出的为红色字体。
    如果不配置,默认使用SYSTEM_OUT进行输出。括号中是调用的方法。
    代码如下:
<Appenders>
     <!-- 在log4j2.xml文件中配置  采用Console标签即可。-->
        <Console name="Console" target="SYSTEM_OUT">
            <!-- 格式化日志 -->
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>
        </Console>
 </Appenders> 

File、 RandomAccessFile

相同点:写入日志信息到文件(单个文件中)
不同点:使用的I/O实现类不同,前者使用FileOutputStream,后者使用RandomAccessFile。
官方文档说是在bufferedIO=true(默认是true)的情况下后者比前者性能提升20% ~ 200%,不明觉厉,就用后者吧。
通俗点解释就是:改组是输出在单个日志文件中。平时采用后者居多.

代码示例:
<Appenders>
        <RandomAccessFile name="File" fileName="logs/app.log" immediateFlush="false">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>
        </RandomAccessFile>
    </Appenders> 
属性解释:

filename:来指定文件位置,文件或目录不存在则会自动创建。通常情况下指定准确的位置,如果不指定盘符,默认位置是开发软件所在home目录。具体的不确定,因此建议改为准确的盘符位置,如文章开头所示例那样。
immediateFlush:是否每次写入都要立刻刷新到硬盘中。默认true,如果使用默认值可能会影响性能。

RollingFile 、 RollingRandomAccessFile

可以进行多个日志文件输出。(重点掌握)
这一对之间的区别与上一对之间的区别是一样的。平时也是采用RollingRandomAccessFile
上一对的实现类不能进行日志滚动,所谓日志滚动就是当达到设定的条件后,日志文件进行切分。
比如:工程师想让系统中的日志按日进行切分,并且按月归档。
这时候这一对的作用就体现出来了。

示例代码:
<Appenders>
        <RollingRandomAccessFile name="File" fileName="logs/app.log"
                                 filePattern="logs/$${date:hh-mm}/%d{hh-mm-ss}.app.%i.log" >
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>

            <Policies>
                <!-- 每 5s 翻滚一次 -->
                <CronTriggeringPolicy schedule="0/5 * * * * ?" />
                <SizeBasedTriggeringPolicy size="10 MB"/>
            </Policies>
            
            <DefaultRolloverStrategy max="10" />            
        </RollingRandomAccessFile>

    </Appenders>
 

-注意 filePattern这个属性,参照上面示例代码,是定义日志名称的作用,后面的%i的作用,是配合如下policies与DefaultRolloverStrategy使用的。如下配置的fileOattern名称为logs目录下,以分钟为文件夹区分,时分秒为文件名,如果这样设计,那么下面policies属性设5s属性及DefaultRolloverStrategy属性将失去作用,因为文件名不会重复。但是如果使用logs/$${date:hh}/%d{hh}.app.%i.log这样命名,就好很多,因为以小时为文件名,这样文件重名的概率就比较大,从而就使用上i的属性编号。日志文件展示如下图:
在这里插入图片描述

只有上图因为17.app同名,因此此时DefaultRolloverStrategy才能起上作用。一直到创建日志10次之后 会把旧的日志内容覆盖。

Filters

Filters决定日志事件能否被输出。过滤条件有三个值:ACCEPT(接受),DENY(拒绝),NEUTRAL(中立)。

常用的Filter实现类有:

  1. LevelRangeFilter 控制输出日志级别范围
  2. TimeFilter 控制日志按照何种日期进行输出
  3. ThresholdFilter 平时使用比较少
    使用代码如下:
 <Appenders>

        <Console name="Console">

            <!--
                设置 onMismatch="NEUTRAL" 可以让日志经过后续的过滤器
                最后一个过滤器建议设置 onMismatch="DENY", 不然日志就输出了。
            -->
            <Filters>
                <!-- 从大到小:error, warn, info, debug, trace -->
                <LevelRangeFilter minLevel="error" maxLevel="info" onMatch="ACCEPT" onMismatch="NEUTRAL" />
                <!-- 只允许在每天的 8点~8点半 之间输出日志 -->
                <TimeFilter start="08:00:00" end="08:30:00" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>

            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>
        </Console>

    </Appenders>
 

注意:配置起来比较乱,建议使用的时候单个使用,并将最后的onMismatch="DENY"这样就可以 了,做到拦截。同时LevelRangeFilter的日志输出范围为LevelRangeFilter范围与logger设置的level的交集。

Policy & Strategy

上文也说了,Policy是用来控制日志文件何时(When)进行滚动的;Strategy是用来控制日志文件如何(How)进行滚动的。
如果配置的是RollingFile或RollingRandomAccessFile,则必须配置一个Policy。
如果想按月归档,按日切分日志,然后

Policy常用的实现类:

  1. SizeBasedTriggeringPolicy
  2. CronTriggeringPolicy
  3. TimeBasedTriggeringPolicy
SizeBasedTriggeringPolicy

根据日志文件的大小进行滚动。

单位有:KB,MB,GB

CronTriggeringPolicy

使用Cron表达式进行日志滚动,很灵活。

TimeBasedTriggeringPolicy

这个滚动策略依赖于filePattern中配置的最具体的时间单位,根据最具体的时间单位进行滚动。

这种方式比较简洁。CronTriggeringPolicy策略更强大。

简单示例:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration name="baseConf" status="warn" monitorInterval="30">

    <Appenders>

        <RollingRandomAccessFile name="File" fileName="logs/app.log"
                                 filePattern="logs/$${date:hh-mm}/%d{hh-mm-ss}.app.%i.log" >
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>

            <Policies>
                <!-- 每 5s 翻滚一次 -->
                <!--<CronTriggeringPolicy schedule="0/5 * * * * ?" />-->
                
                <!-- 
                    filePattern中最具体的时间单位是 秒。
                    这里用 TimeBasedTriggeringPolicy 替换 CronTriggeringPolicy
                    
                    注意:modulate属性是指从启动时间开始算5秒,还是从0秒开始算5秒,运行一下就明白了。
                    modulate: true(默认值) // 会从启动时间开始算 5秒
                    modulate: false // 从 0秒开始算
                -->
                <TimeBasedTriggeringPolicy interval="5" modulate="true"/>
                
                <SizeBasedTriggeringPolicy size="10 MB"/>
            </Policies>
            
            <DefaultRolloverStrategy max="10" />
            
        </RollingRandomAccessFile>

    </Appenders>

    <Loggers>

        <Root level="info">
            <AppenderRef ref="File"/>
        </Root>

    </Loggers>

</Configuration>

Strategy常用的实现类

  1. DefaultRolloverStrategy
  2. DirectWriteRolloverStrategy
    这两个Strategy都是控制如何进行日志滚动的,至于他们的区别我还是不太明白,大佬解释一下吧。平时大部分用DefaultRolloverStrategy就可以了。

Logger

Logger部分就比较简单了,分为两个Logger:

  1. Root(必须配置)
  2. Logger

简单示例:


<?xml version="1.0" encoding="UTF-8"?>
<Configuration name="baseConf" status="warn" monitorInterval="30">

    <Appenders>

        <Console name="Console">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
        </Console>

    </Appenders>

    <Loggers>

        <Root level="trace">
            <AppenderRef ref="Console"/>
            <Filters>
                <LevelRangeFilter minLevel="error" maxLevel="info" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>
        </Root>

    </Loggers>

</Configuration>

注意:Logger中也可以加过滤器的哟~

较重要的问题: 日志重复打印

这时候我们需要使用一个Logger的属性来解决,那就是additivity,其默认值为true,需要配置为false。参照上面的示例代码。

<Logger name="AsyncFileLogger" level="trace" additivity="false">
			<AppenderRef ref="Console" />
		</Logger>

总结:

其实使用logger日志,只需关系日志怎么使用,日志输出位置即可。关于该文章目的就是为了了解log4j2.xml文件的配置方式。以下有几种经验。
1.在使用过程中会查看别人配置文件 遇到如下图不知道$${jndi:logging/context-name}是什么意思,此时解决方法就是,在log日志中,将这个变量输出,看一下到底是什么,就知道是什么值了。同样,有时候会在filename等属性中也会遇到类似这种不知道的值,解决方案也如此。
在这里插入图片描述
2.在配置文件中自己定义属性。并在配置文件中进行引用。
在这里插入图片描述
3.关于注意 大写HH为24小时制,hh为12小时制,这与java日期格式一致。
在这里插入图片描述
4.关于控制jar包及框架日志情况,只需要开启包名即可 如下代码spring框架日志。

<Loggers>
        
        <!-- 
            限制Spring框架日志的输出级别,其它框架类似配置
            或者使用 AppenderRef 标签,将其输出到指定文件中,记得加上 additivity="false"
        -->
        <logger name="org.springframework" level="warn"/>
        <Root level="info">
            <AppenderRef ref="File1"/>
        </Root>

    </Loggers>
 

5.关于lookups的知识,个人觉得不要进行太纠结,钻死牛角。及日志输出格式问题,能显示出来即可,不需要死记硬背,会用即可。
lookups参考资料:
https://blog.csdn.net/ghsau/article/details/52334762

猜你喜欢

转载自blog.csdn.net/qq_32281025/article/details/83419628
今日推荐