log4j2 高性能

原创: http://www.imet.me/post/2018/07-18_log4j2_high_performance/

开篇词

log4j2 日志性能在某些场景下要优于 logback 等其他日志组件,带来了非常大的性能提升,究竟有多大呢?

这几个新的特性如下:

高性能的几个表现对比 (High performance)

1. 日志组件之间的对比

结论:log4j2 all async 胜出,异步是同步的6-10倍

主要得益于:

Logging Library Performance Comparison

(refer: log4j2 performance)

2. 异步日志场景下是否记录调用栈

结论:不记录相关的 class, line num 这些信息的话,性能有 30~100 的提升

如果日志 pattern 中打印以下信息的话: %C or $class, %F or %file, %l or %location, %L or %line, %M or %method
将会极大的影响日志的性能,日志组件需要打印当前栈的快照,遍历 stack trace 然后找到 location 等相关信息

Asynchronous Logging with Caller Location Information

(refer: log4j2 performance)

3. 同步场景下 garbage free

大部分情况下 garbage free 的性能要优

sync log compare

(refer: log4j2 performance, garbagefree)

log4j2 相关的配置

maven pom 相关的配置

.pom.xml

  <dependencies>
    <!-- 日志门面 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>

    <!-- log4j2 作为 slf4j 的实现 -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.10.0</version>
    </dependency>

    <!-- log4j2 核心 jar -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.10.0</version>
    </dependency>

    <!-- log4j2 核心 jar -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.10.0</version>
    </dependency>

    <!-- 将老版本的 log4j 1.2 升级到 log4j2  -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-1.2-api</artifactId>
        <version>2.10.0</version>
    </dependency>

    <!--&lt;!&ndash; log4j2 jul 的实现  &ndash;&gt;-->
    <!--<dependency>-->
        <!--<groupId>org.apache.logging.log4j</groupId>-->
        <!--<artifactId>log4j-jul</artifactId>-->
        <!--<version>2.10.0</version>-->
    <!--</dependency>-->

    <!-- 使用log4j2的AsyncLogger需要包含disruptor -->
    <dependency>
        <groupId>com.lmax</groupId>
        <artifactId>disruptor</artifactId>
        <version>3.3.7</version>
    </dependency>

    <!-- 需要再把其他依赖里面的 slf4j implement 给排除掉,已经依赖的实现日志包 -->
    <dependency>
      <groupId>xxx</groupId>
      <artifactId>xxx-yy</artifactId>
      <version>zz</version>
      <exclusions>
        <exclusion>
            <artifactId>slf4j-log4j12</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
        <exclusion>
            <artifactId>log4j</artifactId>
            <groupId>log4j</groupId>
        </exclusion>
      </exclusions>
    </dependency>

  </dependencies>

log4j2 日志相关的配置

.log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Properties>
        <Property name="LOG_HOME">./logs</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%level [%date{HH:mm:ss.SSS}][%thread][%class][%line]:%message%n"/>
        </Console>

        <RollingRandomAccessFile name="infoLog" fileName="${LOG_HOME}/info.log"
                                 filePattern="${LOG_HOME}/info.%d{yyyy-MM-dd}.log.gz" immediateFlush="false" append="true">
            <PatternLayout pattern="[%X][%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread][%level]:%message%n"/>
            <Filters>
                <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
                <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingRandomAccessFile>
        <RollingRandomAccessFile name="warnLog" fileName="${LOG_HOME}/warn.log"
                                 filePattern="${LOG_HOME}/warn.%d{yyyy-MM-dd}.log.gz" immediateFlush="false" append="true">
            <Filters>
                <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="[%X][%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread][%level][%class][%line]:%message%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingRandomAccessFile>
        <RollingRandomAccessFile name="errorLog" fileName="${LOG_HOME}/error.log"
                                 filePattern="${LOG_HOME}/error.%d{yyyy-MM-dd}.log.gz" immediateFlush="false" append="true">
            <Filters>
                <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="[%X][%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread][%level][%class][%line]:%message%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingRandomAccessFile>

    </Appenders>

    <Loggers>

        <!-- 指定相关的 logger name 的日志级别 -->
        <logger name="org.springframework" level="info" additivity="false">
            <appender-ref ref="infoLog"/>
            <appender-ref ref="warnLog"/>
            <appender-ref ref="errorLog"/>
        </logger>

        <!-- 剩余其他的日志级别 -->
        <Root level="warn" includeLocation="true">
            <appender-ref ref="infoLog"/>
            <appender-ref ref="warnLog"/>
            <appender-ref ref="errorLog"/>
        </Root>

    </Loggers>

</Configuration>

.log4j2.component.properties

# 设置全异步的打日志方式, 就不需要在命令行加 -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector 参数了
log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
# size = 1024 * 1024
log4j2.asyncLoggerRingBufferSize=1048576
# discard not to block the queue
log4j2.asyncQueueFullPolicy=Discard
# 默认是在 INFO 级别去 discard
log4j2.discardThreshold=INFO

参考

  1. csdn blog: java日志组件介绍(common-logging,log4j,slf4j,logback )
  2. 简书: 该让log4j退休了 - 论Java日志组件的选择
  3. 网易lede: 日志工具现状调研
  4. 网易lede: Log4j 2.x 日志升级的详细流程(针对各种混合使用Log4j 1.x,Logback,JCL,JUL等)
  5. log4j2 runtime-dependencies: log4j2 相关 jar 及依赖关系
  6. log4j2 async: Asynchronous Loggers
  7. log4j2 performance: log4j2 performance
  8. log4j2 garbagefree: garbagefree
  9. lock-free by disruptor: lock-free data structure
  10. log4j 配置文件: log4j2 configuration
  11. log4j2异步注意事项
  12. log4j2性能剖析
  13. log4j2异步Logger
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值