Default log4j policy

Viewed 376

I'm trying to understand how TimeBasedTriggeringPolicy determines when a log file is created/appended/deleted.

For the below configuration :

<RollingRandomAccessFile name="test" fileName="/logs/test.log" filePattern="/logs/test.log.%d{yyyy-MM-dd}"
<Policies>
 <TimeBasedTriggeringPolicy />
</Policies>
</RollingRandomAccessFile>

Is this correct:

The %d parameter indicates a new log files test.log appended with the current {yyyy-MM-dd} is created every day ? Previous versions of test.log are not deleted ? If I changed %d to %M should a new file be created every month ?

In order to ensure just the current day log file is avaialable and other log files are deleted the should the policy be amended to :

<RollingRandomAccessFile name="test" fileName="/logs/test.log" filePattern="/logs/test.log.%d{yyyy-MM-dd}"
<Policies>
 <TimeBasedTriggeringPolicy interval="1"/>
</Policies>
</RollingRandomAccessFile>

?

2 Answers

I'm trying to understand how TimeBasedTriggeringPolicy determines when a log file is created/appended/deleted.

TimeBasedTriggeringPolicy controls when the next rollover occurs. The next rollover time is determined based on the date unit provided. {yyyy-MM-dd} means it is next day. With no other trigger policy, all the logs are appended to the current day file.

DefaultRolloverStrategy controls when the logs files are archived/deleted/created based on the file pattern. When the next day arrives, new file with current date will be created and all the logs are appended to new file. Depending on the rollover strategy configuration the previous day file can be retained or removed. max and min attributes controls the number of files with %i specifier in the file pattern to maintain the file counter and fileIndex to control the file renaming.

Original

The %d parameter indicates a new log files test.log appended with the current {yyyy-MM-dd} is created every day ? Previous versions of test.log are not deleted ? If I changed %d to %M should a new file be created every month ?

%d is conversion specifier - Log4j 2 has converters for different conversion specifiers. %d refers to date and allows you to send date format. Datetime unit itself controls when the rollover should happen. %m is not recognized in log4j2 instead you would use %d{yyyy-MM} to create file every month. You can use modulate flag to roll over the file at the interval boundary - start of the month.

In order to ensure just the current day log file is avaialable and other log files are deleted the should the policy be amended to :

<RollingRandomAccessFile name="test" fileName="/logs/test.log" filePattern="/logs/test.log.%d{yyyy-MM-dd}" TimeBasedTriggeringPolicy interval="1"/> /RollingRandomAccessFile> ?

Yes, it is correct. interval="1" is default so can be removed. DefaultRollOverStrategy is applied when you don't specify any rollover strategy. Default Rollover strategy will use the file name pattern provided to roll over. As this is daily (-dd) it will roll over file daily with no intermediate files on same day.

From docs -

A RollingRandomAccessFileAppender requires a TriggeringPolicy and a RolloverStrategy. The triggering policy determines if a rollover should be performed while the RolloverStrategy defines how the rollover should be done. If no RolloverStrategy is configured, RollingRandomAccessFileAppender will use the DefaultRolloverStrategy

You can further customize using appropriate trigger policy and rollover strategy.

Among others, when you configure a RollingFileAppender you need to provide a value for the filePattern parameter.

This configuration parameter will indicate the pattern of the file name of the generated archived log files.

The format of this pattern is dependent on the RolloverPolicy that is used by RollingFileAppender.

By default, Log4j 2 will use the Default Rollover Strategy.

This strategy will allow you to rollover your logs based on a numeric index, by indicating the %i pattern token or by date/time, by indicating the %d pattern token as in your use case. You can add the numeric index to the date/time pattern as well: in that case, the numeric index will be incremented until the result of the date/time pattern changes.

If you define a date/time pattern, you need to provide the base granularity for which the rollover will be performed, by passing a SimpleDateFormat compatible pattern, yyyy-MM-dd in your example.

I said base granularity and not just granularity because the actual log rollover moment will depend on how you configure the trigger policy associated with the RollingFileAppender.

In the case of TimeBasedTriggeringPolicy you can configure several parameters that will determine the log rollover behavior, mainly two.

First, you have the interval parameter: it will indicate how often a rollover should occur based on the most specific time unit in the date pattern. i.e. if, as in your example, you configure day as your most specific unit and provide a value of 3 (it is 1 by default) for the interval parameter the rollover would occur every 3 days.

Second, you can activate (it is false by default) the modulate parameter. This parameter indicates whether the interval should be adjusted to cause the next rollover to occur on the interval boundary. The Log4j2 documentation provides a clear example:

For example, if the item is hours, the current hour is 3 am and the interval is 4 then the first rollover will occur at 4 am and then next ones will occur at 8 am, noon, 4pm, etc.

Something similar will occur in your use case but with the semantic of day of year.

Please, see the source code of the PatternProcessor class for an in-depth information. Pay attention to the increment method as well.

Regarding log deletion, as far as I know the default rollover strategy will only delete old files if you are using a numeric index in your pattern (by tweaking the fileIndex, min end max parameters) but, since Log4j 2.5, you can use the delete action to perform cleanup of your date/time based logs when the log rollover occurs (in Log4j think in actions as a kind of hook).

For example, if you only need to keep your log files for 30 days you can configure this feature with something like:

<RollingRandomAccessFile name="test" fileName="/logs/test.log" filePattern="/logs/test.log.%d{yyyy-MM-dd}">
  <Policies>
    <TimeBasedTriggeringPolicy/>
  </Policies>
  <DefaultRolloverStrategy>
    <Delete basePath="/logs">
      <IfFileName glob="test.log.*" />
      <IfLastModified age="30d" />
    </Delete>
  </DefaultRolloverStrategy>
</RollingRandomAccessFile>

It is very important to be aware that the deletion process can affect to any files, not only log files: please, be sure to parameterize the right path in which it should be performed and to provide the right glob pattern when you use this feature.

Related