Log4j1升级Log4j2实战

这是在公司内部的一次升级实践,删除了很多隐私的内容,所以可能不是很完整。

1、背景

在任何系统中,日志都是非常重要的组成部分,它是反映系统运行情况的重要依据,也是排查问题时的必要线索。绝大多数人都认可日志的重要性,但是又有多少人仔细想过该怎么打日志,日志对性能的影响究竟有多大呢?

新的Log4j 2.0版本有了大幅的性能提升、新的插件系统,以及配置设置方面的很多改善。Log4j 1.x 在高并发情况下出现死锁导致cpu使用率异常飙升,而Log4j2.0基于LMAX Disruptor的异步日志在多线程环境下性能会远远优于Log4j 1.x和logback ——官方测试结果。

本次升级是以thrift服务化项目为例子进行的,后续会在其他项目中进行,本次工作内容为:Log4j1.x 升级到 Log4j2(如果不想了解原理,可以直接跳到:3、升级方式)

2、log4j2说明

2.1 特性

  • API分离: Log4j2将API与实现分离开来(log4j-api: 作为日志接口层,用于统一底层日志系统,log4j-core : 作为上述日志接口的实现,是一个实际的日志框架)
  • 改进的特定: Log4j2的性能在某些关键领域比Log4j 1.x更快,而且大多数情况下与Logback相当。
  • 多个API支持:Log4j2提供最棒的性能的同时,还支持SLF4J和公共日志记录API。
  • 自动配置加载:像Logback一样,一旦配置发生改变,Log4j2可以自动载入这些更改后的配置信息,又与Logback不同,配置发生改变时不会丢失任何日志事件。
  • 高级过滤功能:与Logback类似,Log4j2可以支持基于上下文数据、标记,正则表达式以及日志事件中的其他组件的过滤。
  • 插件架构:所有可以配置的组件都以Log4j插件的形式来定义。无需修改任何Log4j代码就可以创建新的Appender、Layout、Pattern Convert 等等。Log4j自动识别预定义的插件,如果在配置中引用到这些插件,Log4j就自动载入使用。
  • 属性支持:属性可以在配置文件中引用,也可以直接替代或传入潜在的组件,属性在这些组件中能够动态解析。属性可以是配置文件,系统属性,环境变量,线程上下文映射以及事件中的数据中定义的值。用户可以通过增加自己的Lookup插件来定制自己的属性。
  • log4j2配置: 不支持properties文件,但却可以以json文件作为配置

2.2 性能

吞吐量测试

平均耗时

其中:

Loggers mixed sync/async: 同步与异步logger可以混合使用,分别由标签 指定
异步Logger与异步Appender区别:AsyncAppender使用ArrayBlockingQueue来处理message,AsyncLogger使用LMAX Disruptor
* AsyncAppender的做法是:应用线程创建LogEvent将其塞入Queue,消费线程取出LogEvent写磁盘。在这种框架的可扩展性不好,当加倍消费线程时各个线程的吞吐量会减半,所以总吞吐量并不会得到增加。原因是,并发queue是标准java库的一部分,会使用锁来保证数据传递的正确性。
* LMAX Disruptor是一个无锁数据结构,可以在线程间传递消息。详细介绍可访问其网站:https://github.com/LMAX-Exchange/disruptor/wiki/Introduction

更多性能测试信息可参考官方报告:
http://logging.apache.org/log4j/2.x/manual/async.html#Performance
http://logging.apache.org/log4j/2.x/performance.html

2.3 主要组件

2.4 配置

Configuration

示例:


<Configuration>

    <Properties>
        <Property name="pattern_layout">%d %-5p (%F:%L) - %m%nProperty>
        <Property name="LOG_HOME">/var/***/logsProperty>
    Properties>

    <Appenders>
        <Console name="console" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="${pattern_layout}"/>
        Console>

        <RollingRandomAccessFile name="file"
                                 fileName="${LOG_HOME}/${sys:app.key}.log"
                                 filePattern="${LOG_HOME}/${sys:app.key}.log.%d{yyyy-MM-dd}">
            <PatternLayout pattern="${pattern_layout}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
            Policies>
        RollingRandomAccessFile>

        <RollingRandomAccessFile name="access_kpi"
                                 fileName="${LOG_HOME}/${sys:app.key}_access_kpi.log"
                                 filePattern="${LOG_HOME}/${sys:app.key}_access_kpi.log.%d{yyyy-MM-dd}">
            <PatternLayout pattern="${pattern_layout}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
            Policies>
        

你可能感兴趣的:(Java,coding,log4j,性能)