与log4j1相比,log4j2的性能 [英] Performance of log4j2 compared to log4j1

查看:85
本文介绍了与log4j1相比,log4j2的性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将我的应用迁移到使用log4j2.当前正在使用log4j 1.2.16.我的项目也有一个性能构建,升级到log4j 2后,性能似乎有了很大提高.

I'm trying to migrate my app into using log4j2. It is currently using log4j 1.2.16. I also have a performance build for my project, and after upgrading to log4j 2, the performance seemed to have improve a lot.

也就是说,直到我读到有关桥接的内容为止.根据文档,我必须从类路径中排除log4j1 JAR,并包括桥接JAR-我假设它名为"org.apache.logging.log4j:log4j-1.2-api".一旦完成此操作,性能就会再次下降.

That is, until I read about bridging. According to the doc, I have to exclude log4j1 JAR from the classpath, and include the bridging JAR - which I assume is named 'org.apache.logging.log4j:log4j-1.2-api'. Once I did this, performance dropped again.

总结一下:

  1. 使用log4j2 +桥接jar + log4j-1.2-api + log4j1的性能:很好
  2. log4j2 +桥接jar + log4j-1.2-api的性能:很差(以至于性能下降到仅log4j1的程度)

我已经检查过log4j-1.2-api在类路径中是否更早.因此,应该先加载它.

I have checked that the log4j-1.2-api is earlier in the classpath. So it should have been loaded first.

任何想法会导致此问题吗?

Any idea what could cause this problem?

非常感谢您!

哦,我用于记录的完整类路径是:

Oh my complete classpath for logging are:

  • org.slf4j:slf4j-api
  • org.slf4j:log4j-over-slf4j
  • org.slf4j:jcl-over-slf4j
  • org.apache.logging.log4j:log4j-slf4j-impl
  • org.apache.logging.log4j:log4j-core
  • org.apache.logging.log4j:log4j-api
  • org.apache.logging.log4j:log4j-1.2-api
  • log4j:log4j(如上所述,带&不带)

版本:

  • Log4j2:2.6.2
  • slf4j:1.7.20
  • log4j1:1.2.16

我的配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration
        xmlns:xi="http://www.w3.org/2001/XInclude">

    <xi:include href="log4j2-xinclude-appenders.xml" />

    <Loggers>

        <Root level="info">
            <AppenderRef ref="rollingFileAppender"/>
            <AppenderRef ref="stdOutAppender"/>
        </Root>
    </Loggers>
</Configuration>

log4j2-xinclude-appenders.xml看起来像:

And the log4j2-xinclude-appenders.xml looks like:

<?xml version="1.0" encoding="UTF-8"?>
<appenders>
    <RollingRandomAccessFile name="_rollingFileAppender" fileName="./logs/foo-${sys:app.name.suffix}.log"
                 filePattern="./logs/foo-${sys:foo.app.name.suffix}.log.%i">
        <PatternLayout>
            <Pattern>%d|%X{active.profiles}| %-5p |%X{fcp.session}|%X{StateMachine.key}|%X{StateMachine.currentState}| %m | %t | %c{1.}%n</Pattern>
        </PatternLayout>
        <Policies>
            <OnStartupTriggeringPolicy minSize="0" />
            <SizeBasedTriggeringPolicy size="100 MB" />
        </Policies>
        <DefaultRolloverStrategy max="10"/>
    </RollingRandomAccessFile>

    <Async name="rollingFileAppender" blocking="false" bufferSize="10000">
        <AppenderRef ref="_rollingFileAppender"/>
    </Async>

    <Console  name="_stdOutAppender" target="SYSTEM_OUT">
        <PatternLayout pattern="%d|%X{active.profiles}| %-5p |%X{fcp.session}|%X{StateMachine.key}|%X{StateMachine.currentState}| %m | %t | %c{1.}%n"/>
    </Console>     
    <Async name="stdOutAppender" blocking="false" bufferSize="10000">
        <AppenderRef ref="_stdOutAppender"/>
    </Async>
</appenders>

