1. Home
  2. Tutorials
  3. Java
  4. Log4j2
Yolinux.com Tutorial

Log4j2: Java logging framework

Log4j2 is a Java framework for logging of Java classes. The Apache Log4j2 library is the second generation framework following the success of Log4j. Log viewing tools like Apache Chainsaw can accept streaming logs or view a log file generated by Log4j2.

Log4j2 is the next generation upgrade to the Java logger Log4j. Log4j2 improvements include performance improvements, advanced filtering, automatically reload its configuration upon modification, Java 8 Lambda support.

Log4j2 Description:

Apache Log4j2 is a framework which provides the capability to log messages in a variety of formats to the local console, local files, streamed over a socket or even launch an email based on a hierarchy of notification levels.

Log LevelDescription
FATALSevere errors that cause premature termination.
ERROROther run-time errors or unexpected conditions.
WARNRun-time situations that are undesirable or unexpected, but not necessarily "wrong".
INFOInteresting run-time events (start-up/shutdown).
DEBUGDetailed information on the flow through the system.
TRACEMore detailed information.
Also defined are ALL and OFF.

Log4j2 Installation:

Download a prebuilt Log4j2 jar file: https://logging.apache.org/log4j/2.x/download.html eg. apache-log4j-2.x.x-bin.tar.gz

Installation: cd /opt; sudo tar xzf ~/Downloads/apache-log4j-2.6.2-bin.tar.gz

Includes these two jar files to be placed in your CLASSPATH:
  • log4j-api-2.6.2.jar
  • log4j-core-2.6.2.jar
Complete list:
[prompt]$ tar tzf apache-log4j-2.6.2-bin.tar.gz
apache-log4j-2.6.2-bin/LICENSE.txt
apache-log4j-2.6.2-bin/NOTICE.txt
apache-log4j-2.6.2-bin/RELEASE-NOTES.txt
apache-log4j-2.6.2-bin/log4j-api-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-api-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-api-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-core-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-core-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-core-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-core-2.6.2-tests.jar
apache-log4j-2.6.2-bin/log4j-iostreams-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-iostreams-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-iostreams-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-jcl-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-jcl-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-jcl-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-jul-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-jul-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-jul-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-flume-ng-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-flume-ng-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-flume-ng-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-1.2-api-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-1.2-api-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-1.2-api-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-slf4j-impl-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-slf4j-impl-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-slf4j-impl-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-to-slf4j-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-to-slf4j-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-to-slf4j-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-jmx-gui-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-jmx-gui-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-jmx-gui-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-taglib-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-taglib-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-taglib-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-web-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-web-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-web-2.6.2-javadoc.jar
apache-log4j-2.6.2-bin/log4j-nosql-2.6.2.jar
apache-log4j-2.6.2-bin/log4j-nosql-2.6.2-sources.jar
apache-log4j-2.6.2-bin/log4j-nosql-2.6.2-javadoc.jar

Add to CLASSPATH: ~/.bashrc
...
...


if [ -d /opt/apache-log4j-2.6.2-bin ]
then
  export CLASSPATH=/opt/apache-log4j-2.6.2-bin/log4j-api-2.6.2.jar:/opt/apache-log4j-2.6.2-bin/log4j-core-2.6.2.jar:$CLASSPATH
fi


...
...

Log4j2 Simple Example:

Example Java Class to log:

File: HelloWorld.java
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
     
public class HelloWorld {
    private static final Logger logger = LogManager.getLogger("HelloWorld");

    public static void main(String[] args) {
        String name = "Greg";
        logger.trace("Hello, World!");
        logger.debug("Debug example!");
        logger.info("Info example!");
        logger.warn("Example of a warning!");
        logger.error("My name is {}", name);
    }
}

File: log4j2.xml (Log4j2 default configuration file name)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
      <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
          <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <!-- set this value to one of fatal, error, warn, info, debug or trace -->
        <Root level="info">
          <AppenderRef ref="Console"/>
        </Root>
      </Loggers>
</Configuration>
If the log level is not specified, the log level is set to the default: "error"

For more on Log4j2 configuration file options see Apache Log4j2 configuration

