Apache Log4j 2 Tutorials

摘要: A simple log4j 2 hello world example.

A simple log4j 2 hello world example.

Tested with

  • Log4j 2.11.2
  • Maven 3
  • Java 8
Note
Apache Log4j 2, the fastest Java logging framework, provides significant improvements over its predecessor, Log4j 1.x.

1. Project Directory

2. Maven

	<dependency>
		<groupId>org.apache.logging.log4j</groupId>
		<artifactId>log4j-api</artifactId>
		<version>2.11.2</version>
	</dependency>
	<dependency>
		<groupId>org.apache.logging.log4j</groupId>
		<artifactId>log4j-core</artifactId>
		<version>2.11.2</version>
	</dependency>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.mkyong</groupId>
    <artifactId>log4j2</artifactId>
    <version>1.0</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <log4j.version>2.11.2</log4j.version>
        <disruptor.version>3.4.2</disruptor.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <!-- https://logging.apache.org/log4j/2.x/manual/async.html -->
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>${disruptor.version}</version>
        </dependency>
        <!-- slf4j bridge to log4j
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        -->
        <!-- SMTPAppender need this  -->
        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>javax.mail</artifactId>
            <version>1.6.2</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <!-- Attach the shade into the package phase -->
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.mkyong.HelloWorld</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

3. log4j2.xml

3.1 Create a log4j2.xml in the project classpath.

src/resources/log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="LogToConsole" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="com.mkyong" level="debug" additivity="false">
            <AppenderRef ref="LogToConsole"/>
        </Logger>
        <Root level="error">
            <AppenderRef ref="LogToConsole"/>
        </Root>
    </Loggers>
</Configuration>

For other format

4. Hello Log4j 2

4.1 Read this Log4j 2 API

