Upgrade log4j 2.x version cache asynchronous configuration interpretation

 Please indicate the source for reprint: http://zl378837964.iteye.com/blog/2359382

 

Now the latest Log4j 2 is the V2.8 version, using the 2.x version needs to import the jar as follows:

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-core</artifactId>
	<version>2.5</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-api</artifactId>
	<version>2.5</version>
</dependency>

 The following two are the jars that are compatible with V1.x and required for asynchrony :

(Disruptor is an open-source concurrency framework that can implement network Queue concurrent operations without locks.)

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-1.2-api</artifactId>
	<version>2.5</version>
</dependency>
(注意:require disruptor-3.3.3.jar or higher)
<dependency>
	<groupId>com.lmax</groupId>
	<artifactId>disruptor</artifactId>
	<version>3.3.4</version>
</dependency>

     

        The configuration method of the V2.x version, in addition to the encoded writing, also includes XML, JSON, YAML and Properties (note that this is re-supported after V2.4, the configuration method is similar to XML and JSON, which is different from the previous V1.x version) The configuration file can be implemented on the classpath, as well as defining variables, filtering settings, regularly deleting logs, supporting JDK8's Lambda and other new features; also compatible with Log4j 1.2, SLF4J, Commons Logging and java.util.logging (JUL) APIs, etc. Various log tools; you can also reload the configuration file periodically, just simply add the following:

<Configuration monitorInterval="30" status="INFO">

...  unit is s, with a minimum interval of 5s

...  a total of 8 levels, from low to high: All < Trace < Debug < Info < Warn < Error < Fatal < OFF

</Configuration>

 

 

If you want to use the YAML format, you need to import the formatting tools as follows:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId> jackson-data-format-yaml </artifactId>
    <version>2.8.5</version>
</dependency>

 If you want to use the JSON format, you need to import the formatting tools as follows:

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.8.5</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.8.5</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.8.5</version>
</dependency>

 

### Log4j2 is the most prominent, supporting efficient and low-latency asynchronous log writing ###

 

Asynchronous Loggers is a new feature in Log4j 2. It can be fully asynchronous or mixed with synchronization. It can also be used to only asynchronously implement Appenders to improve system performance. Official data shows that mixing is not as effective as fully asynchronous (below).

Comparison of multiple situations

1. Fully asynchronous XML configuration + parameters are as follows:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
    <RandomAccessFile name="RandomAccessFile" fileName="async.log" immediateFlush="false" append="false">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
      </PatternLayout>
    </RandomAccessFile>
  </Appenders>
  <Loggers>
    <Root level="info" includeLocation="false">
      <AppenderRef ref="RandomAccessFile"/>
    </Root>
  </Loggers>
</Configuration>

 Pay attention, pay attention! Configure parameters!

A. If you want loggers to be fully asynchronous, don't forget to set the startup parameter: -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector 

B. Or, create a log4j2.component.properties file and put it under the classpath, log4j2 will be automatically loaded at startup, and then the log output will become asynchronous output.

File content: Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

 

2. Mixed is synchronous and asynchronous. Due to the use of disruptor, tagging implementation no longer needs to set startup parameters (about Log4jContextSelector);

<asyncRoot> or <asyncLogger> can be mixed with <root> or <logger>.

The xml used in the mix is ​​as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!-- No need to set system property "Log4jContextSelector" 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>

