Log4j

Log4j BufferSize Example

This article is a tutorial about log priority levels in Log4j. In this tutorial, we are going to configure log4j via property files.

1. Introduction

Log4J (Java) is a widely used logging framework for Java. It continues to grow continuously with the recent upgrade to Log4j2. Log4j supports logging via Logger, Appender and Layouts.

Logger is the interaction point for the application and carries out the logging activity. It is used to specify the logging mode and the name of the logger. It also delivers logs to the specified destination with the help of the appender. The Appender delivers the log to the logging destination i.e. console, file or database along with options to fine-tune the logging mechanism. Appenders generally have lifecycle configuration and filtering support. Filtering enables to filter the messages whose logging mode does not match the level configured. Log4j supports multiple predefined appenders and also helps create custom appenders.

Layout specifies the display format of the logs. The most commonly used layout for Log4j is PatternLayout. A sample pattern is %d [%t] %-5p (%F: %L) -%m%n. The format strings for the pattern are as follows:

  • Date – Full date until microseconds.
  • Thread – JVM thread logging the output.
  • Logging Mode – INFO/ERROR/DEBUG/WARN.
  • Class – Java Class logging the output.
  • Line number – Line number in java class.
  • Message – The message logged.
  • Default line separator -/n unless specified otherwise.

2. Standard Logging

In this section, we will cover the standard example of logging to a file via Log4j.

Example Class

package com.jcg.examples;
import org.apache.log4j.Logger;
public class LoggerMain {
public static final Logger logger = Logger.getLogger(LoggerMain.class);
public static void main(String[] args) {
IntStream.rangeClosed(1, 1000).forEach(count -> {
logger.warn("This is a warn log");
}
);
} 
}
  • Line 4 configures a logger with the name as com.jcg.examples.LoggerMain.
  • Line 7 indicates the method used ie logging level for this message.

The next part is configuring the logger via XML file or properties. Below, we have used properties to provide a suitable configuration for the appender and the destination.

Configuration

log4j.rootLogger=WARN, fileLogger
log4j.appender.fileLogger=org.apache.log4j.FileAppender
log4j.appender.fileLogger.layout=org.apache.log4j.PatternLayout
log4j.appender.fileLogger.layout.ConversionPattern=%d [%t] %-5p (%F:%L) - %m%n
log4j.appender.fileLogger.File=example.log

  • Line 1 specifies the threshold /allowed log level for the application.
  • Line 2 specifies the type of appender used i.e. FileAppender for appending events to the file.
  • In Line 5, we specify the output file name with the fully qualified path. In this example, the relative path is specified and the file will be created in the application directory.

The below screenshot shows the logged messages to the file example.log created under application directory.

log4j filtered logs

3. Buffered Logging

In this section, we will cover buffered logging with an example. Buffering is used to reduce IO operations. It stores the events in memory and directs log to the destination on reaching the buffer threshold.

Buffering Configuration

log4j.rootLogger=WARN, fileLogger
log4j.appender.fileLogger=org.apache.log4j.FileAppender
log4j.appender.fileLogger.layout=org.apache.log4j.PatternLayout
log4j.appender.fileLogger.layout.ConversionPattern=%d [%t] %-5p %m%n
log4j.appender.fileLogger.File=example.log
log4j.appender.fileLogger.bufferedIO = true
  • Here the conversion pattern does not include %F and %L flags. These slow down the logging performance.
  • bufferedIO is set to true to enable buffered logging.
  • In this example, buffersizeis not set. If it is not set, a default buffer size of 8 KB is used.

The above configuration will produce an output as specified in the screenshot.

log4j_buffer

 

4. Buffered Logging with buffer size

In the previous configuration, buffer size was not explicitly configured. Log4j supports defining a buffer size to control buffered logging.

Buffer Size Configuration

log4j.rootLogger=WARN, fileLogger
log4j.appender.fileLogger=org.apache.log4j.FileAppender
log4j.appender.fileLogger.layout=org.apache.log4j.PatternLayout
log4j.appender.fileLogger.layout.ConversionPattern=%d [%t] %-5p %m%n
log4j.appender.fileLogger.File=example.log
log4j.appender.fileLogger.bufferedIO = true
log4j.appender.fileLogger.bufferSize = 16
  • In Line 6, buffer capability is enabled.
  • Line 7 specifies the buffer size. In this configuration, it is set to 16 KB. In our small application, we don’t see the effects of buffer size setting. But the difference is that logs will be buffered till the buffer size reaches 16KB in the second configuration.

5. Buffer and ImmediateFlush

In our previous post(ImmediateFlush), we looked at another way of delayed flushing. If bufferedIO is enabled, immediateFlush is set to false. i.e flushing is delayed and logs are buffered. By default, immediate flush has a buffer size of 1 KB. Now this configuration would be sufficient for most of the applications but for a configurable buffer size, bufferedIO and bufferedSize must be utilized. This allows developers to control the performance parameters of the application.

Buffering has similar disadvantages of immediateFlush. The application can crash before the last few lines are buffered to the logging destination. Even in our above example, the application terminates before the logs are written. If we observe during the run, in log file only ~900 log lines will be written. Our application terminates and the last 100 lines are missing in the log file. We need to consider the performance trade-off while disabling the buffer.

6. Execution Steps

  1. Import the example as a Maven project.
  2. Maven will import the dependencies automatically.
  3. Run the application with the configuration specified above.

7. Download the Source Code

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

Rajagopal ParthaSarathi

Rajagopal works in software industry solving enterprise-scale problems for customers across geographies specializing in distributed platforms. He holds a masters in computer science with focus on cloud computing from Illinois Institute of Technology. His current interests include data science and distributed computing.
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