当前位置:首页>编程知识库>后端开发知识>你了解Log4j2中RollingFile的文件滚动更新机制吗?
你了解Log4j2中RollingFile的文件滚动更新机制吗?
阅读 1
2021-06-10

一、什么是RollingFile

RollingFileAppenderLog4j2中的一种能够实现日志文件滚动更新(rollover)的Appender
rollover的意思是当满足一定条件(如文件达到了指定的大小,达到了指定的时间)后,就重命名原日志文件进行归档,并生成新的日志文件用于log写入。如果还设置了一定时间内允许归档的日志文件的最大数量,将对过旧的日志文件进行删除操作。
RollingFile实现日志文件滚动更新,依赖于TriggeringPolicyRolloverStrategy
其中,TriggeringPolicy为触发策略,其决定了何时触发日志文件的rollover,即When
RolloverStrategy为滚动更新策略,其决定了当触发了日志文件的rollover时,如何进行文件的rollover,即How
Log4j2提供了默认的rollover策略DefaultRolloverStrategy
下面通过一个log4j2.xml文件配置简单了解RollingFile的配置。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/app-%d{yyyy-MM-dd HH}.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy interval="1"/>
        <SizeBasedTriggeringPolicy size="250MB"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>
上述配置文件中配置了一个RollingFile,日志写入logs/app.log文件中,每经过1小时或者当文件大小到达250M时,按照app-2017-08-01 12.log的格式对app.log进行重命名并归档,并生成新的文件用于写入log
其中,fileName指定日志文件的位置和文件名称(如果文件或文件所在的目录不存在,会创建文件。)
filePattern指定触发rollover时,文件的重命名规则。filePattern中可以指定类似于SimpleDateFormat中的date/time pattern,如yyyy-MM-dd HH,或者%i指定一个整数计数器。

TimeBasedTriggeringPolicy指定了基于时间的触发策略。

SizeBasedTriggeringPolicy指定了基于文件大小的触发策略。

二、TriggeringPolicy

RollingFile的触发rollover的策略有

CronTriggeringPolicy(Cron表达式触发)

OnStartupTriggeringPolicy(JVM启动时触发)

SizeBasedTriggeringPolicy(基于文件大小)

TimeBasedTriggeringPolicy(基于时间)

CompositeTriggeringPolicy(多个触发策略的混合,如同时基于文件大小和时间)
其中,SizeBasedTriggeringPolicy(基于日志文件大小)、TimeBasedTriggeringPolicy(基于时间)或同时基于文件大小和时间的混合触发策略最常用。
SizeBasedTriggeringPolicy
SizeBasedTriggeringPolicy规定了当日志文件达到了指定的size时,触发rollover操作。size参数可以用KBMBGB等做后缀来指定具体的字节数,如20MB
<SizeBasedTriggeringPolicy size="250MB"/>
TimeBasedTriggeringPolicy
TimeBasedTriggeringPolicy规定了当日志文件名中的date/time pattern不再符合filePattern中的date/time pattern时,触发rollover操作。
比如,filePattern指定文件重命名规则为app-%d{yyyy-MM-dd HH}.log,文件名为app-2017-08-25 11.log,当时间达到2017825日中午12点(2017-08-25 12),将触发rollover操作。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/app-%d{yyyy-MM-dd HH}-%i.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>
上述配置文件中,filePatternyyyy-MM-dd HH最小时间粒度为小时,TimeBasedTriggeringPolicyinterval使用默认值1,将每1小时触发一次rollover
若将filePattern改为filePattern=“logs/app-%d{yyyy-MM-dd HH-mm}-%i.log”,yyyy-MM-dd HH-mm最小时间粒度为分钟,将每1分钟触发一次rollover
CompositeTriggeringPolicy
将多个TriggeringPolicy放到Policies中表示使用复合策略
<Policies>
    <TimeBasedTriggeringPolicy />
    <SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
如上,同时使用了TimeBasedTriggeringPolicySizeBasedTriggeringPolicy,有一个条件满足,就会触发rollover

三、DefaultRolloverStrategy