eg. A complete project XML configuration example is as follows: 

 

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="ERROR">
    <Properties>
        <Property name="baseDir">/Users/chocolate/logs</Property>
        <Property name="filename">/Users/chocolate/logs/baseCollection.log</Property>
        <Property name="filenameError">/Users/chocolate/logs/baseCollectionError.log</Property>
    </Properties>

    <Appenders>
        <Console name="STDOUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %l - %msg%n"/>
        </Console>
        <RollingFile name="RollingFile" fileName="${filename}"
                     filePattern="${baseDir}/${date:yyyy-MM}/baseCollection-%d{yyyy-MM-dd-HH-mm}.log.gz">
            <PatternLayout pattern="%d %-5level [%t]%l - %msg%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="200 MB"/>
                <TimeBasedTriggeringPolicy interval="10" modulate="true"/>
            </Policies>
            <!--Automatically delete log compressed files older than 120 days-->
            <DefaultRolloverStrategy>
                <Delete basePath="${baseDir}" maxDepth="2">
                    <IfFileName glob="*/baseCollection-*.log.gz"/>
                    <IfLastModified age="20d"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        <!--Error log into file-->
        <RollingFile name="RollingFileError" fileName="${filenameError}"
                     filePattern="${baseDir}/${date:yyyy-MM}/baseCollectionError-%d{yyyy-MM-dd-HH}.log">
            <PatternLayout pattern="%d %-5level [%t]%l - %msg%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="200 MB"/>
                <TimeBasedTriggeringPolicy interval="24" modulate="true"/>
            </Policies>
            <!--Automatically delete log compressed files older than 120 days-->
            <DefaultRolloverStrategy>
                <Delete basePath="${baseDir}" maxDepth="2">
                    <IfFileName glob="*/baseCollectionError-*.log"/>
                    <IfLastModified age="30d"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>
    <Loggers>
        <!--Asynchronous output log-->
        <AsyncLogger name="com.choco" level="info">
            <!--Write info level-->
            <AppenderRef ref="RollingFile"/>
            <!--Write error level-->
            <AppenderRef ref="RollingFileError" level="error"/>
        </AsyncLogger>
        <Root level="debug">
            <AppenderRef ref="STDOUT"/>
        </Root>
    </Loggers>
</Configuration>

 important point:

<I>

Sometimes the log4j log printing in the same log file is repeated because the Console is set as the appender of logger and root in the following configuration,

此时只需要设置additivity="false"即可解决。(the appender associated with logger com.foo.Bar is first used, which writes the first instance to the Console. Next, the parent of com.foo.Bar, which in this case is the root logger, is referenced. The event is then passed to its appender, which is also writes to the Console, resulting in the second instance.)

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <!--Control output trace, do not inherit-->
    <Logger name="com.foo.Bar" level="trace" additivity="false">
      <!--The console prints the info above the specified package path-->
      <AppenderRef ref="Console" level="info"/>
    </Logger>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

 

<II> 

Log4jV1.x upgrade to V2.x, it should be noted that the original project uses log4j or self4j, and the way to obtain loggers is different:

Log4j instance:

import org.apache.log4j.Logger;

private static final Logger LOGGER = Logger.getLogger(X.class);

Slf4j instance: 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static final Logger logger = LoggerFactory.getLogger(X.class);

Use of Log4j2: 

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

private static final Logger logger = LogManager.getLogger(X.class);

Log4j V2.x provides conversion packages based on the above differences. You only need to import a few conversion packages to transparently use Log4j2 configuration, thereby avoiding code modifications in large projects, yeah yeah yeah!

However, there are several official restrictions:

  1. They must not access methods and classes internal to the Log4j 1.x implementation such as Appenders, LoggerRepository or Category's callAppenders method.
  2. They must not programmatically configure Log4j.
  3. They must not configure by calling the classes DOMConfigurator or PropertyConfigurator.

<III> 

 The log4j output cache log is in 8K units, and one block of the disk is 8K, which can reduce fragmentation; that is to say, if you set the cache to 20K, log4j will output when it is 16K (8K*2)), not 20K.

 

Appendix A:

Appenders official document: http://logging.apache.org/log4j/2.x/manual/appenders.html (23 kinds of everything)

Async Low-Latency Loggers official documentation: http://logging.apache.org/log4j/2.x/manual/async.html

log4j 2 official configuration: http://logging.apache.org/log4j/2.x/manual/configuration.html

 

Appendix B:

Properties configuration files support the advertiser, monitorInterval, name, packages, shutdownHook, shutdownTimeout, status, verbose, and dest attrbutes. See  Configuration Syntax  for the definitions of these attributes. (Props method is not common to all versions in V2.x, it is not recommended use)

status = error
dest = err
name = PropertiesConfig
 
property.filename = target/rolling/rollingtest.log
 
filter.threshold.type = ThresholdFilter
filter.threshold.level = debug
 
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %m%n
 
appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = ${filename}
appender.rolling.filePattern = target/rolling2/test1-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 2
appender.rolling.policies.time.modulate = true
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=100MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 5
 
appender.list.type = List
appender.list.name = List
appender.list.filter.threshold.type = ThresholdFilter
appender.list.filter.threshold.level = error
 
logger.rolling.name = com.example.my.app
logger.rolling.level = debug
logger.rolling.additivity = false
logger.rolling.appenderRef.rolling.ref = RollingFile
 
rootLogger.level = info
rootLogger.appenderRef.stdout.ref = STDOUT

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326644157&siteId=291194637