编辑:这是包含在类路径中的log4j 1 xml文件

This is the log4j 1 xml file that gets included in the classpath

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration debug="false" xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="A1" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n"/>
        </layout>
    </appender>

    <appender name="R" class="com.bar.common.util.RollingFileAppender">
        <param name="File" value="./logs/bar.log"/>
        <param name="MaxFileSize" value="100MB"/>
        <param name="MaxBackupIndex" value="10"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n"/>
        </layout>
    </appender>

    <!-- Performance Appender -->
    <appender name="OneSecondStatsAppender"
              class="com.foo.perf.AggregatedStatisticsAppender">
        <param name="TimeSlice" value="1000"/>
        <appender-ref ref="OneSecondStatsLogger"/>
    </appender>
    <appender name="FiveMinuteStatsAppender"
              class="com.bar.perf.DatafabricAggregatedStatisticsAppender">
        <param name="TimeSlice" value="300000"/>
        <appender-ref ref="FiveMinuteStatsLogger"/>
    </appender>

    <!-- Aggregated Performance Statistics Appender -->
    <appender name="OneSecondStatsLogger" class="org.apache.log4j.FileAppender">
        <param name="File" value="./logs/bar-performance.log"/>
        <layout class="com.bar.perf.AggregatedStatisticsCsvLayout"/>
        <filter class="com.bar.perf.CategorisedStatisticExclusionFilter"/>
    </appender>
    <appender name="FiveMinuteStatsLogger" class="org.apache.log4j.FileAppender">
        <param name="File" value="./logs/bar-minutes.log"/>
        <layout class="com.bar.perf.AggregatedStatisticsCsvLayout">
            <param name="ShowEmptyStatistics" value="true"/>
        </layout>
    </appender>

    <!-- Loggers -->
    <logger name="org.perf4j.TimingLogger" additivity="false">
        <level value="INFO"/>
        <appender-ref ref="OneSecondStatsAppender"/>
        <appender-ref ref="FiveMinuteStatsAppender"/>
    </logger>

    <logger name="com.bar">
        <level value="INFO"/>
    </logger>

    <logger name="com.gemstone.gemfire">
        <level value="INFO"/>
    </logger>

    <logger name="org.springframework.data">
        <level value="INFO"/>
    </logger>

    <!-- Root logger configuration -->
    <root>
        <priority value="INFO"/>
        <appender-ref ref="R"/>
    </root>

</log4j:configuration>

编辑2 : 糟糕的类路径顺序:

EDIT 2: Classpath order for poor performance:

log4j-1.2-api-2.6.2.jar
jcl-over-slf4j-1.7.20.jar
slf4j-api-1.7.20.jar
log4j-slf4j-impl-2.6.2.jar
log4j-core-2.6.2.jar
log4j-api-2.6.2.jar
log4j-1.2.16.jar

Classpath顺序以获得良好的性能

Classpath order for good performance

log4j-1.2-api-2.6.2.jar
jcl-over-slf4j-1.7.20.jar
slf4j-api-1.7.20.jar
log4j-over-slf4j-1.7.20.jar
log4j-slf4j-impl-2.6.2.jar
log4j-core-2.6.2.jar
log4j-api-2.6.2.jar
log4j-1.2.16.jar

推荐答案

我在这里有两个问题:

  1. 为什么在某些类路径配置中使用log4j 1
  2. 为什么log4j 2不快于log4j 1

1.为什么使用log4j 1

我怀疑以下slf4j依赖性导致使用了旧的log4j 1.2:

I suspect that the following slf4j dependencies caused the old log4j 1.2 to be used:

org.slf4j:log4j-over-slf4j
org.slf4j:jcl-over-slf4j

如果您使用maven,即使您未在POM中明确声明它,也可能将旧的Log4j 1引入为传递依赖项.

If you use maven these could bring in the old Log4j 1 as a transitive dependency even if you don't explicitly declare it in your POM.

请删除这些. Log4j 2具有log4j-slf4j-impl和log4j-jcl模块,它们将完成相同的功能,但改用Log4j 2.