File: build.xml
<?xml version="1.0" encoding="utf-8"?>
<project name="IO" default="jar" basedir=".">
        <description>Builds, tests, and runs the project Test.</description>
        <property name="build.dir" value="./" />
        <property name="src.dir" location="${build.dir}" />
       <path id="classpath">
                <!-- the current path is included to point to the config file log4j2.xml   -->
                <pathelement location="./" />
                <pathelement location="/usr/java/latest/lib/tools.jar" />
                <pathelement location="/opt/apache-log4j-2.6.2-bin/log4j-api-2.6.2.jar"/>
                <pathelement location="/opt/apache-log4j-2.6.2-bin/log4j-core-2.6.2.jar"/>
        </path>
        <target name="compile">
                <javac destdir="${build.dir}" debug="true" includeAntRuntime="false">
                        <src path="${src.dir}" />
                        <classpath refid="classpath" />
                </javac>
        </target>
        <target name="jar" depends="compile">
                <jar jarfile="hello-world.jar">
                        <manifest>
                                <attribute name="Main-Class" value="HelloWorld" />
                                <attribute name="Class-Path" value="classpath" />
                        </manifest>
                        <fileset dir="${build.dir}" includes="**/*.class" />
                </jar>
        </target>
        <target name="run" depends="jar">
                <java classname="HelloWorld" failonerror="true" fork="true">
                        <classpath>
                                <path refid="classpath" />
                                <path location="./hello-world.jar"/>
                        </classpath>
                </java>
        </target>
</project>

Building and running example:
  • Build: ant
  • Run example: ant run
run:
     [java] 00:12:07.759 [main] INFO  HelloWorld - Info example!
     [java] 00:12:07.761 [main] WARN  HelloWorld - Example of a warning!
     [java] 00:12:07.764 [main] ERROR HelloWorld - My name is Greg

BUILD SUCCESSFUL
Total time: 1 second

Log4j2 Multi-log Example:

This example shows how to log from multiple classes to multiple log file outputs and then control them independently. It also shows how to define the Log4J2 XML configuration file programatically and control the log levels independently.

Example Java Class to log:

File: HelloWorld.java
    import java.io.File;

    import org.apache.logging.log4j.Logger;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.core.LoggerContext;
     
    public class HelloWorld {
        static {
            System.setProperty("log4j.configurationFile",  "Log4j2ConfigurationFile.xml");
        }
        private static final Logger logger   = LogManager.getLogger(HelloWorld.class);
        private static final Logger loggerf2 = LogManager.getLogger(HelloWorld.class.getName() + "_File2");

        public static class InnerClassExample {
            private final Logger loggerInner = LogManager.getLogger("InnerClassExample.class");

            public InnerClassExample() {
                loggerInner.info("Hello from the inner class");
            }
        }

        public static void main(String[] args) {

            String name = "Greg";
            logger.trace("Hello, World!");
            logger.debug("Debug example!");
            logger.info("Info example!");
            logger.warn("Example of a warning!");
            logger.error("My name is {}", name);

            InnerClassExample innerClassExample = new InnerClassExample();

            for(int ii=0; ii<5; ii++) {
                loggerf2.info(" count: " + ii);
            }
        }
    }
Note the use of a static block assignment to set the Log4J2 configuration file name. This assignes the file name before anything executes in the application. Alternatively, the configuration file can be specified with the java command line arguments -Dlog4j.configuration=file:Log4j2ConfigurationFile.xml where the file is in the CLASSPATH or use a fully qualified path: -Dlog4j.configuration=/path/to/Log4j2ConfigurationFile.xml. Three loggers are assigned which can be independently configured.

File: Log4j2ConfigurationFile.xml (Log4j2 configuration file)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
      <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
          <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
          <File name="File" fileName="app.log" append="false">
          <PatternLayout>
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5p - %msg%n</Pattern>
          </PatternLayout>
        </File>
        <File name="File2" fileName="app2.log" append="false">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
          </PatternLayout>
        </File>
      </Appenders>
      <Loggers>
        <!-- set this value to one of all, off, fatal, error, warn, info, debug or trace -->
        <Root level="info">
          <AppenderRef ref="Console"/>
          <AppenderRef ref="File" level="WARN"/>
        </Root>
        <Logger name="HelloWorld.InnerClassExample" level="all" additivity="false">
          <AppenderRef ref="File"/>
        </Logger>
        <Logger name="HelloWorld_File2" level="all" additivity="false">
          <AppenderRef ref="File2"/>
        </Logger>
      </Loggers>