HelloWorld.java
package com.mkyong;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class HelloWorld {
    private static final Logger logger = LogManager.getLogger(HelloWorld.class);
    public static void main(String[] args) {
        logger.debug("Hello from Log4j 2");
        // in old days, we need to check the log level to increase performance
        /*if (logger.isDebugEnabled()) {
            logger.debug("{}", getNumber());
        }*/
        // with Java 8, we can do this, no need to check the log level
        logger.debug("{}", () -> getNumber());
    static int getNumber() {
        return 5;

Output

19:12:25.337 [main] DEBUG com.mkyong.HelloWorld - Hello from Log4j 2
19:12:25.340 [main] DEBUG com.mkyong.HelloWorld - 5

5. Log4j 2 Configuration

5.1 We can change the status to “trace”, “debug”, “info”, “warn”, “error” and “fatal” to enable the internal Log4j events, it will display many useful logs for the Log4j components. Read this for Log4j configuration

src/resources/log4j2.xml
<Configuration status="DEBUG">
</Configuration>

6. Log4j 2 Appenders

Some of the common Log4j appenders.

6.1 ConsoleAppender

log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
    <Appenders>
        <Console name="LogToConsole" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
		<!-- avoid duplicated logs with additivity=false -->
        <Logger name="com.mkyong" level="debug" additivity="false">
            <AppenderRef ref="LogToConsole"/>
        </Logger>
        <Root level="error">
            <AppenderRef ref="LogToConsole"/>
        </Root>
    </Loggers>
</Configuration>

6.2 FileAppender

log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
    <Appenders>
        <Console name="LogToConsole" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <File name="LogToFile" fileName="logs/app.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
        </File>
    </Appenders>
    <Loggers>
        <Logger name="com.mkyong" level="debug" additivity="false">
            <AppenderRef ref="LogToFile"/>
            <AppenderRef ref="LogToConsole"/>
        </Logger>
        <Logger name="org.springframework.boot" level="error" additivity="false">
            <AppenderRef ref="LogToConsole"/>
        </Logger>
        <Root level="error">
            <AppenderRef ref="LogToFile"/>
            <AppenderRef ref="LogToConsole"/>
        </Root>
    </Loggers>
</Configuration>

6.3 RollingFileAppender – Rotate log files daily or when the file size > 10MB.

log4j2.xml
<Configuration status="DEBUG">
    <Appenders>
        <Console name="LogToConsole" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <RollingFile name="LogToRollingFile" fileName="logs/app.log"
                    filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
			<PatternLayout>
				<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
			</PatternLayout>
			<Policies>
				<TimeBasedTriggeringPolicy />
				<SizeBasedTriggeringPolicy size="10 MB"/>
			</Policies>
		</RollingFile>
    </Appenders>
    <Loggers>
        <!-- avoid duplicated logs with additivity=false -->
        <Logger name="com.mkyong" level="debug" additivity="false">
            <AppenderRef ref="LogToRollingFile"/>
        </Logger>
        <Root level="error">
            <AppenderRef ref="LogToConsole"/>
        </Root>
    </Loggers>
</Configuration>

By default, it will create up to 7 archives on the same day.

We can override the default 7 archives with this DefaultRolloverStrategy

	<RollingFile name="LogToRollingFile" fileName="logs/app.log"
			filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
		<PatternLayout>
			<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
		</PatternLayout>
		<Policies>
			<TimeBasedTriggeringPolicy/>
			<SizeBasedTriggeringPolicy size="10 MB"/>
		</Policies>
		<DefaultRolloverStrategy max="10"/>
	</RollingFile>

6.4 RollingRandomAccessFileAppender – Similar to the RollingFileAppender, but faster.

log4j2.xml
	<RollingRandomAccessFile name="LogToRollingRandomAccessFile" fileName="logs/app.log"
			filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
		<PatternLayout>
			<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
		</PatternLayout>
		<Policies>
			<TimeBasedTriggeringPolicy/>
			<SizeBasedTriggeringPolicy size="1 MB"/>
		</Policies>
		<DefaultRolloverStrategy max="10"/>
	</RollingRandomAccessFile>

6.5 AsyncAppender – Make appender asynchronous. Increase performance.

log4j2.xml
<Configuration status="DEBUG">
    <Appenders>
        <Console name="LogToConsole" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <RollingRandomAccessFile name="LogToRollingRandomAccessFile" fileName="logs/app.log"
               filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="1 MB"/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingRandomAccessFile>
        <Async name="Async">
			<!-- reference to other appenders -->
            <AppenderRef ref="LogToRollingRandomAccessFile"/>
        </Async>
    </Appenders>
    <Loggers>
        <!-- avoid duplicated logs with additivity=false -->
        <Logger name="com.mkyong" level="debug" additivity="false">
            <AppenderRef ref="Async"/>
        </Logger>
        <Root level="error">
            <AppenderRef ref="LogToConsole"/>
        </Root>
    </Loggers>
</Configuration>

6.6 SMTPAppender – Need javax.mail to send email.

pom.xml
	<dependency>
		<groupId>com.sun.mail</groupId>
		<artifactId>javax.mail</artifactId>
		<version>1.6.2</version>
	</dependency>
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <RollingRandomAccessFile name="LogToRollingRandomAccessFile" fileName="logs/app.log"
                filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="1 MB"/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingRandomAccessFile>
        <SMTP name="LogToMail" subject="Error Log From Log4j"
              from="from@DOMAIN"
              to="to@DOMAIN"
              smtpHost="smtp.mailgun.org"
              smtpPort="25"
              smtpUsername="abc"
              smtpPassword="123"
              bufferSize="100">
        </SMTP>
    </Appenders>
    <Loggers>
        <Logger name="com.mkyong" level="debug" additivity="false">
            <AppenderRef ref="LogToRollingRandomAccessFile"/>
            <AppenderRef ref="LogToConsole"/>
        </Logger>
        <Root level="error">
            <AppenderRef ref="LogToMail"/>
        </Root>
    </Loggers>
</Configuration>

Simulate an error

package com.mkyong;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class HelloWorldError {
    private static final Logger logger = LogManager.getLogger(HelloWorldError.class);
    public static void main(String[] args) {
        try {
            System.out.println(getData());
        } catch (IllegalArgumentException e) {
            logger.error("{}", e);
    static int getData() throws IllegalArgumentException {
        throw new IllegalArgumentException("Sorry IllegalArgumentException!");

Sample email

Note
Always refer to this official Log4j appenders

7. Asynchronous Loggers

7.1 To enable all loggers to asynchronous, we need 2 things :

  • The disruptor 3 is present in project class path.
  • Set system property log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

7.2 If we try to configure log4j2.contextSelector and the disruptor is not present in the classpath, it will prompt the following error message :

$ mvn clean package
$ mvn -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -jar target\log4j2-1.0.jar
java.lang.NoClassDefFoundError: com/lmax/disruptor/EventTranslatorVararg
    at java.lang.ClassLoader.defineClass1 (Native Method)
    at java.lang.ClassLoader.defineClass (ClassLoader.java:1009)
    at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:174)
    at java.net.URLClassLoader.defineClass (URLClassLoader.java:545)
    at java.net.URLClassLoader.access$100 (URLClassLoader.java:83)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:453)

7.3 To fix it, add disruptor

pom.xml
	<dependency>
		<groupId>com.lmax</groupId>
		<artifactId>disruptor</artifactId>
		<version>3.4.2</version>
	</dependency>

7.4 Run it again, with Log4j 2 configuration in debug status.

Asynchronous Loggers

$ java -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -jar target\log4j2-1.0.jar
2019-03-25 21:11:23,919 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@464bee09
2019-03-25 21:11:23,921 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@464bee09,component=AsyncLoggerRingBuffer
2019-03-25 21:11:23,921 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@464bee09,component=StatusLogger
2019-03-25 21:11:23,922 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@464bee09,component=ContextSelector
2019-03-25 21:11:23,923 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@464bee09,component=Loggers,name=
2019-03-25 21:11:23,923 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@464bee09,component=Loggers,name=com.mkyong
2019-03-25 21:11:23,924 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@464bee09,component=Appenders,name=LogToConsole
2019-03-25 21:11:23,924 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@464bee09,component=Appenders,name=LogToRollingFile
//...
2019-03-25 21:11:24,020 pool-1-thread-1 DEBUG Stopped LoggerContext[name=AsyncContext@464bee09, org.apache.logging.log4j.core.async.AsyncLoggerContext@45fd9a4d] with 

Synchronous Loggers

2019-03-25 21:12:49,432 main DEBUG Registering MBean org.apache.logging.log4j2:type=57baeedf,component=StatusLogger
2019-03-25 21:12:49,433 main DEBUG Registering MBean org.apache.logging.log4j2:type=57baeedf,component=ContextSelector
2019-03-25 21:12:49,433 main DEBUG Registering MBean org.apache.logging.log4j2:type=57baeedf,component=Loggers,name=
2019-03-25 21:12:49,434 main DEBUG Registering MBean org.apache.logging.log4j2:type=57baeedf,component=Loggers,name=com.mkyong
2019-03-25 21:12:49,435 main DEBUG Registering MBean org.apache.logging.log4j2:type=57baeedf,component=Appenders,name=LogToConsole
2019-03-25 21:12:49,435 main DEBUG Registering MBean org.apache.logging.log4j2:type=57baeedf,component=Appenders,name=LogToRollingFile
//...
2019-03-25 21:12:49,449 pool-1-thread-1 DEBUG Stopped LoggerContext[name=57baeedf, org.apache.logging.log4j.core.LoggerContext@4ed5eb72] with status true

8. Mixing Synchronous and Asynchronous Loggers

<Configuration status="WARN">
    <Appenders>
        <Console name="LogToConsole" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <RollingRandomAccessFile name="LogToRollingRandomAccessFile" fileName="logs/app.log"
                                 filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="1 MB"/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <!-- asynchronous loggers -->
        <AsyncLogger name="com.mkyong" level="debug" additivity="false">
            <AppenderRef ref="LogToRollingRandomAccessFile"/>
            <AppenderRef ref="LogToConsole"/>
        </AsyncLogger>
        <!-- synchronous loggers -->
        <Root level="error">
            <AppenderRef ref="LogToConsole"/>
        </Root>
    </Loggers>
</Configuration>

Read this Asynchronous Loggers for Low-Latency Logging

上一篇: JavaScript How to redirect a page
下一篇: Spring Boot + Spring data JPA + PostgreSQL
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号