DefaultRolloverStrategy指定了当触发rollover时的默认策略。
DefaultRolloverStrategyLog4j2提供的默认的rollover策略,即使在log4j2.xml中没有显式指明,也相当于为RollingFile配置下添加了如下语句。DefaultRolloverStrategy默认的max7
<DefaultRolloverStrategy max="7"/>
max参数指定了计数器的最大值。一旦计数器达到了最大值,过旧的文件将被删除。
注意:不要认为max参数是需要保留的日志文件的最大数目。
max参数是与filePattern中的计数器%i配合起作用的,其具体作用方式与filePattern的配置密切相关。
1.如果filePattern中仅含有date/time pattern,每次rollover时,将用当前的日期和时间替换文件中的日期格式对文件进行重命名。max参数将不起作用。
如,filePattern="logs/app-%d{yyyy-MM-dd}.log"
2.如果filePattern中仅含有整数计数器(即%i),每次rollover时,文件重命名时的计数器将每次加1(初始值为1),若达到max的值,将删除旧的文件。
如,filePattern="logs/app-%i.log"
3.如果filePattern中既含有date/time pattern,又含有%i,每次rollover时,计数器将每次加1,若达到max的值,将删除旧的文件,直到data/time pattern不再符合,被替换为当前的日期和时间,计数器再从1开始。
如,filePattern="logs/app-%d{yyyy-MM-dd HH-mm}-%i.log"
假设fileNamelogs/app.logSizeBasedTriggeringPolicysize10KBDefaultRolloverStrategymax3
根据filePattern配置的不同分为以下几种情况:
情况1filePattern中仅含有date/time pattern
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" name="MyApp" packages="">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
        <RollingFile name="RollingFile" fileName="logs/app.log"
        filePattern="logs/app-%d{yyyy-MM-dd}.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <SizeBasedTriggeringPolicy size="10KB"/>
            </Policies>
            <DefaultRolloverStrategy max="3"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>