Please remove these. Log4j 2 has log4j-slf4j-impl and log4j-jcl modules that will accomplish the same but use Log4j 2 instead.

您不应在类路径中包含Log4j 1.如果您的应用程序(或使用的任何库)依赖于Log4j 1 API,则添加log4j-1.2-api模块.

You should not have Log4j 1 in the classpath. If your application (or any of the libraries you use) depend on the Log4j 1 API, then add the log4j-1.2-api module.

2.为什么log4j 2不快于log4j 1

您描述的配置没有利用log4j 2功能.它使用AsyncAppender(在log4j 1和2中大致等效)和ConsoleAppender(在log4j 2中稍差一些). ConsoleAppender比文件附加器慢60倍.登录生产系统中的控制台时,请格外小心.

The configuration you describe does not take advantage of log4j 2 features. It uses AsyncAppender (which is roughly equivalent in log4j 1 and 2) and ConsoleAppender (which is slightly worse in log4j 2). ConsoleAppender is about 60 times slower than file appender. Be extremely careful when logging to the console in production systems.

这是我的建议:删除以下内容(现在似乎可以提供更好的性能,但是请多多包涵)

Here is what I suggest: remove the following (which now seems to give better performance, but bear with me)

  • log4j-over-slf4j-1.7.20
  • log4j-1.2.16
  • 旧的lo4j.xml配置

添加 LMAX Disruptor依赖项:

Add the LMAX Disruptor dependency:

<!-- https://mvnrepository.com/artifact/com.lmax/disruptor -->
<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.2.0</version>
</dependency>

使用以下log4j2.xml配置.暂时将其简化为一个没有包含文件的简单文件,您可以稍后再放回去. (注意,我在文件的开头添加了<Configuration status="trace":它将输出内部log4j2调试语句,因此您可以确认配置没有问题.)

Use the following log4j2.xml configuration. Temporarily just make it a simple file without includes, you can put that back later. (Notice I added <Configuration status="trace" to the beginning of the file: that will output internal log4j2 debugging statements so you can confirm that configuration completed without problems.)

请注意,我怀疑控制台控制台会记录WARN级别,因为它会影响性能.

Note that I made Console logging WARN level as I suspect it is impacting performance.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="TRACE" xmlns:xi="http://www.w3.org/2001/XInclude">

  <appenders>
    <RollingRandomAccessFile name="_rollingFileAppender" 
                 fileName="./logs/foo-${sys:app.name.suffix}.log"
                 filePattern="./logs/foo-${sys:foo.app.name.suffix}.log.%i">
        <PatternLayout>
            <Pattern>%d|%X{active.profiles}| %-5p |%X{fcp.session}|%X{StateMachine.key}|%X{StateMachine.currentState}| %m | %t | %c{1.}%n</Pattern>
        </PatternLayout>
        <Policies>
            <OnStartupTriggeringPolicy minSize="0" />
            <SizeBasedTriggeringPolicy size="100 MB" />
        </Policies>
        <DefaultRolloverStrategy max="10"/>
    </RollingRandomAccessFile>

    <Console  name="_stdOutAppender" target="SYSTEM_OUT">
        <PatternLayout pattern="%d|%X{active.profiles}| %-5p |%X{fcp.session}|%X{StateMachine.key}|%X{StateMachine.currentState}| %m | %t | %c{1.}%n"/>
    </Console>     
  </appenders>

    <Loggers>
        <Root level="info">
            <AppenderRef ref="_rollingFileAppender"/>
            <AppenderRef ref="_stdOutAppender" level="WARN" />
        </Root>
    </Loggers>
</Configuration>

现在,最后一个(关键)点:启用log4j 2

Now, the final (key) point: enable log4j 2 async loggers by setting system property Log4jContextSelector to org.apache.logging.log4j.core.async.AsyncLoggerContextSelector.

这最后一点应该会带来很大的性能差异. (以及禁用控制台日志记录.)

This last bit should make a large performance difference. (Together with disabling Console logging.)

这篇关于与log4j1相比,log4j2的性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