Logback

Logback RollingFileAppender Example

In this example, we will begin by explaining the Logback RollingFileAppender and then move on to how to get RollingFileAppender running on simple examples. Logback is a modern, fast and flexible logging framework. The RollingFileAppender in the Logback is one of the most using Appender in the enterprise world. It extends the FileAppender with the capability to rollover log files. You can find more information about the Logback, Appenders and FileAppender in this post: Logback FileAppender Example

1.Rolling FileAppender

What is the meaning of the rolling file? Let me explain. When you use FileAppender, the event messages are constantly appended to the end of the log file. The size of the log file increases gradually. By the applying RollingFileAppender, the regular log file are splitted up into many based on a particular schedule, such as daily, weekly, monthly. Assume that we configure by daily, the log file list are seen like below:

   example.log.2015-04-30
   example.log.2015-05-01
   example.log.2015-05-02
   example.log.2015-05-03
   …
   example.log

The log file is rolled out every day, and the file without the date in its name is the current log file. At the end of the day, the current log file ( example.log ) is backed up into the file with date info in its name. For example “example.log.2015-05-03”. And the “example.log” becomes a logging file for the new day.

The size of the log files is smaller with this helpful and effective technique. You can delete old generated log files or move them to another disk space. When a problem occurs, you can quickly identify by inspecting only the relevant log files.

1.1 Configuration of the RollingFileAppender

RollingFileAppender extends the FileAppender. So the “file”, “encoder”, “append” and “prudent” properties are inherited by the FileAppender. You can read about them in this post again: Logback FileAppender Example. The other properties specific to the RollingFileAppender are rollingPolicy and triggeringPolicy. The RollingPolicy is responsible for undertaking the actions required for a rollover. The TriggeringPolicy determines if and exactly when the rollover occurs. Thus, RollingPolicy is responsible for the what and TriggeringPolicy is responsible for the when.

TimeBasedRollingPolicy is possibly the most popular rolling policy. It defines a rollover policy based on time. It takes these properties:

Property NameTypeMandatory?Description
fileNamePatternStringYesIt 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 which may contain a date-and-time pattern. 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. The rollover period is inferred from the value of fileNamePattern.
maxHistoryintNoIt controls the maximum number of archive files to keep, deleting older files. For example, if you specify monthly rollover, and set maxHistory to 8, then 8 months worth of archives files will be kept with files older than 8 months deleted.
cleanHistoryOnStartbooleanNoIf set to true, the archive will be removed on appender start up. By default this property is set to false.

Here are some fileNamePattern values with their explanation.

fileNamePatternRollover ScheduleDescription
/logs/example.%dDaily rollovertime and date pattern for the %d token specifier is omitted. So the default pattern is “yyyy-MM-dd”, which corresponds to daily rollover.
/logs/example.%d{yyyy-MM}.logMonthly rolloverThe files that rolled over look like: example.2015-03.log, example.2015-04.log
/logs/example.%d{yyyy-MM-dd_HH}.logHourly rolloverThe files that rolled over look like: example.2015-05-17_09.log, example.2015-05-17_10.log
/logs/%d{yyyy/MM}/example.logMonthly rolloverPlease notice that date and time pattern is in the directory name. The current log file path is “logs/example.log”. The directories of the rolled over files are “logs/2015/04/example.log”, “logs/2015/03/example.log”, …
/logs/example.%d{yyyy-ww}.zipWeekly rolloverPlease notice that file pattern ends with “zip”. Thus, the rolled over files are compressed. Logback applies automatic file compression if the value of the fileNamePattern option ends with .gz or .zip.

Another rolling policy is FixedWindowRollingPolicy. It renames the files according to a fixed window algorithm. 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. The minIndex and maxIndex properties represent the upper and lower bound for the window’s index. For example, using logFile%i.log associated with minimum and maximum values of 1 and 3 will produce archive files named logFile1.log, logFile2.log and logFile3.log.

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. Its maxFileSize option can be specified in bytes, kilobytes, megabytes or gigabytes.

We have tried to mention some configuration properties of the Logback RollingFileAppender. Now we exemplify them in some running code below.

2.Overview

Our preferred IDE is Eclipse and preferred build automation tool is Maven. I have already illustrated in detail how to create a Maven Project in the Eclipse in my reference example. This post is also about Logback, so the maven dependencies are the same with this example. You can examine: Logback FileAppender Example

3.Implemantation

In this implementation part, In order to show you more, I would like to demonstrate small code and configuration snippets and their execution results, rather than a complete example files.

3.1 TimeBasedRollingPolicy Example

logback.xml

 	...
	<appender name="TIME_BASED_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
 		<file>c:/logs/timeBasedlogFile.log</file>
    	<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">    	
      		<!-- daily rollover -->
      		<fileNamePattern>c:/logs/timeBasedlogFile.%d{yyyy-MM-dd-HH-mm}.log</fileNamePattern>
      		<maxHistory>30</maxHistory>
    	</rollingPolicy>

    	<encoder>
      		<pattern>%relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    	</encoder>
  	</appender>	
	...
	<logger name="timeBased" level="INFO">
		<appender-ref ref="TIME_BASED_FILE" />
		<appender-ref ref="STDOUT" />
	</logger>	

The date and time conversion specifier ( %d{} ) is “yyyy-MM-dd-HH-mm” in the fileNamePattern configuration. So the rollover period of the TimeBasedRollingPolicy is minutely. Because the smallest date unit is “minute” in this pattern. And please note that The rollover period is inferred from the value of fileNamePattern.