filePattern="logs/app-%d{yyyy-MM-dd}.log",指定当发生rollover时,将按照app-%d{yyyy-MM-dd}.log的格式对文件进行重命名。
每次触发rollover时,将按照如下方式对文件进行rollover
情况2filePattern中仅含有整数计数器(%i
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" name="MyApp" packages="">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
        <RollingFile name="RollingFile" fileName="logs/app.log"
        filePattern="logs/app-%i.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <SizeBasedTriggeringPolicy size="10KB"/>
            </Policies>
            <DefaultRolloverStrategy max="3"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>
filePattern="logs/app-%i.log",其余配置同上。
每次触发rollover时,将按照如下方式对文件进行rollover
情况3:如果filePattern中既含有date/time pattern,又含有%i计数器
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" name="MyApp" packages="">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
        <RollingFile name="RollingFile" fileName="logs/app.log"
        filePattern="logs/app-%d{yyyy-MM-dd HH-mm}-%i.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="10KB"/>
            </Policies>
            <DefaultRolloverStrategy max="3"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>
filePattern="logs/app-%d{yyyy-MM-dd HH-mm}-%i.log",同时指定了TimeBasedTriggeringPolicySizeBasedTriggeringPolicy的触发策略,每1分钟或者文件大小达到10KB,将触发rollover。往期面试题汇总:250期面试资料
每次触发rollover时,将按照如下方式对文件进行rollover
总结:

max参数是与filePattern中的计数器%i配合起作用的,若
filePatternfilePattern="logs/app-%d{yyyy-MM-dd}.log"&gt;,由于没有设置%i计数器,max参数将不起作用。

max参数不是需要保留的文件的最大个数。如情况3,日志文件date/time pattern不再符合filePattern时,计算器将被重置为1,日志总个数超过了max的指定值。
可认为max参数规定了一定时间范围内归档文件的最大个数。

四、DeleteAction

DefaultRolloverStrategy制定了默认的rollover策略,通过max参数可控制一定时间范围内归档的日志文件的最大个数。
Log4j 2.5 引入了DeleteAction,使用户可以自己控制删除哪些文件,而不仅仅是通过DefaultRolloverStrategy的默认策略。
注意:通过DeleteAction可以删除任何文件,而不仅仅像DefaultRolloverStrategy那样,删除最旧的文件,所以使用的时候需要谨慎!
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Properties>
    <Property name="baseDir">logs</Property>
  </Properties>
  <Appenders>
    <RollingFile name="RollingFile" fileName="${baseDir}/app.log"
          filePattern="${baseDir}/app-%d{yyyy-MM-dd}.log.gz">
      <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
      <CronTriggeringPolicy schedule="0 0 0 * * ?"/>
      <DefaultRolloverStrategy>
        <Delete basePath="${baseDir}" maxDepth="2">
          <IfFileName glob="*/app-*.log.gz" />
          <IfLastModified age="60d" />
        </Delete>
      </DefaultRolloverStrategy>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>
上述配置文件中,Delete部分便是配置DeleteAction的删除策略,指定了当触发rollover时,删除baseDir文件夹或其子文件下面的文件名符合app-*.log.gz且距离最后的修改日期超过60天的文件。
其中,basePath指定了扫描开始路径,为baseDir文件夹。maxDepth指定了目录扫描深度,为2表示扫描baseDir文件夹及其子文件夹。
IfFileName指定了文件名需满足的条件,IfLastModified指定了文件修改时间需要满足的条件。往期面试题汇总:250期面试资料
DeleteAction常用参数如下:

五、程序测试demo

public class HelloWorld {
 
    public static void main(String[] args) {
        Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
        try{
            //通过打印i,日志文件中数字越小代表越老
            for(int i = 0; i < 50000; i  ) {
                logger.info("{}", i);
                logger.info("logger.info\n");
                Thread.sleep(100);//为了防止50000条很快跑完,sleep一段时间
            }
        } catch (InterruptedException e) {}
    }
}

1.测试基于时间触发

filePattern最小时间粒度为秒,将每5秒触发一次rollover
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" name="MyApp" packages="">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
        <!--<RollingFile name="RollingFile" fileName="logs/app.log"-->
                     <!--filePattern="logs/app-%d{yyyy-MM-dd HH}-%i.log">-->
        <RollingFile name="RollingFile" fileName="logs/app.log"
                     filePattern="logs/app-%d{yyyy-MM-dd HH-mm-ss}.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <!--当经过了interval时间后,将根据filePattern对文件进行重命名,并生成新的文件用于日志写入-->
                <TimeBasedTriggeringPolicy interval="5"/>
                <!--当日志文件大小大于size时,将根据filepattern对文件进行重命名,并生成新的文件用于日志写入-->
                <!--<SizeBasedTriggeringPolicy size="30KB"/>-->
            </Policies>
            <DefaultRolloverStrategy max="3"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>

2.测试基于文件大小的触发

日志文件达到5KB,将触发rollover
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" name="MyApp" packages="">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
        <!--<RollingFile name="RollingFile" fileName="logs/app.log"-->
                     <!--filePattern="logs/app-%d{yyyy-MM-dd HH}-%i.log">-->
        <RollingFile name="RollingFile" fileName="logs/app.log"
                     filePattern="logs/app-%d{yyyy-MM-dd HH-mm-ss}.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <!--当经过了interval时间后,将根据filePattern对文件进行重命名,并生成新的文件用于日志写入-->
                <!--<TimeBasedTriggeringPolicy interval="5"/>-->
                <!--当日志文件大小大于size时,将根据filepattern对文件进行重命名,并生成新的文件用于日志写入-->
                <SizeBasedTriggeringPolicy size="5KB"/>
            </Policies>
            <DefaultRolloverStrategy max="3"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>

3.测试DefaultRolloverStrategy的max参数和%i计数器的搭配使用

注意filePattern最小时间粒度为分钟,且含%i计数器
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" name="MyApp" packages="">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
        <RollingFile name="RollingFile" fileName="logs/app.log"
                     filePattern="logs/app-%d{yyyy-MM-dd HH-mm}-%i.log">
        <!--<RollingFile name="RollingFile" fileName="logs/app.log"-->
                     <!--filePattern="logs/app-%d{yyyy-MM-dd HH-mm-ss}.log">-->
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <!--当经过了interval时间后,将根据filePattern对文件进行重命名,并生成新的文件用于日志写入-->
                <!--<TimeBasedTriggeringPolicy interval="5"/>-->
                <!--当日志文件大小大于size时,将根据filepattern对文件进行重命名,并生成新的文件用于日志写入-->
                <SizeBasedTriggeringPolicy size="5KB"/>
            </Policies>
            <DefaultRolloverStrategy max="3"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>



感谢阅读,希望对你有所帮助 :)
来源:cnblogs.com/yeyang/p/7944899.html


 
  END
 


 十期推荐
 
  【271期】面试官:Spring MVC的处理流程是怎样的?
  

 
 
  【272期】数据结构:哈希表原理以及面试中的常见考点
  

 
 
  【273期】告诉面试官,我能优化groupBy,而且知道得很深!
  

 
 
  【274期】面试官:怎么保证缓存和数据库一致性
  

 
 
  【275期】面试官:你对MySQL中的索引了解多少?
  

 
 
  【276期】面试官:你分析过@Annotation注解的实现原理吗?
  

 
 
  【277期】面试官:说几种常用的分布式 ID 解决方案
  

 
 
  【278期】面试官:都说 select * 效率低下,你知道什么原因吗?
  

 
 
  【279期】面试官:Java遍历Map集合有哪几种方式?各自效率怎么样?
  

 
 
  【280期】k8s面试问什么?
  

 
 
  

 
? ~
以上数据来源于网络,如有侵权,请联系删除。
评论 (0)