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!