There is so much to tell about the Western country in that day that it is hard to know where to start. One thing sets off a hundred others. The problem is to decide which one to tell first.
—JOHN STEINBECK, East of Eden
Manual · Appenders · Appenders: Rolling File
Appenders: Rolling File
RollingFileAppender
RollingFileAppender
extends FileAppender with the capability to rollover log
files. For example, RollingFileAppender can log to a
file named log.txt file and, once a certain condition is
met, change its logging target to another file.
There are two important subcomponents that interact with
RollingFileAppender. The first
RollingFileAppender sub-component, namely
RollingPolicy, (see
below) is responsible for undertaking the actions required for
a rollover. A second subcomponent of
RollingFileAppender, namely
TriggeringPolicy, (see
below) will determine if and exactly when rollover
occurs. Thus, RollingPolicy is responsible for the
what and TriggeringPolicy is responsible for
the when.
To be of any use, a RollingFileAppender must have
both a RollingPolicy and a
TriggeringPolicy set up. However, if its
RollingPolicy also implements the
TriggeringPolicy interface, then only the former needs
to be specified explicitly.
Here are the available properties for RollingFileAppender:
| Property Name | Type | Description |
|---|---|---|
| file | String |
See FileAppender properties. Note
that file can be null in
which case the output is written only to the target specified
by the RollingPolicy. |
| append | boolean |
See FileAppender properties. |
| encoder |
Encoder
|
See OutputStreamAppender properties. |
| rollingPolicy | RollingPolicy |
This option is the component that will dictate
RollingFileAppender's behavior when rollover
occurs. See more information below.
|
| triggeringPolicy | TriggeringPolicy |
This option is the component that will tell
RollingFileAppender when to activate the rollover
procedure. See more information below.
|
| prudent | boolean |
FixedWindowRollingPolicy
is not supported in prudent mode.
FileAppender.
|
Overview of rolling policies
RollingPolicy
is responsible for the rollover procedure which involves file
moving and renaming.
The RollingPolicy interface is presented below:
package ch.qos.logback.core.rolling;
import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.spi.LifeCycle;
public interface RollingPolicy extends LifeCycle {
public void rollover() throws RolloverFailure;
public String getActiveFileName();
public CompressionMode getCompressionMode();
public void setParent(FileAppender appender);
}
The rollover method accomplishes the work involved
in archiving the current log file. The
getActiveFileName() method is called to compute the
file name of the current log file (where live logs are written
to). As indicated by getCompressionMode method a
RollingPolicy is also responsible for determining the compression
mode. Lastly, a RollingPolicy is given a reference to
its parent via the setParent method.
TimeBasedRollingPolicy
TimeBasedRollingPolicy is possibly the most
popular rolling policy. It defines a rollover policy based on time,
for example by day or by month.
TimeBasedRollingPolicy assumes the responsibility for
rollover as well as for the triggering of said rollover. Indeed,
TimeBasedTriggeringPolicy implements both
RollingPolicy and TriggeringPolicy
interfaces.
TimeBasedRollingPolicy's configuration takes one
mandatory fileNamePattern property and
several optional properties.
| Property Name | Type | Description |
|---|---|---|
| fileNamePattern | String |
The mandatory fileNamePattern
property defines the name of the rolled-over (archived) log
files. Its value should consist of the name of the file, plus
a suitably placed %d conversion specifier. The
%d conversion specifier may contain a date-and-time
pattern as specified by the
java.text.SimpleDateFormat class. If the
date-and-time pattern is omitted, then the default pattern
yyyy-MM-dd is assumed. The rollover period is
inferred from the value of fileNamePattern.
Note that the file property in
However, if you choose to omit the file property, then the active file will be computed anew for each period based on the value of fileNamePattern. In this configuration no roll over occurs, unless file compression is specified. The examples below should clarify this point. The date-and-time pattern, as found within the accolades of %d{} follow java.text.SimpleDateFormat conventions. The forward slash '/' or backward slash '\' characters anywhere within the fileNamePattern property or within the date-and-time pattern will be interpreted as directory separators. Multiple %d specifiersIt is possible to specify multiple %d specifiers but only one of which can be primary, i.e. used to infer the rollover period. All other tokens must be marked as auxiliary by passing the 'aux' parameter (see examples below). Multiple %d specifiers allow you to organize archive files in a folder structure different than that of the roll-over period. For example, the file name pattern shown below organizes log folders by year and month but roll-over log files every day at midnight. /var/log/%d{yyyy/MM, aux}/myapplication.%d{yyyy-MM-dd}.log
TimeZoneUnder certain circumstances, you might wish to roll-over log files according to a clock in a timezone different than that of the host. It is possible to pass a timezone argument following the date-and-time pattern within the %d conversion specifier. For example: aFolder/test.%d{yyyy-MM-dd-HH, UTC}.log
If the specified timezone identifier is unknown or misspelled, the GMT timezone is assumed as dictated by the TimeZone.getTimeZone(String) method specification. |
| maxHistory | int | The optional maxHistory property controls the maximum number of archive files to keep, asynchronously deleting older files. For example, if you specify monthly rollover, and set maxHistory to 6, then 6 months worth of archives files will be kept with files older than 6 months deleted. Note as old archived log files are removed, any folders which were created for the purpose of log file archiving will be removed as appropriate. Setting maxHistory to zero disables archive removal. By default, maxHistory is set to zero, i.e. by default there is no archive removal. |
| totalSizeCap | FileSize | The optional totalSizeCap property controls the total size of all archive files. Oldest archives are deleted asynchronously when the total size cap is exceeded. The totalSizeCap property requires maxHistory property to be set as well. Moreover, the "max history" restriction is always applied first and the "total size cap" restriction applied second. In other words, if enabled, both restrictions are applied, albeit sequentially. The totalSizeCap property can be specified in units of bytes, kilobytes, megabytes or gigabytes by suffixing a numeric value with KB, MB and respectively GB. For example, 5242880, 5120KB, 5120 KB, 5MB, 5 MB, 2 GB and 2GB are all valid values, with the first five being equivalent. A numerical value with no suffix is taken to be in units of bytes. By default, totalSizeCap is set to zero, meaning that there is no total size cap. |
| cleanHistoryOnStart | boolean |
If set to true, archive removal will be executed on appender start up. By default, this property is set to false. Archive removal is normally performed during roll over. However, some applications may not live long enough for roll over to be triggered. It follows that for such short-lived applications archive removal may never get a chance to execute. By setting cleanHistoryOnStart to true, archive removal is performed at appender start up. |
Here are a few fileNamePattern values with an
explanation of their effects.
| fileNamePattern | Rollover schedule | Example |
|---|---|---|
| /wombat/foo.%d | Daily rollover (at midnight). Due to the omission of the optional time and date pattern for the %d token specifier, the default pattern of yyyy-MM-dd is assumed, which corresponds to daily rollover. |
file property not set: During November 23rd, 2006, logging output will go to the file /wombat/foo.2006-11-23. At midnight and for the rest of the 24th, logging output will be directed to /wombat/foo.2006-11-24. file property set to /wombat/foo.txt: During November 23rd, 2006, logging output will go to the file /wombat/foo.txt. At midnight, foo.txt will be renamed as /wombat/foo.2006-11-23. A new /wombat/foo.txt file will be created and for the rest of November 24th logging output will be directed to foo.txt. |
| /wombat/%d{yyyy/MM}/foo.txt | Rollover at the beginning of each month. |
file property not set: During the month of October 2006, logging output will go to /wombat/2006/10/foo.txt. After midnight of October 31st and for the rest of November, logging output will be directed to /wombat/2006/11/foo.txt. file property set to /wombat/foo.txt: The active log file will always be /wombat/foo.txt. During the month of October 2006, logging output will go to /wombat/foo.txt. At midnight of October 31st, /wombat/foo.txt will be renamed as /wombat/2006/10/foo.txt. A new /wombat/foo.txt file will be created where logging output will go for the rest of November. At midnight of November 30th, /wombat/foo.txt will be renamed as /wombat/2006/11/foo.txt and so on. |
| /wombat/foo.%d{yyyy-ww}.log | Rollover at the first day of each week. Note that the first day of the week depends on the locale. | Similar to previous cases, except that rollover will occur at the beginning of every new week. |
| /wombat/foo%d{yyyy-MM-dd_HH}.log | Rollover at the top of each hour. | Similar to previous cases, except that rollover will occur at the top of every hour. |
| /wombat/foo%d{yyyy-MM-dd_HH-mm}.log | Rollover at the beginning of every minute. | Similar to previous cases, except that rollover will occur at the beginning of every minute. |
| /wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log | Rollover at the beginning of every minute. | Similar to previous cases, except that file names will be expressed in UTC. |
| /foo/%d{yyyy-MM,aux}/%d.log | Rollover daily. Archives located under a folder containing year and month. | In this example, the first %d token is marked as auxiliary. The second %d token, with time and date pattern omitted, is then assumed to be primary. Thus, rollover will occur daily (default for %d) and the folder name will depend on the year and month. For example, during the month of November 2006, archived files will all placed under the /foo/2006-11/ folder, e.g /foo/2006-11/2006-11-14.log. |
Any forward or backward slash characters are interpreted as folder (directory) separators. Any required folder will be created as necessary. You can thus easily place your log files in separate folders.
Automatic file compression
TimeBasedRollingPolicy supports automatic file
compression. This feature is enabled if the value of the fileNamePattern option ends with .gz
.zip or .xz. Note that xz compression requires
Tukaani project's XZ library for
Java. In case XZ compression is requested but the XZ
library is missing, then logback will substitute GZ compression as
a fallback.
| fileNamePattern | Rollover schedule | Example |
|---|---|---|
| /wombat/foo.%d.gz | Daily rollover (at midnight) with automatic GZIP compression of the archived files. |
file property not set: During November 23rd, 2009, logging output will go to the file /wombat/foo.2009-11-23. However, at midnight that file will be compressed to become /wombat/foo.2009-11-23.gz. For the 24th of November, logging output will be directed to /wombat/folder/foo.2009-11-24 until it's rolled over at the beginning of the next day. file property set to /wombat/foo.txt: During November 23rd, 2009, logging output will go to the file /wombat/foo.txt. At midnight that file will be compressed and renamed as /wombat/foo.2009-11-23.gz. A new /wombat/foo.txt file will be created where logging output will go for the rest of November 24th. At midnight November 24th, /wombat/foo.txt will be compressed and renamed as /wombat/foo.2009-11-24.gz and so on. |
The fileNamePattern serves a dual purpose. First, by studying the pattern, logback computes the requested rollover periodicity. Second, it computes each archived file's name. Note that it is possible for two different patterns to specify the same periodicity. The patterns yyyy-MM and yyyy@MM both specify monthly rollover, although the resulting archive files will carry different names.
By setting the file property you can decouple the location of the active log file and the location of the archived log files. The logging output will be targeted into the file specified by the file property. It follows that the name of the active log file will not change over time. However, if you choose to omit the file property, then the active file will be computed anew for each period based on the value of fileNamePattern. By leaving the file option unset you can avoid file renaming errors which occur while there exist external file handles referencing log files during roll over.
The maxHistory property controls the maximum number of archive files to keep, deleting older files. For example, if you specify monthly rollover, and set maxHistory to 6, then 6 months worth of archives files will be kept with files older than 6 months deleted. Note as old archived log files are removed, any folders which were created for the purpose of log file archiving will be removed as appropriate.
For various technical reasons, rollovers are not clock-driven but depend on the arrival of logging events. For example, on 8th of March 2002, assuming the fileNamePattern is set to yyyy-MM-dd (daily rollover), the arrival of the first event after midnight will trigger a rollover. If there are no logging events during, say 23 minutes and 47 seconds after midnight, then rollover will actually occur at 00:23'47 AM on March 9th and not at 0:00 AM. Thus, depending on the arrival rate of events, rollovers might be triggered with some latency. However, regardless of the delay, the rollover algorithm is known to be correct, in the sense that all logging events generated during a certain period will be output in the correct file delimiting that period.
Here is a sample configuration for
RollingFileAppender in conjunction with a
TimeBasedRollingPolicy.
Example: Sample configuration of a
RollingFileAppender using a
TimeBasedRollingPolicy
(logback-examples/src/main/resources/chapters/appenders/conf/logback-RollingTimeBased.xml)
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logFile.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} -%kvp- %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
Requires a server call.
Requires a server call.
The next configuration sample illustrates the use of
RollingFileAppender associated with
TimeBasedRollingPolicy in prudent
mode.
Example: Sample configuration of a
RollingFileAppender using a
TimeBasedRollingPolicy
(logback-examples/src/main/resources/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml)
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- Support multiple-JVM writing to the same log file -->
<prudent>true</prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} -%kvp -%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
Requires a server call.
Requires a server call.
Size and time based rolling policy
Sometimes you may wish to archive files essentially by date but
at the same time limit the size of each log file, in particular if
post-processing tools impose size limits on the log files. In
order to address this requirement, logback ships with
SizeAndTimeBasedRollingPolicy.
Note that TimeBasedRollingPolicy already allows
limiting the combined size of archived log files. If you only wish
to limit the combined size of log archives, then
TimeBasedRollingPolicy described above and setting
the totalSizeCap property should be amply
sufficient. Moreover, given that file renaming is a relatively
slow process and is frought with problems, we discourage the use
of SizeAndTimeBasedRollingPolicy unless you have a
real-world use case.
The roll over based on size relies on the "%i" conversion token in addition to "%d". Both the %i and %d tokens are mandatory. Each time the current log file reaches maxFileSize before the current time period ends, it will be archived with an increasing index, starting at 0.
The table below lists the properties applicable for
SizeAndTimeBasedRollingPolicy. Note these properties
complement those applicable for TimeBasedRollingPolicy.
| Property Name | Type | Description |
|---|---|---|
| maxFileSize | FileSize |
Each time the current log file reaches maxFileSize before the current time period ends, it will be archived with an increasing index, starting at 0. Options in defined in units of "FileSize" can be specified in bytes, kilobytes, megabytes or gigabytes by suffixing a numeric value with KB, MB and respectively GB. For example, 5000000, 5000KB, 5MB and 2GB are all valid values, with the first three being equivalent. |
| checkIncrement | Duration |
since 1.5.8 The checkIncrement property is no longer needed as logback now counts the number of bytes written to file. |
Here is a sample configuration file demonstrating time and size based log file archiving.
Example: Sample configuration for
SizeAndTimeBasedRollingPolicy
(logback-examples/src/main/resources/chapters/appenders/conf/logback-sizeAndTime.xml)
<configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.txt</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="ROLLING" />
</root>
</configuration>
Requires a server call.
Requires a server call.
Note the "%i" conversion token in addition to "%d". Both the %i and %d tokens are mandatory. Each time the current log file reaches maxFileSize before the current time period ends, it will be archived with an increasing index, starting at 0.
Size and time based archiving supports deletion of old archive files. You need to specify the number of periods to preserve with the maxHistory property. When your application is stopped and restarted, logging will continue at the correct location, i.e. at the largest index number for the current period.
In versions prior to 1.1.7, this document mentioned a component
called SizeAndTimeBasedFNATP. However, given that
SizeAndTimeBasedRollingPolicy offers a simpler configuration
structure, we no longer document
SizeAndTimeBasedFNATP. Moreover, in logback version
1.5.8,
SizeAndTimeBasedFNATP was renamed as
SizeAndTimeBasedFileNamingAndTriggeringPolicy. Thus, earlier
configuration files using SizeAndTimeBasedFNATP will
no longer work.
FixedWindowRollingPolicy
Given that file renaming is a relatively slow process and is
frought with problems, we consider
FixedWindowRollingPolicy as a deprecated policy and do
not recommend its use.
When rolling over,
FixedWindowRollingPolicy renames files according
to a fixed window algorithm as described below.
The fileNamePattern option represents the file name pattern for the archived (rolled over) log files. This option is required and must include an integer token %i somewhere within the pattern.
Here are the available properties for
FixedWindowRollingPolicy
| Property Name | Type | Description |
|---|---|---|
| minIndex | int |
This option represents the lower bound for the window's index. |
| maxIndex | int |
This option represents the upper bound for the window's index. |
| fileNamePattern | String |
This option represents the pattern that will be followed
by the For example, using MyLogFile%i.log associated with minimum and maximum values of 1 and 3 will produce archive files named MyLogFile1.log, MyLogFile2.log and MyLogFile3.log. Note that file compression is also specified via this property. For example, fileNamePattern set to MyLogFile%i.log.zip means that archived files must be compressed using the zip format; gz format is also supported. |
Given that the fixed window rolling policy requires as many file renaming operations as the window size, large window sizes are strongly discouraged. When large values are specified by the user, the current implementation will automatically reduce the window size to 20.
Let us go over a more concrete example of the fixed window rollover policy. Suppose that minIndex is set to 1, maxIndex set to 3, fileNamePattern property set to foo%i.log, and that file property is set to foo.log.
| Number of rollovers | Active output target | Archived log files | Description |
|---|---|---|---|
| 0 | foo.log | - | No rollover has happened yet, logback logs into the initial file. |
| 1 | foo.log | foo1.log | First rollover. foo.log is renamed as foo1.log. A new foo.log file is created and becomes the active output target. |
| 2 | foo.log | foo1.log, foo2.log | Second rollover. foo1.log is renamed as foo2.log. foo.log is renamed as foo1.log. A new foo.log file is created and becomes the active output target. |
| 3 | foo.log | foo1.log, foo2.log, foo3.log | Third rollover. foo2.log is renamed as foo3.log. foo1.log is renamed as foo2.log. foo.log is renamed as foo1.log. A new foo.log file is created and becomes the active output target. |
| 4 | foo.log | foo1.log, foo2.log, foo3.log | In this and subsequent rounds, the rollover begins by deleting foo3.log. Other files are renamed by incrementing their index as shown in previous steps. In this and subsequent rollovers, there will be three archive logs and one active log file. |
The configuration file below gives an example of configuring
RollingFileAppender and
FixedWindowRollingPolicy. Note that the File option is mandatory even if it contains
some of the same information as conveyed with the fileNamePattern option.
Example: Sample configuration of a RollingFileAppender using a
FixedWindowRollingPolicy (logback-examples/src/main/resources/chapters/appenders/conf/logback-RollingFixedWindow.xml)
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>tests.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} -%kvp -%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
Requires a server call.
Requires a server call.
Overview of triggering policies
TriggeringPolicy
implementations are responsible for instructing the
RollingFileAppender when to rollover.
The TriggeringPolicy interface contains only one
method.
package ch.qos.logback.core.rolling;
import java.io.File;
import ch.qos.logback.core.spi.LifeCycle;
public interface TriggeringPolicy<E> extends LifeCycle {
public boolean isTriggeringEvent(final File activeFile, final <E> event);
}
The isTriggeringEvent() method takes as parameters
the active file and the logging event currently being
processed. The concrete implementation determines whether the
rollover should occur or not, based on these parameters.
The most widely-used triggering policy, namely
TimeBasedRollingPolicy which also doubles as a
rolling policy, was already discussed earlier along with
other rolling policies.
SizeBasedTriggeringPolicy
SizeBasedTriggeringPolicy looks at the size of the
currently active file. If it grows larger than the specified size,
it will signal the owning RollingFileAppender to
trigger the rollover of the existing active file.
SizeBasedTriggeringPolicy accepts only one
parameter, namely maxFileSize, with a
default value of 10 MB.
The maxFileSize option can be specified in bytes, kilobytes, megabytes or gigabytes by suffixing a numeric value with KB, MB and respectively GB. For example, 5000000, 5000KB, 5MB and 2GB are all valid values, with the first three being equivalent.
Here is a sample configuration with a
RollingFileAppender in conjunction with
SizeBasedTriggeringPolicy triggering rollover when
the log file reaches 5MB in size.
Example: Sample configuration of a
RollingFileAppender using a
SizeBasedTriggeringPolicy
(logback-examples/src/main/resources/chapters/appenders/conf/logback-RollingSizeBased.xml)
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>test.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} -%kvp -%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
Requires a server call.
Requires a server call.