Java, Logging

Log4j Features and Best Practices

Logging Levels

ALL – Turns on all logging. (MOST SPECIFIC)

FATAL – Severe errors that cause premature termination.

ERROR – Other run time errors or unexpected conditions.

WARN – Other run time situations that are undesirable or unexpected, but not necessarily “wrong”.

INFO – Interesting run time events: start up, shutdown, etc.

DEBUG – Detailed information on the flow through the system.

TRACE – A fine-grained debug message, typically capturing the flow through the application (v 2.x)

OFF – Turns off all logging. (LEAST SPECIFIC)

Suggested Best Practices

DEBUG messages should print to the console, not log files. To accomplish this, messages of level DEBUG can be configured to print to the console, and messages of level INFO and higher can be configured to print to the log files.

Additivity should be disabled (by setting the additivity attribute on the logger to false) to prevent extraneous output to the console and log files.

If desired, special purpose loggers, such as security, performance, etc. can be used to create multiple log files for each application, but that are smaller, and catered to a specific issue type.

The method configureAndWatch() should be invoked in the startup class so that changes to the configuration file will be monitored and implemented without restarting the application.

Capping Log File Size

Log file size can be capped by using the RollingFileAppender which can be configured to back up the log file once it reaches a certain size. You can also set the maximum number of backup files to be kept. To work properly, the apache-log4j-extras dependency with Maven must be added.

In order to see RollingFileAppender in action, refer this post.

Using Different Configuration Files for Different Environments

Different configuration files can be used in the different environments, in conjunction with Maven profiles, to facilitate reducing unnecessary logging statements in QA, Staging, and Production while still providing all of the information in Development. For example, DEBUG messages could be configured to only print to the log file in Development, but not in QA, Staging, or Production. Separate configuration files can be created for each environment such as: log4j-dev.xml, log4j-qa.xml, log4j-stage.xml, and log4j-prod.xml. To associate each configuration file with the correct Maven profile, the line:

<log4j.file> src/main/resources/environment_specific_config_file_name.xml </log4j.file>

can be added to the properties section of each environment’s Maven profile in the pom.xml.

Here is a link to a great article on log4j – log4j

Java, Logging, Maven

How to configure log4j in Java

Log4j is a simple and flexible logging framework. This post demonstrates how to configure log4j in your application using the XML file. The log4j can also be configured using the properties file. However, now a days configuring log4j using the properties file is considered to be outdated, and it is recommended to use XML file.

Step 1:If you are using Maven, add appropriate log4j dependency in pom.xml.

		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>

Step 2:Create log4j.xml file

This is the main config file having all run time configuration used by log4j. This file will have appenders information, log level information and output file names for file appenders.

This file goes into the \resources directory of your project.

log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC
  "-//APACHE//DTD LOG4J 1.2//EN" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
	debug="false">

	<appender name="file" class="org.apache.log4j.RollingFileAppender">
		<param name="File" value="../logs/SampleApp.log" />
		<param name="Append" value="true" />
		<param name="Threshold" value="INFO" />
		<param name="MaxFileSize" value="1MB" />
		<param name="MaxBackupIndex" value="1" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p %d [%t] %c: %m%n" />
		</layout>
	</appender>

	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Threshold" value="INFO" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n" />
		</layout>
	</appender>

	<root>
		<appender-ref ref="file" />
		<appender-ref ref="console" />
	</root>

</log4j:configuration>

Step 3:Add loggers in the code

	private static final long serialVersionUID = 1L;
	private static Logger logger = Logger.getLogger(WelcomeServlet.class);
	
	protected void doGet(
			HttpServletRequest request,
			HttpServletResponse response
	) throws ServletException, IOException {
		logger.info("Welcome in doGet!");
	}

Now when you hit this servlet, you will see ‘Welcome in doGet!’ on your console. Also, when you deploy the application on server and hit the servlet, you will notice a file being created in your server \logs directory with the name ‘SampleApp.log’.