Java main method

        ... 
	private static final Logger	LOGGER	= LoggerFactory.getLogger( "timeBased" );

	public static void main( final String[] args ) {

		for ( int i = 1; i <= 24; i++ ) {
			LOGGER.info( "write log" );

			try {
				Thread.sleep( 10000L );
			} catch ( final InterruptedException e ) {
				LOGGER.error( "an error occurred", e );
			}
		}
	}
        ...

In the Java code, the “for loop” executes for 24 times and in each step, the Thread sleeps for 10 seconds. So the total execution time of the “for loop” is about 4 minutes. According to the minutely rollover configuration we expect 4 log files to be generated.

Log files directory content
Log files directory content

As you see, 4 rolled over log files were generated after the execution.

timeBasedlogFile.2015-05-19-01-59

40349 [main] INFO  timeBased - write log
50432 [main] INFO  timeBased - write log
60433 [main] INFO  timeBased - write log
70434 [main] INFO  timeBased - write log
80434 [main] INFO  timeBased - write log
90435 [main] INFO  timeBased - write log

If we look into the content of one the rolled over log file, we see 6 lines of log. Because log messages were inserted with 10 seconds interval.

3.2 FixedWindowRollingPolicy Example

logback.xml

	...
 	<appender name="FIX_WINDOW_BASED_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
 		<file>c:/logs/fixWindowBasedlogFile.log</file>
    	<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
      		<fileNamePattern>c:/logs/fixWindowBasedlogFile%i.log</fileNamePattern>
      		<minIndex>1</minIndex>
      		<maxIndex>10</maxIndex>
    	</rollingPolicy>

  		<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      		<maxFileSize>1KB</maxFileSize>
    	</triggeringPolicy>
    	
    	<encoder>
      		<pattern>%relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    	</encoder>
  	</appender> 	
	...
	<logger name="fixWindowBased" level="INFO">
		<appender-ref ref="FIX_WINDOW_BASED_FILE" />
		<appender-ref ref="STDOUT" />
	</logger>

In this example, “FixedWindowRollingPolicy” is used. The string %i, which indicates the position of the current window index is at the end of the log file in the fileNamePattern. So the archive files are produced with the name like “fixWindowBasedlogFile1”, “fixWindowBasedlogFile2” and so on. MinIndex is set to 1, maxIndex set to 10. Thus, 10 backup log files can be generated at most. But after the 10th archived file is created, what will happen in the next rollover? In the subsequent rounds, the rollover begins by deleting fixWindowBasedlogFile10.log. Other files are renamed by incrementing their index. For example, fixWindowBasedlogFile8 is renamed as fixWindowBasedlogFile9, fixWindowBasedlogFile is renamed as fixWindowBasedlogFile1 and a new fixWindowBasedlogFile is created and becomes the active output target.

According to the SizeBasedTriggeringPolicy trigger policy in the configuration, when the size of the current log file grows larger than 1 kilobyte, the rollover is triggered.

        ... 
	private static final Logger	LOGGER	= LoggerFactory.getLogger( "fixWindowBased" );

	public static void main( final String[] args ) {

		for ( int i = 1; i <= 100; i++ ) {
			LOGGER.info( "write log with FixedWindowRollingPolicy" );

			try {
				Thread.sleep( 200L );
			} catch ( final InterruptedException e ) {
				LOGGER.error( "an error occurred", e );
			}
		}
	}
        ...

After the 100 log writing events, we see that 7 archived files are produced:

ss
Log files directory content

Now, we test the automatic file compression skill of the Logback. I change the “fileNamePattern” as c:/logs/fixWindowBasedlogFile%i.log.zip by adding “.zip” at the end of the file name pattern.

After the execution, the archive files are compressed with the zip format:

ss
Log files directory content

3.3 Size and Time Based Rolling Example

We have already illustrated the time based and size based rolling. In the Logback, it is possible to mix them. With the sub-component for TimeBasedRollingPolicy called SizeAndTimeBasedFNATP, the rollover occurs when the active log file reaches the maximum file size before the end of the time period.

 	<appender name="SIZE_AND_TIME_BASED_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
 		<file>c:/logs/sizeAndTimeBasedlogFile.log</file>
    	<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      		<fileNamePattern>c:/logs/sizeAndTimeBasedlogFile.%d{yyyy-MM-dd-HH-mm}.%i.log</fileNamePattern>
      		<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        		<maxFileSize>1KB</maxFileSize>
      		</timeBasedFileNamingAndTriggeringPolicy>
    	</rollingPolicy>
    	
    	<encoder>
      		<pattern>%relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    	</encoder>
  	</appender> 

Note the “%i” conversion token in addition to “%d”. 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.

        ...
	private static final Logger	LOGGER	= LoggerFactory.getLogger( "sizeAndTimeBased" );

	public static void main( final String[] args ) {

		for ( int i = 1; i <= 40; i++ ) {
			LOGGER.info( "write log with SizeAndTimeBasedFNATP" );

			try {
				Thread.sleep( 1000L );
			} catch ( final InterruptedException e ) {
				LOGGER.error( "an error occurred", e );
			}
		}
	}
        ...

After the execution, archived log files are created as below:

ss
Log files directory content

4.Download the Eclipse Project

This project demonstrates how to use the “RollingFileAppender” in the Logback framework. Download link is below.

Download
You can download the full source code of this example here : logbackrollingfileappenderexample

Ilker Konar

I am a senior software developer with experience mostly in java-related technologies with appliance in the telecommunication industry. I have been programming for more than fifteen years. I am passionate about programming. I like learning new frameworks, languages and design patterns.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button