log4j is a very popular logging library for Java development. It provides convenient and flexible logging mechanism as well as fast performance.
Putting log4j into your code is pretty easy as it requires minimum of work which mostly involves in configuring the logging system. This article describes the configuration of log4j in details, as well as providing some working examples.
Table of content
4.Code examples:
Typically, the steps to use log4j in your Java application are as follows:
You can get a distribution of log4j at: http://logging.apache.org/log4j/1.2/download.html
The latest version of log4j is 1.2.17. Download log4j-1.2.17.zipfile and extract the archive into a directory you like. The distribution comes with a lot of stuff: documentation, source code, examples… but the only thing we need is the log4j-1.2.17.jar file – log4j’s JAR library.
Add the log4j-1.2.17.jar into compilation classpath and runtime classpath of your project in order to have your code can be compiled and executed with log4j.
It is possible to write log4j’s logging statements without making any configuration, as shown in the following code snippet:
Logger logger = Logger.getLogger(MyClass.class); BasicConfigurator.configure(); logger.info("This is my first log4j's statement");
The above code will print out logging statements to the standard console:
0 [main] INFO com.mycompany.MyClass - This is my first log4j's statement
However, in practice, it is preferable to create a separate configuration for log4j for the following reasons:
Typically, configuring log4j involves in the following tasks:
We will describe each task in details.
The root logger is the base logger from which other loggers inherits. Syntax for configuring the root logger is as follows:
log4j.rootLogger=level[, appender1, appender2…]
- - Where level can be one of the following values (in ascending order of severity): ALL, DEBUG, INFO, WARN, ERROR, FATAL, and OFF. These constants are defined in the class org.apache.log4j.Level.
- appender1, appender2 are names of the appenders that configures how messages are logged, i.e. to standard console or log files. One logger can have multiple appenders, each one is configured individually by some properties start with log4j.appender.<appender_name>.For example:
log4j.rootLogger=DEBUG, ConsoleAppender, FileAppender
That tell log4j configures the root logger to log all messages from DEBUG level to console and to log file.
Programmatically, the root logger can be obtained by invoking the static method Logger.getRootLogger() which returns a Logger object. The level can be set via setLevel(Level) method; an appender can be specified via addAppender(Appender) method of the Logger object, respectively.
It is possible to configure loggers other than the root logger. The syntax is similar:
log4j.logger.<logger-name>=level[, appender1, appender2…]
where <logger-name>is name of a particular logger in the source code, for example: if you define a logger called com.mycompany.DatabaseUtil, then you can configure it through log4j’s configuration file as follows:
log4j.logger.com.mycompany.DatabaseUtil=INFO, ConsoleAppender
Programmatically, an individual logger can be created or retrieved (if already exists) by invoking the static methods Logger.getLogger(Class) or Logger.getLogger(String). For example:
Logger logger1 = Logger.getLogger(“com.mycompany.MyClass”); Logger logger2 = Logger.getLogger(MyClass.class);
In log4j’s terms, an appender specifies how messages are logged. An appender is a class that implements the interface org.apache.log4j.Appenderand is configured in configuration file follows this syntax:
log4j.appender.<appender_name>=<appender_class_name>
log4j.appender.<appender_name>.<property1_name>=<property1_value>
log4j.appender.<appender_name>.<property2_name>=<property2_value>
- - Whereappender_namemust match the name specified in the configuration of root logger or a particular logger.
- appender_class_name: fully qualified name of a class that implements org.apache.log4j.Appender interface, for example org.apache.log4j.ConsoleAppenderfor console appender,org.apache.log4j.FileAppender for file appender, to name a few. To see a complete list of appender classes provided by log4j, go to http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Appender.html, under “All known implementing classes”.
- property1_name: name of a particular property of the appender, depending on type of appender.
- property1_value: value of the corresponding property.
The following example indicates the configuration for a console appender of the root logger:
log4j.rootLogger=DEBUG, Console log4j.appender.Console =org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout
Programmatically, an appender can be created and assigned to a logger as follows:
Appender console = new ConsoleAppender(); Logger root = Logger.getRootLogger(); root.addAppender(console);
With log4j, messages are logged in a specified format which is referred as “layout”. Each appender is associated with a layout follows this syntax:
log4j.appender.<appender_name>.layout=<layout_class_name>
log4j.appender.<appender_name>.layout.ConversionPattern=<conversion_pattern>
- layout_class_name: fully qualified name of a class that extends the abstract class org.apache.log4j.Layout, for example org.apache.log4j.PatternLayout which formats the log message by a configurable pattern. To see a complete list of layout classes provided by log4j, go to http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Layout.html, under “Direct Known Subclasses”.
- conversion_pattern: specifies the pattern which formats log messages for the layout org.apache.log4j.PatternLayout, for example:
log4j.appender.console.layout.ConversionPattern=[%t] %-5p %c - %m%n
The conversion pattern can include String literals and conversion specifiers.
- String literals: any literal text.
- Each conversion specifier must follow this format:
<percent sign (%)>[format modifiers]<conversion characters>
- Where:
The specifiers used in the above example:
- t: name of the current executing thread.
- p: priority
- c: category
- m: log message.
- n: line separator character.
There are three ways to configure log4j:
We will describe each way in details in with code examples in the next section.
Properties file configuration example
XML file configuration example
Programmatic configuration example
The static method configure()of the class BasicConfigurator used to create a simple configuration.
The following program illustrates the simplest usage of log4j, without any explicit configuration:
import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Logger; public class BasicLog4jExample { public static void main(String[] args) { Logger logger = Logger.getLogger(BasicLog4jExample.class); BasicConfigurator.configure(); logger.info("This is my first log4j's statement"); } }
The basic configuration logs messages to standard console and uses the following conversion pattern:
%r [%t] %p %c %x - %m%n
Hence the above program produces the following output:
0 [main] INFO BasicLog4jExample - This is my first log4j's statement
To configures log4j from an external .properties file, invoke the static method configure() of the class PropertyConfigurator:
PropertyConfigurator.configure(String configFilename)
We specify log4j configuration in a file called log4j.properties as follows:
log4j.rootLogger=DEBUG, Appender1,Appender2 log4j.appender.Appender1=org.apache.log4j.ConsoleAppender log4j.appender.Appender1.layout=org.apache.log4j.PatternLayout log4j.appender.Appender1.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n log4j.appender.Appender2=org.apache.log4j.FileAppender log4j.appender.Appender2.File=applog.txt log4j.appender.Appender2.layout=org.apache.log4j.PatternLayout log4j.appender.Appender2.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n
As we can see, the root logger is configured with level set to DEBUG, and two appenders:
The following program illustrates how to load log4j configuration from a .properties file:
import java.io.File; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; public class PropertiesFileLog4jExample { static Logger logger = Logger.getLogger(PropertiesFileLog4jExample.class); public static void main(String[] args) { String log4jConfigFile = System.getProperty("user.dir") + File.separator + "log4j.properties"; PropertyConfigurator.configure(log4jConfigFile); logger.debug("this is a debug log message"); logger.info("this is a information log message"); logger.warn("this is a warning log message"); } }
It produces the following output on both the console and in the applog.txt file:
DEBUG 2012-09-30 14:14:58,718 [main] PropertiesFileLog4jExample - this is a debug log message INFO 2012-09-30 14:14:58,719 [main] PropertiesFileLog4jExample - this is a information log message WARN 2012-09-30 14:14:58,719 [main] PropertiesFileLog4jExample - this is a warning log message
NOTE:If we put the log4j.properties file under the root of the classpath, then we won’t have to call the configure() method explicitly. Log4j can detect this file automatically and configure its logging system based on the configuration file. For example, put this file in the same folder as the PropertiesFileLog4jExample.java file, then we can simply do:
Logger logger = Logger.getLogger(PropertiesFileLog4jExample.class); logger.debug("this is a debug log message");
It’s also possible to configure log4j with an XML file, by invoking the static method configure() of the class DOMConfigurator:
DOMConfigurator.configure(String configFilename)
We specify log4j configuration in a file called log4j.xml as follows:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="Appender1" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-7p %d [%t] %c %x - %m%n"/> </layout> </appender> <appender name="Appender2" class="org.apache.log4j.FileAppender"> <param name="File" value="applog.txt" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-7p %d [%t] %c %x - %m%n"/> </layout> </appender> <root> <priority value="DEBUG"/> <appender-ref ref="Appender1" /> <appender-ref ref="Appender2" /> </root> </log4j:configuration>
The log4j.xml file does the same purpose as the log4j.properties file in the section Properties file configuration example.
And following is code of the example program:
import java.io.File; import org.apache.log4j.Logger; import org.apache.log4j.xml.DOMConfigurator; public class XMLFileLog4jExample { static Logger logger = Logger.getLogger(XMLFileLog4jExample.class); public static void main(String[] args) { String log4jConfigFile = System.getProperty("user.dir") + File.separator + "log4j.xml"; DOMConfigurator.configure(log4jConfigFile); logger.debug("this is a debug log message"); logger.info("this is a information log message"); logger.warn("this is a warning log message"); } }
NOTE: Log4j can automatically detect the log4j.xml file if it is placed under the root of the classpath, so we won’t have to call the configure() method explicitly. Just get the logger and use the log methods.
When necessary, all log4j’s configuration can be set programmatically. The following example program does the same thing as Properties file configuration example and XML file configuration example, but without creating any external configuration file:
import org.apache.log4j.Appender; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.FileAppender; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; public class ProgrammaticLog4jExample { public static void main(String[] args) { // creates pattern layout PatternLayout layout = new PatternLayout(); String conversionPattern = "%-7p %d [%t] %c %x - %m%n"; layout.setConversionPattern(conversionPattern); // creates console appender ConsoleAppender consoleAppender = new ConsoleAppender(); consoleAppender.setLayout(layout); consoleAppender.activateOptions(); // creates file appender FileAppender fileAppender = new FileAppender(); fileAppender.setFile("applog3.txt"); fileAppender.setLayout(layout); fileAppender.activateOptions(); // configures the root logger Logger rootLogger = Logger.getRootLogger(); rootLogger.setLevel(Level.DEBUG); rootLogger.addAppender(consoleAppender); rootLogger.addAppender(fileAppender); // creates a custom logger and log messages Logger logger = Logger.getLogger(ProgrammaticLog4jExample.class); logger.debug("this is a debug log message"); logger.info("this is a information log message"); logger.warn("this is a warning log message"); } }