I. Introduction to log4j2
log4j2 is an upgraded version of log4j 1.x, which refers to some excellent logback designs and fixes some problems, thus bringing about some significant improvements.
- Compared with log4j 1 and logback, log4j2 has a significant performance improvement and supports asynchronous log processing.
- Automatic overload configuration, referring to the logback design, will of course provide automatic refresh parameter configuration, in production can dynamically modify the level of the log without restarting the application.
- log4j2 no longer supports properties files, only xml, json or yaml.
2. SpringBoot 2.x Integration Log4j2
By default, spring boot uses lobback as a log implementation framework, and needs to exclude logback dependencies.
1.pom file addition
<!-- Integrate Log4j2 Journal --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
2.application.properties file addition
logging.config=classpath:log4j2.xml
3. Edit log4j2.xml file under Resources folder
?xml version="1.0" encoding="UTF-8"?> <Configuration status="INFO"> <Appenders> <Console name="STDOUT" target="SYSTEM_OUT"> <!-- <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> --> <PatternLayout pattern=".%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%file:%line] %-5level %logger{36} - %msg %n"/> </Console> <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log"> <PatternLayout> <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%file:%line] %-5level %logger{35} - %msg %n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="102400KB"/> </Policies> <DefaultRolloverStrategy fileIndex="max" max="2"/> </RollingFile> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="STDOUT"/> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>
III. Asynchronous Logging
Log4j2 is characterized by asynchronous logging, adding message queues as caching. Log4j2 provides two ways to implement logging. One is through AsyncAppender, the other is through AsyncLogger, which corresponds to the Appender component and Logger component we mentioned earlier.
Async Appender Mode
The default implementation is java.util.concurrent.Array BlockingQueue. Blocking queues in multi-threaded environments are vulnerable to lock contention, which may have an impact on performance.
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" name="MyApp" packages=""> <Appenders> <File name="MyFile" fileName="logs/app.log"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> </File> <Async name="Async"> <AppenderRef ref="MyFile"/> </Async> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="Async"/> </Root> </Loggers> </Configuration>
AsyncLogger approach
The officially recommended asynchronization method is faster, which is divided into global asynchronism and hybrid asynchronism, using disruptor non-blocking message queue.
- Global asynchrony
All logs are recorded asynchronously. When the system is initialized, the global parameter configuration is added:
System.setProperty("log4j2.contextSelector, "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
You can also load JVM startup parameters to set:
java -Dog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
- Hybrid Asynchronism
The use of synchronous and asynchronous logs in applications makes the configuration of logs more flexible.
<?xml version="1.0" encoding="UTF-8"?> <!-- No need to set system property "log4j2.contextSelector" to any value when using <asyncLogger> or <asyncRoot>. --> <Configuration status="WARN"> <Appenders> <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. --> <RandomAccessFile name="RandomAccessFile" fileName="asyncWithLocation.log" immediateFlush="false" append="false"> <PatternLayout> <Pattern>%d %p %class{1.} [%t] %location %m %ex%n</Pattern> </PatternLayout> </RandomAccessFile> </Appenders> <Loggers> <!-- pattern layout actually uses location, so we need to include it --> <AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true"> <AppenderRef ref="RandomAccessFile"/> </AsyncLogger> <Root level="info" includeLocation="true"> <AppenderRef ref="RandomAccessFile"/> </Root> </Loggers> </Configuration>
Notes for Asynchronous Logging
- Don't use AsyncAppender and AsyncLogger at the same time.
- Don't use AsyncAppender and AsyncLogger with global synchronization enabled.
- If not, do not print location information, such as% C or $class,% F or% file,% L or% location,% L or% line,% M or% method in pattern mode, which is a huge performance drain.
- Setting immediateFlush to false regardless of synchronization or asynchrony will greatly improve performance.
IV. Use of Note @Slf4j
If you don't want to write private final Logger logger = LoggerFactory. getLogger (current class name. class); you can use the annotation @Slf4j.
1.eclipse installs lombok plug-ins
2. Adding lombok dependencies to pom files
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.16</version> </dependency>
3. Add the @Sl4j annotation to the class and print the log.
@Slf4j class LogTest { @Test void testLog() { String testInfo = "Free flying flowers are like dreams"; log.info("The test info is :{}", testInfo); } }