添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

一、什么是RollingFile

RollingFileAppender是Log4j2中的一种能够实现日志文件滚动更新(rollover)的Appender。

rollover的意思是当满足一定条件(如文件达到了指定的大小,达到了指定的时间)后,就重命名原日志文件进行归档,并生成新的日志文件用于log写入。如果还设置了一定时间内允许归档的日志文件的最大数量,将对过旧的日志文件进行删除操作。

RollingFile实现日志文件滚动更新,依赖于TriggeringPolicy和RolloverStrategy。

其中,TriggeringPolicy为触发策略,其决定了何时触发日志文件的rollover,即When。

RolloverStrategy为滚动更新策略,其决定了当触发了日志文件的rollover时,如何进行文件的rollover,即How。

Log4j2提供了默认的rollover策略DefaultRolloverStrategy。

下面通过一个log4j2.xml文件配置简单了解RollingFile的配置。

< 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参数可以用KB、MB、GB等做后缀来指定具体的字节数,如20MB。

TimeBasedTriggeringPolicy

TimeBasedTriggeringPolicy规定了当日志文件名中的date/time pattern不再符合filePattern中的date/time pattern时,触发rollover操作。

比如,filePattern指定文件重命名规则为app-%d{yyyy-MM-dd HH}.log,文件名为app-2017-08-25 11.log,当时间达到2017年8月25日中午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 >

上述配置文件中,filePattern中yyyy-MM-dd HH最小时间粒度为小时,TimeBasedTriggeringPolicy中interval使用默认值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中表示使用复合策略

如上,同时使用了TimeBasedTriggeringPolicy、SizeBasedTriggeringPolicy,有一个条件满足,就会触发rollover。

三、DefaultRolloverStrategy

DefaultRolloverStrategy指定了当触发rollover时的默认策略。

DefaultRolloverStrategy是Log4j2提供的默认的rollover策略,即使在log4j2.xml中没有显式指明,也相当于为RollingFile配置下添加了如下语句。DefaultRolloverStrategy默认的max为7。

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"

假设fileName为logs/app.log,SizeBasedTriggeringPolicy的size为10KB,DefaultRolloverStrategy的max为3。

根据filePattern配置的不同分为以下几种情况:

情况1:filePattern中仅含有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。

<? 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 >
<? 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",同时指定了TimeBasedTriggeringPolicy和SizeBasedTriggeringPolicy的触发策略,每1分钟或者文件大小达到10KB,将触发rollover。

每次触发rollover时,将按照如下方式对文件进行rollover。

app-2017-08-17 20-52-3.log

当前时间变为app-2017-08-17 20-53,触发第5次rollover,app-2017-08-17 20-52-1.log被删除。app-2017-08-17 20-52-2.log被重命名为app-2017-08-17 20-52-1.log,app-2017-08-17 20-52-3.log被重命名为app-2017-08-17 20-52-2.log,app.log被重命名为app-2017-08-17 20-52-3.log。新的app.log被创建出来,用于写入log。 app.log

app-2017-08-17 20-52-1.log

app-2017-08-17 20-52-2.log

app-2017-08-17 20-52-3.log

app-2017-08-17 20-53-1.log

当app.log的size达到10KB,触发第6次rollover,app.log被重命名为app-2017-08-17 20-53-1.log。新的app.log被创建出来,用于写入log。

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

2.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指定了文件修改时间需要满足的条件。

DeleteAction常用参数如下:

删除文件的过滤条件,满足指定条件的文件将会被删除,可以指定一个或多个。

如果指定多个pathCondition,需要同时满足。Conditions可以嵌套,当嵌套配置时,只有当满足了外部的contion时,才能对内部的condition进行判断。如果Conditions不是嵌套的,会可能以任意顺序进行判断。

Conditions也可以通过使用IfAll,IfAny,IfNot等类似于AND,OR,NOT的condition,实现复杂的condition。

  • IfFileName-判断文件的文件名是否满足正则表达式或glob表达式
  • IfLastModified-判断文件的修改时间是否早于指定的duration
  • IfAccumulatedFileCount-判断在遍历文件树的时候,文件个数是否超过了指定值
  • IfAccumulatedFileSize-判断在遍历文件树的时候,文件的总大小是否超过了指定值
  • IfAll-判断嵌套的condition是否都满足
  • IfAny-判断嵌套的condition是否有一个满足
  • IfNot-判断嵌套的condition是否不满足
  • 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) {}
    <? 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 >
    <? 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 >
    <? 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 >