The environment

The JDK: 1.7.0 _79

CPU: [email protected] 4 cores

Eclipse: 3.7

Operating system: Win7

To prepare

Log4j: 1.7.21

<dependency>
        <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.721.</version>
</dependency>
Copy the code

log4j.xml

<? xml version="1.0" encoding="UTF-8"? > <! DOCTYPE log4j:configuration SYSTEM"log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

    <appender name="myConsole" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%d{dd HH:mm:ss,SSS\} %-5p] [%t] %c{2\} - %m%n"/> </layout> <! -- Filter sets the level of output --> <filterclass="org.apache.log4j.varia.LevelRangeFilter">
            <param name="levelMin" value="debug" />
            <param name="levelMax" value="warn" />
            <param name="AcceptOnMatch" value="true" />
        </filter>
    </appender>

    <appender name="myFile" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="log4jTest.log" />
        <param name="Append" value="true" />
        <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%t] - %m%n" />
        </layout>
    </appender>

    <appender name="async_file" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="32" />
        <appender-ref ref="myFile" />
    </appender>

    <logger name="org.logTest" additivity="false">
        <level value="info" />
        <appender-ref ref="async_file"/ > <! -- Sync :FILE Async_file --> </logger> </log4j: Configuration >Copy the code

2. The logback: 1.1.7

< the dependency > < groupId > ch. Qos. Logback < / groupId > < artifactId > logback - classic < / artifactId > < version > 1.1.7 < / version > </dependency>Copy the code

logback.xml

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <! -- Encoder defaults to PatternLayoutEncoder -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS}[%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>testFile.log</file> <append>true</append> <encoder> <pattern>[%t] - %m%n  </pattern> </encoder> </appender> <! Asynchronous output -- -- - > < appender name = "ASYNC" class = "ch. Qos. Logback. Classic. AsyncAppender" > <discardingThreshold>0</discardingThreshold> <appender-ref ref="FILE" /> </appender> <logger name="org.logTest" level="INFO" additivity="false"> <appender-ref ref="ASYNC" /> <! </logger> <root level="ERROR"> <appender-ref ref="STDOUT" /> </root> </configuration>Copy the code

3. Log4j2:2.6.2

< the dependency > < groupId > org. Apache. Logging. Log4j < / groupId > < artifactId > log4j - core < / artifactId > < version > 2.6.2 < / version > </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.6.2</version> </dependency> <dependency> <groupId>com.lmax</groupId> <artifactId> Disruptor </artifactId> < version > we < / version > < / dependency >Copy the code

log4j2.xml

<? The XML version = "1.0" encoding = "utf-8"? > <! Set log4j2's own log level to WARN --> <configuration status="warn"> <appenders> <console name=" console "target="SYSTEM_OUT"> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n" /> </console> <RollingFile name="RollingFileInfo" fileName="info.log" filePattern="${sys:user.home}/logs/hpaasvc/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"> <Filters> <ThresholdFilter level="INFO" /> <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL" /> </Filters> <PatternLayout pattern="[%t] - %m%n" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="100 MB" /> </Policies> </RollingFile> <RandomAccessFile name="RandomAccessFile" fileName="asyncWithLocation.log" immediateFlush="false" append="true"> <PatternLayout> <Pattern>[%t] - %m%n</Pattern> </PatternLayout> </RandomAccessFile> </appenders> <loggers> <! -- <AsyncLogger name="asynLogger" level="trace" includeLocation="true"> <AppenderRef ref="RandomAccessFile" /> </AsyncLogger> --> <Root level="info" includeLocation="true"> <AppenderRef ref="RollingFileInfo" /> </Root> </loggers> </configuration>Copy the code

test

Prepare 50 threads to record 1000000 pieces of data at the same time, and then count the time, the detailed code is as follows:

import java.util.concurrent.CountDownLatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class App { private static Logger log = LoggerFactory.getLogger(App.class); public static void main(String[] args) throws InterruptedException { int messageSize = 1000000; int threadSize = 50; final int everySize = messageSize / threadSize; final CountDownLatch cdl = new CountDownLatch(threadSize); long startTime = System.currentTimeMillis(); for (int ts = 0; ts < threadSize; ts++) { new Thread(new Runnable() { @Override public void run() { for (int es = 0; es < everySize; es++) { log.info("======info"); } cdl.countDown(); } }).start(); } cdl.await(); long endTime = System.currentTimeMillis(); System.out.println("log4j1:messageSize = " + messageSize + ",threadSize = " + threadSize + ",costTime = " + (endTime - startTime) + "ms"); }}Copy the code

Log4j1 and logBack should be synchronized and asynchronously appender

The asynchronous mode of log4j2 provides two modes:

1. Enable it globally

Attribute is set Log4jContextSelector systems: org. Apache. Logging. Log4j. Core. Async. AsyncLoggerContextSelector

System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
Copy the code

2. Hybrid synchronous asynchronous mode

You don’t need to set Log4jContextSelector, but you do need to use the AsyncLogger tag

More detailed official documents: logging.apache.org/log4j/2.x/m…

The results were statistically shown in the table below:

The asynchronous mode of Log4J2 provides a clear performance advantage, primarily due to the use of the Disruptor framework

LMAX Disruptor technology. Asynchronous Loggers internally use the Disruptor, a lock-free inter-thread communication library, instead of queues, resulting in higher throughput and lower latency.
Copy the code

A library of lockless interthread communication replaces the original queue

More Disruptor:

Developer.51cto.com/art/201306/…

ifeve.com/disruptor/

Source: my.oschina.net/OutOfMemory…

Recent hot articles recommended:

1.1,000+ Java Interview Questions and Answers (2021)

2. Don’t use if/ else on full screen again, try strategy mode, it smells good!!

3. Oh, my gosh! What new syntax is xx ≠ null in Java?

4.Spring Boot 2.5 is a blockbuster release, and dark mode is exploding!

5. “Java Development Manual (Songshan version)” the latest release, quick download!

Feel good, don’t forget to click on + forward oh!