This article is about configuring Apache Log4j. Apache log4j is an open-source project from Apache group. It takes care of the following scenarios:
- It allows us to control the logging activity from an external configuration file. It can be in for of a properties file or XML.
- One can publish logging information to any level of granularity based on the code invoking it.
- It is capable of publishing logging information to various destinations such as files, consoles, even JMS and database.
- It has decoupled the message being logged and the pattern in which it finally logs so one can publish or print it in different formats and layouts
- Finally, it is highly scalable as it allows developers to enhance the capability of logging by creating new logging destinations and unique formats and layouts.
Let’s get started with the example.
Log4j Dependency
In this example, I am using log4j
version 1.2.7. We need to add the dependency to our pom.xml
.
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javarticles.log4j</groupId> <artifactId>log4jExample</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies> </project>
log4j Layers
We will configure lo4j properties using the key value format. Before we start configuring lo4j, let’s understand the three important layers involved.
- Logger – The Logger object is responsible for capturing logging information. Logger objects are stored in a namespace hierarchy so if one wants each Logger object can be configured differently.
- Appender – The Appender object is responsible for publishing logging information to the preferred destinations. Each Appender object will have at least one target destination attached to it.
- Layout – The Layout object is used to format logging information in different styles.
Logger Layers
log4j.rootLogger
is the root logger.
The rootLogger is the father of all appenders. Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy (including rootLogger).
If Logger11 is child Logger1 which in turn is child of RootLogger, any logging request for Logger11 will be forwarded to Logger1 which in turn will forward it to its parent the RootLogger.
In our example, we have set one Logger for each package.
- log4j.rootLogger – RootLogger
- log4j.logger.com.javarticles – Logger for
com.javarticles
- log4j.logger.com.javarticles.log4j – Logger for
com.javarticles.log4j
- log4j.logger.com.javarticles.log4j.info.Log4jInfoExample – Logger for class
Log4jInfoExample
- log4j.logger.com.javarticles.log4j.warn.Log4jWarnExample – Logger for class
Log4jWarnExample
Appender
The Appender object is responsible for publishing logging information to various preferred destinations. Each Appender object will have at least one target destination attached to it.
In our example, we are using org.apache.log4j.FileAppender
and org.apache.log4j.ConsoleAppender
.
Level
Level defines the granularity and priority of any logging information, for example, OFF, DEBUG, INFO, ERROR, WARN, FATAL and ALL.
Configuring Log4j
First we will configure the RootLogger. We will set its level to INFO level and assign couple of appenders file
and console
. These are just names. You can use any name you want.
Next, you need to assign an appender and layer implementation to the logger.
For example, we will assign a FileAppender
to file
log4j.appender.file=org.apache.log4j.FileAppender
Next, assign a layout.
log4j.appender.file.layout=org.apache.log4j.PatternLayout
You can also assign a format for the message. %d will be filled with the datetime. %p will be filled with the priority code. %F will be replaced with the file name. %L is the line number. %m is the actual message and %n is the line separator.
log4j.appender.file.layout.ConversionPattern=%d | %p | %F %L | %m%n
log4j.properties:
# Root logger option log4j.rootLogger=INFO, file, console log4j.logger.com.javarticles=INFO, console log4j.logger.com.javarticles.log4j=INFO, console log4j.logger.com.javarticles.log4j.info.Log4jInfoExample=INFO, console log4j.logger.com.javarticles.log4j.warn.Log4jWarnExample=WARN, console # Direct log messages to a log file log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=javarticles.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d | %p | %F %L | %m%n # Direct log messages to stdout log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.Target=System.out log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d{HH:mm}| %p | %F %L | %m%n
Run the Example
Log4jInfoExample:
package com.javarticles.log4j.info; import org.apache.log4j.Logger; public class Log4jInfoExample { public void log(String msg){ LOGGER.info(msg + ", this is Log4j info message"); } private static final Logger LOGGER = Logger.getLogger(Log4jInfoExample.class); }
Log4jWarnExample:
package com.javarticles.log4j.warn; import org.apache.log4j.Logger; public class Log4jWarnExample { public void log(String msg) { LOGGER.warn(msg + ", this is a warning from Log4jWarnExample"); LOGGER.info(msg + ", this is an info from Log4jWarnExample"); } private static final Logger LOGGER = Logger.getLogger(Log4jWarnExample.class); }
Log4jExample:
package com.javarticles; import org.apache.log4j.Logger; import com.javarticles.log4j.info.Log4jInfoExample; import com.javarticles.log4j.warn.Log4jWarnExample; public class Log4jExample { public static void main(String[] args) { LOGGER.info("This is Log4j Example"); Log4jInfoExample infoExample = new Log4jInfoExample(); infoExample.log("Hello"); Log4jWarnExample warnExample = new Log4jWarnExample(); warnExample.log("Hello"); } private static final Logger LOGGER = Logger.getLogger(Log4jExample.class); }
Note that the message repeats as we multiple loggers and each logger consumes the requests as well as forwards the request to its parent.
Output:
16:27| INFO | Log4jExample.java 11 | This is Log4j Example 16:27| INFO | Log4jExample.java 11 | This is Log4j Example 16:27| INFO | Log4jInfoExample.java 8 | Hello, this is Log4j info message 16:27| INFO | Log4jInfoExample.java 8 | Hello, this is Log4j info message 16:27| INFO | Log4jInfoExample.java 8 | Hello, this is Log4j info message 16:27| INFO | Log4jInfoExample.java 8 | Hello, this is Log4j info message 16:27| WARN | Log4jWarnExample.java 8 | Hello, this is a warning from Log4jWarnExample 16:27| WARN | Log4jWarnExample.java 8 | Hello, this is a warning from Log4jWarnExample 16:27| WARN | Log4jWarnExample.java 8 | Hello, this is a warning from Log4jWarnExample 16:27| WARN | Log4jWarnExample.java 8 | Hello, this is a warning from Log4jWarnExample
Download the source code
This was an example about Apache’s log4j. You can download the source code here: log4jExample.zip