</Configuration>
This Log4J2 configuration file shows three outup configurations:
  • console terminal: output all logs which are "info" or worse (warn, error, fatal)
  • output file app.log: for all logs which are "warn" or worse (error, fatal)
  • output file app2.log: for all logs which are writen using the log handle "loggerf2" (for loop)

For more on Log4j2 configuration file options see Apache Log4j2 configuration

Building and running example:
  • Build: ant
  • Run example: ant run
run:
     [java] 02:14:10.794 [main] INFO  HelloWorld - Info example!
     [java] 02:14:10.797 [main] WARN  HelloWorld - Example of a warning!
     [java] 02:14:10.799 [main] ERROR HelloWorld - My name is Greg
     [java] 02:14:10.801 [main] INFO  InnerClassExample.class - Hello from the inner class

BUILD SUCCESSFUL
Total time: 1 second
Output from console terminal.

Log file: app.log
2018-04-07 02:28:01.352 [main] WARN  - Example of a warning!
2018-04-07 02:28:01.353 [main] ERROR - My name is Greg

Log file: app2.log
2018-04-07 02:28:01,354 INFO HelloWorld_File2 [main]  count: 0 
2018-04-07 02:28:01,354 INFO HelloWorld_File2 [main]  count: 1 
2018-04-07 02:28:01,354 INFO HelloWorld_File2 [main]  count: 2 
2018-04-07 02:28:01,354 INFO HelloWorld_File2 [main]  count: 3 
2018-04-07 02:28:01,354 INFO HelloWorld_File2 [main]  count: 4

Using Log4j2 with the "Chainsaw" log file viewer:

Apache Chainsaw is a Java GUI application for viewing log files. It can accept streaming logs or view a log file.

Chainsaw will filter, color code and display log messages. The screenshot below is showing two applications streaming log messages to two "receivers" configured in Chainsaw.

Controls on the left panel set the logging focus to the log pointers of your choice. Right click on the logger pointer and select "Focus on logger-ptr-name" to turn off all other logger pointers you don't want to see including logging from the Chainsaw application itself.

The controls on the right panel define the log levels for the application.

Apache Chainsaw configured for two XML socket receivers

Other Logger Display Programs:

Apache Chainsaw is my personal preference as it can display streaming logs from multiple programs, can ingest log files and works. Many of the logger programs have their personal strengths but often omit a key basic feature possessed by Chainsaw. Listed below are two of the Apache groups log file viewers. For a complete list see our list of logger display software.

Log ViewerDescription
Apache ChainsawDisplay log files, socket streams, filters, supports multiple applications.
Apache LogFactor5Display log files, socket streams, filters, supports multiple applications. LogFactor5 ships with Apache Log4j. Download from http://logging.apache.org/log4j/
RHEL6 install: yum install log4j
RHEL6 script: /usr/bin/logfactor5
Run: java -cp log4j-1.2.8.jar org.apache.log4j.lf5.StartLogFactor5

Links:

Books:

"Core Java 2, Volume 1: Fundamentals "
by Cay S. Horstmann, Gary Cornell
ISBN # 0132354764, Prentice Hall PTR 8th edition

The industry standard. Need I say more?

Amazon.com
"Core Java 2: Volume 2 Advanced Features "
by Cay S. Horstmann, Gary Cornell
ISBN # 0132354799, Prentice Hall PTR 8th edition

The industry standard. Need I say more?

Amazon.com
Logging and Log Management: The Authoritative Guide to Understanding the Concepts Surrounding Logging and Log Management
by Anton Chuvakian, Kevin Schmidt
ISBN #1597496359, Syngress

First edition (December 13, 2012) Logging and Log Management helps to simplify the process of effectively analyzing large volumes of diverse logs.

Amazon.com