Log4j Configurations – Controlling Logging to Multiple Files

Introduction
The purpose of inserting log statements into the code is a low-tech method for debugging it. It may also be the only way because debuggers are not always available or applicable. This is often the case for distributed applications.
Features of Log4j
We can enable logging at runtime without modifying the application binary.
We can control the behavior of logging by editing only the configuration file, no need to touch the application binary.
Developer are always clear with detailed context for application failures.
Log4j has one of the distinctive features – the notion of inheritance. Using this logger hierarchy feature we are able to control the log statements output at arbitrarily fine granularity but also at great ease. This helps to reduce the volume of logged output and the cost of logging.
We can set many targets for the log output such as a file, an OutputStream, a java.io.Writer, a remote log4j server, a remote Unix Syslog daemon, or many other output targets.
Loggin Levels
FATAL: shows messages at a FATAL level only
ERROR: Shows messages classified as ERROR and FATAL
WARNING: Shows messages classified as WARNING, ERROR, and FATAL
INFO: Shows messages classified as INFO, WARNING, ERROR, and FATAL
DEBUG: Shows messages classified as DEBUG, INFO, WARNING, ERROR, and FATAL
ALL – The ALL Level has the lowest possible rank and is intended to turn on all logging.
OFF – The OFF Level has the highest possible rank and is intended to turn off logging.
For more information please go through Apache Log4j http://logging.apache.org/log4j/2.x/
I will show you how we can control logging output to multiple log files. For example, we want to show logging for a package structure com.roytuts.* in a file called “log.log” but we want to show logging for a package structure com.roytuts.json in another file called “json.log”, then we want to create two different log files. We also want to exclude the logging from file “log.log” for package structure com.roytuts.json which is already appended to the “json.log” file.
Prerequisites
The following configurations are required in order to run the application
Eclipse
JDK 1.7
Have maven installed and configured
slf4j dependency in pom.xml
Now we will see the below steps how to create a maven based spring project in Eclipse
Step 1. Create a standalone maven project in Eclipse
Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.
maven-arctype-quickstart
Now enter the required fields (Group Id, Artifact Id) as shown below
Group Id : com.roytuts
Artifact Id : roytuts
Step 2. Modify the pom.xml file as shown below.

<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.roytuts</groupId>
    <artifactId>roytuts</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>roytuts</name>
    <url>http://maven.apache.org</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jdk.version>1.7</jdk.version>
        <json-sanitizer.version>1.0</json-sanitizer.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Step 3. If you see JRE System Library[J2SE-1.4] then change the version by below process
Do right-click on the project and go to Build -> Configure build path, under Libraries tab click on JRE System Library[J2SE-1.4], click on Edit button and select the appropriate jdk 1.7 from the next window. Click on Finish then Ok.
Step 4. For testing logger working correctly please create below two class in different packages
in package com.roytuts create below class

package com.roytuts;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MapTest {
  private static final Logger LOGGER = LoggerFactory.getLogger(MapTest.class);
  /**
   * @param args
   */
  public static void main(String[] args) {
    Map<String, String> map = new HashMap<String, String>();
    map.put("1", "One");
    map.put("2", "Two");
    LOGGER.debug("This will be printed in log.log file => map.size : " + map.size());
  }
}

So logging should be printed in log.log file
in package com.roytuts.json create below class

package com.roytuts.json;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JsonTest {
  private static final Logger LOGGER = LoggerFactory.getLogger(JsonTest.class);
  /**
   * @param args
   */
  public static void main(String[] args) {
    LOGGER.debug("This will be printed in json.log file");
  }
}

So logging should be printed in json.log file but it won’t append to the log.log file because I have added additivity=”false” to the category in log4j.xml
Step 5. Now create log4j.xml file in src/main/resources with the below content

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="FileAppender" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="log.log" />
        <param name="MaxFileSize" value="2MB" />
        <param name="MaxBackupIndex" value="15" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%d{HH:mm:ss.SSS}] %-5p %c %x - %m%n" />
        </layout>
    </appender>
    <appender name="JsonFileAppender" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="json.log" />
        <param name="MaxFileSize" value="2MB" />
        <param name="MaxBackupIndex" value="15" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%d{HH:mm:ss.SSS}] %-5p %c %x - %m%n" />
        </layout>
    </appender>
    <!-- additivity="false" because we do not want to append to main log file log.log file -->
    <category name="com.roytuts.json" additivity="false">
        <priority value="debug" />
        <appender-ref ref="JsonFileAppender" />
    </category>
    <category name="com.roytuts">
        <priority value="debug" />
    </category>
    <root>
        <priority value="debug" />
        <appender-ref ref="FileAppender" />
    </root>
</log4j:configuration>

In this file we have created two RollingFileAppender for logging to two different log files.
Step 6. Now run the above main classes, you will find there are two log files with the logging.
json.log file contains following

DEBUG com.roytuts.json.JsonTest  - This will be printed in json.log file

log.log file contains following

DEBUG com.roytuts.MapTest  - This will be printed in log.log file => map.size : 2

Note: log files are created in the project root directory.
Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *