Java日志框架性能比较

1 Java日志框架性能比较

前面几章,笔者分别介绍了log4j,logback,log4j2三大日志实现框架。

接下来,就用具体的数据比较下,哪个日志框架的性能更好!

单线程:外循环100次,内循环100000次;

多线程:开启100个线程,每个线程执行100000次;

1.1 测试代码:

(1)log4j:

public class log4jDemo {

    Logger logger = Logger.getLogger(log4jDemo.class);

    @Test
    public void testThread() throws InterruptedException {
        int THREAD_NUM = 100;
        final int LOOP_NUM = 100000;

        final CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM);
        long start = System.currentTimeMillis();
        for(int x= 0;x < THREAD_NUM;x++){
            new Thread(new Runnable() {
                public void run() {
                    for (int y = 0; y < LOOP_NUM; y++) {
                        logger.info("Info Message!");
                    }
                    countDownLatch.countDown();
                }
            }).start();
        }
        countDownLatch.await();
        System.out.println(System.currentTimeMillis() - start);
    }

    @Test
    public void test() throws InterruptedException {
        int X_NUM = 100;
        int Y_NUM = 100000;

        long start = System.currentTimeMillis();
        for(int x=0;x < X_NUM;x++) {
            for (int y = 0; y < Y_NUM; y++) {
                logger.info("Info Message!");
            }
        }
        System.out.print(System.currentTimeMillis() - start);
    }
}

(2)logback:

public class logbackDemo {

    Logger logger =  LoggerFactory.getLogger(logbackDemo.class);

    @Test
    public void testThread() throws InterruptedException {
        int THREAD_NUM = 100;
        final int LOOP_NUM = 100000;

        final CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM);
        long start = System.currentTimeMillis();
        for(int x= 0;x < THREAD_NUM;x++){
            new Thread(new Runnable() {
                public void run() {
                    for (int y = 0; y < LOOP_NUM; y++) {
                        logger.info("Info Message!");
                    }
                    countDownLatch.countDown();
                }
            }).start();
        }
        countDownLatch.await();
        System.out.println(System.currentTimeMillis() - start);
    }

    @Test
    public void test() {
        int X_NUM = 100;
        int Y_NUM = 100000;

        long start = System.currentTimeMillis();
        for(int x=0;x<X_NUM;x++) {
            for (int y = 0; y < Y_NUM; y++) {
                logger.info("Info Message!");
            }
        }
        System.out.print(System.currentTimeMillis()-start);
    }
}

(3)log4j2:

public class log4j2Demo {
    private Logger logger = LogManager.getLogger(log4j2Demo.class);

    @Test
    public void testThread() throws InterruptedException {
        int THREAD_NUM = 100;
        final int LOOP_NUM = 100000;

        final CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM);
        long start = System.currentTimeMillis();
        for(int x= 0;x < THREAD_NUM;x++){
            new Thread(new Runnable() {
                public void run() {
                    for (int y = 0; y < LOOP_NUM; y++) {
                        logger.info("Info Message!");
                    }
                    countDownLatch.countDown();
                }
            }).start();
        }
        countDownLatch.await();
        System.out.println(System.currentTimeMillis() - start);
    }
    
    @Test
    public void test() throws InterruptedException {
        int X_NUM = 100;
        int Y_NUM = 100000;

        long start = System.currentTimeMillis();
        for(int x=0;x<X_NUM;x++) {
            for (int y = 0; y < Y_NUM; y++) {
                logger.info("Info Message!");
            }
        }
        System.out.print(System.currentTimeMillis() - start);
    }
}

1.2 配置文件:

(1)log4j:

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

    <!--无缓存,立即输出-->
    <appender name="FILE" class="org.apache.log4j.FileAppender">
        <param name="File" value="e:/log.out" />
        <param name="append" value="true"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %p %c - %m%n" />
        </layout>
    </appender>

    <!--有缓存,不立即输出-->
    <appender name="FILE" class="org.apache.log4j.FileAppender">
        <param name="File" value="e:/log.out" />
        <param name="append" value="true"/>
        <param name="immediateFlush" value="false"/>
        <param name="bufferedIO" value="true"/>
        <param name="bufferSize" value="8192"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %p %c - %m%n" />
        </layout>
    </appender>

    <!--异步appender-->
    <appender name="AsyncAppender" class="org.apache.log4j.AsyncAppender">
        <appender-ref ref="FILE"/>
    </appender>

    <root>
        <priority value="info" />
        <appender-ref ref="FILE" />
        <appender-ref ref="AsyncAppender" />
    </root>
</log4j:configuration>

(2)logback:

<configuration >

    <!--无缓存,立即输出-->
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>e:/log.out</file>
        <append>true</append>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %p %c - %m%n</pattern>
        </encoder>
    </appender>

    <!--有缓存,不立即输出-->
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>e:/log.out</file>
        <append>true</append>
        <immediateFlush>false</immediateFlush>
        <bufferSize>8192</bufferSize>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %p %c - %m%n</pattern>
        </encoder>
    </appender>

    <!--异步appender-->
    <appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">  
        <discardingThreshold>0</discardingThreshold>  
        <queueSize>128</queueSize>  
        <appender-ref ref ="FILE"/>  
    </appender>  
    
    <root level="info">
        <appender-ref ref="ASYNC" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

(3)log4j2:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" monitorInterval="30">
    <Appenders>

        <!--无缓存,立即输出-->
       <File name="File" fileName="e:/log.out" append="true">
            <<PatternLayout>
                <Pattern>%d{HH:mm:ss.SSS} %p %c - %m%n</Pattern>
            </PatternLayout>
        </File>

        <!--有缓存,不立即输出-->
        <File name="File" fileName="e:/log.out" append="true"
              immediateFlush="false" bufferedIO="true" bufferSize="8192">
            <PatternLayout>
                <Pattern>%d{HH:mm:ss.SSS} %p %c - %m%n</Pattern>
            </PatternLayout>
        </File>

       <!--异步appender-->
        <Async name="Async">
            <AppenderRef ref="File"/>
        </Async>
    </Appenders>
    <Loggers>
        <Root level="info" >
            <AppenderRef ref="Async"/>
            <AppenderRef ref="File"/>
        </Root>
        <!--异步logger-->
        <AsyncRoot level="info" >
            <AppenderRef ref="File"/>
        </AsyncRoot>
    </Loggers>
</Configuration>

1.3 结果比较(毫秒)

笔者从单线程、多线程2种情况下进行的测试!

无论是多线程还是单线程,在启用缓存的情况下,系统性能得到了巨大的提升;

在单线程情况下,相比较来说,启用异步Appender并没有对性能有较大的提升!

值得一提的是,在log4j2中,多线程情况下,相对于同步logger来说,异步logger并没有进一步提高系统的性能,两者不相上下;

但是,对于其他情况而言,异步logger还是有较大的提升!

  • 单线程

      (1)单线程,未开启缓存,立即刷出
      
          log4j:29772、29959、30911
          
          logback:25423、24552、26006
          
          log4j2:37927、38240、40164
      
      (2)单线程,开启缓存,不立即刷出
      
          log4j:9858、9677、9665
          
          logback:5561、5604、5611
          
          log4j2:5782、5505、5499
      
      (3)单线程,异步appender,未开启缓存,立即输出
      
          log4j:29683、29929、29385
          
          logback:33102、31779、30516
          
          log4j2:39298、39562、41872
      
      (4)单线程,异步appender,开启缓存,不立即输出
      
          log4j:10110、10068、10177
          
          logback:8753、9112、8922
          
          log4j2:8692、8400、8252
    
  • 多线程

      (1)多线程,未开启缓存,立即刷出
    
          log4j:38541、37791、38366
      
          logback:35644、35463、35442
          
          log4j2:38544、38746、38706
      
      (2)多线程,开启缓存,不立即刷出
    
          log4j:13296、12938、12686
          
          logback:6547、6294、6576
          
          log4j2:5596、5423、5421
      
      (3)多线程,异步appender,未开启缓存,立即输出
    
          log4j:30844、32088、30734
          
          logback:44203、42191、43228
          
          log4j2:46804、46034、46232
      
      (4)多线程,异步appender,开启缓存,不立即输出
    
          log4j:10422、10204、10495
          
          logback:40249、40437、40173
          
          log4j2:7832、8447、8660
    
      (5)多线程,异步logger,未开启缓存,立即输出
    
          log4j2:40555、40245、40325
      
      
      (6)多线程,异步logger,开启缓存,不立即刷出
    
          log4j2:5319、5407、5305
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容

  • [TOC] Java 日志框架解析:设计模式、性能 在平常的系统开发中,日志起到了重要的作用,日志写得好对于线上问...
    albon阅读 3,930评论 1 8
  • log4j 1.1 简介 Log4j是一个由Java编写可靠、灵活的日志框架,是Apache旗下的一个开源项目;现...
    贾博岩阅读 7,775评论 1 31
  • 在应用程序中添加日志记录总的来说基于三个目的:监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析...
    时待吾阅读 4,817评论 1 13
  • 在应用程序中添加日志记录总的来说基于三个目的:监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析...
    时待吾阅读 4,904评论 0 6
  • 这是在公司内部的一次升级实践,删除了很多隐私的内容,所以可能不是很完整。 1、背景 在任何系统中,日志都是非常重要...
    高广超阅读 10,153评论 2 35