`
daimojingdeyu
  • 浏览: 271978 次
  • 性别: Icon_minigender_1
  • 来自: 山东
社区版块
存档分类
最新评论

log4j真的比JDK logger快吗?

    博客分类:
  • Java
阅读更多

这里不想比较这两个日志哪个功能更强,或者是哪个更好用,只是网上说log4j的性能很高想通过自已的方式验证一下。

 

那log4j的性能如果真的高的话,在同等条件下,它究竟比jdk内置的logger快多少呢?这里只比较最常用的文件日志写入速度。

 

最主要是就是这里想不明白,为什么log4j的性能会高呢,log4j的包中并没有包含非java的东东,也就是说没有看到它使用JNI,所以说这里就不太好理解啦,同样使用java的东东,log4j怎么做到比jdk logger快。因为想不明白,所以决定测试一下。

 

刚刚开始时由于对这两个日志实现方式不是太理解,所以走了些弯路,像日志格式没有统一、打印日志分别输出到终端和文件里等等,这里就不再详述,反正过程是痛苦的。

 

测试前期条件为:

1、日志只输出到文件

2、文件的最大大小为1024KB

3、备份文件最多为4个

4、打印消息中没有额外的信息,只是用户打印输出信息,信息写入文件后换行

 

为满足上面的条件,log4j使用如下的配置文件(红色部分为满足上面配置的条件)

log4j.properties 写道
log4j.rootLogger=info, R

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=log4j/example.log
log4j.appender.R.MaxFileSize= 1024KB
log4j.appender.R.MaxBackupIndex=4

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%m%n

 

让jdk logger满足上面的条件则在复杂一些,因为jdk的logger没有提供相应的打印输出控制,刚开始想使用java.util.logging.SimpleFormatter来的,但后来发现这个类有明显的性能问题,因为这个格式化输出类每次都会输出打印日志的类名及调用方法名,通过查看jdk LogRecord类的源码,发现通过如下方式实现:

StackTraceElement stack[] = (new Throwable()).getStackTrace();

 也就是说通过异常类获取当前栈信息,再从栈信息中取到调用日志打印的类及该类中的方法。异常处理的开销应该是比较大的,所以说jdk的SimpleFormatter在日志处理上会比较慢。

 

既然不能使用SimpleFormatter类,那我们就重新写一个简单的满足上面测试条件的日志格式化类,如下:

 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jdklog;

import java.util.logging.Formatter;
import java.util.logging.LogRecord;

/**
 *
 * @author Administrator
 */
public class MyFormatter extends Formatter{
    
    @Override
    public String format(LogRecord record) {
        StringBuilder b = new StringBuilder();
        b.append(record.getMessage());
        b.append('\n');
        return b.toString();
    }
}

 这个搞好了,还需要关闭jdk logger的终端输出并指定其日志格式化为上面写好的MyFormatter类。这个可以通过修改jre/lib下的logging.properties类完成,我使用的是jdk1.6,修改后的文件像下面这样

jre/lib/logging.properties 写道
handlers= java.util.logging.FileHandler

# Default global logging level.
.level= INFO

# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 1048576
java.util.logging.FileHandler.count = 4
java.util.logging.FileHandler.formatter = jdklog.MyFormatter

 因为jdk的大小是按byte算的,所以1024KB=1024*1024byte=1048576,另外我们使用的日志格式化类修改成了新写的MyFormatter类。

 

日志测试时均使用下面的代码进行日志输出:

   for (int i = 0 ; i < Main.MAXSIZE; i++)
        {
            logger.info("This is the " + i + " record");
        }

 

测试结果为:

1万条以下,两者时间基本相同

1~5万条,log4j要较jdk logger快20~50ms

10~100万条,log4j要较jdk logger快100~200ms

200万条时,log4j要较jdk logger快1s

 

总的来说,log4j的性能是要高一些,但是在100万条数据以下优势是不太明显的,而且测试是在循环中调用日志打印的,但是实际情况下应该不会有像上面测试这种短时间内200万条日志写入文件的情况吧?能达到1万条就很多了吧?

 

所以我觉得log4j在性能上是比jdk logger强些,但是相差应该不太,不会成为系统的性能瓶颈。

 

选择哪个还是看用户自己的喜好吧~~~

分享到:
评论
25 楼 a123159521 2012-11-06  
对于轻量级的应用,使用jdk的日志系统够用了,不需要引入额外的jar.
24 楼 hisdonkey 2009-10-15  
ray_linn 写道
walle1027 写道
log4j最大的缺点在于它是静态的,不能通过被注入,如果我想集成写log得老老实实的这样写Log log = LogFactory.getLog(getClass()),很苦闷



有点搞笑了...连上个厕所是否都要注入额?


差点没笑岔气...
23 楼 java.lang.Object 2009-09-28  
zhishuren 写道

这是什么小怪物 ???

这是吉祥物,不是怪物
22 楼 zhishuren 2009-09-27  

这是什么小怪物 ???
21 楼 夜里事挺多 2009-09-24  
lcllcl987 写道
所谓log的性能, 在鄙人看来就是对程序本身几乎没有影响,就是最大的性能。
而不是写log是1ms还是10ms

你能给出一个有影响的吗?
20 楼 清晨阳光 2009-09-24  
貌似现在好多开源项目迁移到slf4j上了,log4j的后续之作叫做:logback
19 楼 bohemia 2009-09-24  
香克斯 写道
bohemia 写道
lcllcl987 写道
所谓log的性能, 在鄙人看来就是对程序本身几乎没有影响,就是最大的性能。
而不是写log是1ms还是10ms


不同人看法不同吧。
如你所说,性能必须是可量化的才是可测量的。 所以数字更能说明问题。
如果同样的环境下,log从10ms到1ms。就意味着有提升。

另外,你提到的最大的性能。我没见到过。任何日志记录实现(只要是消耗CPU的),就不会“几乎没有影响”。


他说的没错啊,其实很多系统中,log的性能就看它对现有系统是不是有影响,特别是那种log很多的系统,异步的log输出是非常有用的,所谓对cpu的影响,只想说对于现在的硬件来说,基本是没影响.并且现在多数的系统其实对cpu的要求都不算高,性能问题主要都出现在io(数据库,硬盘读写)上.

是啊。性能问题。
前段时间,专门做日志输出的性能优化。
从文件,到异步,到JMS,Socket都快尝试变了。
但各种方式比较下来,变化提升不大。

尤其log4j的AsynAppender,这个你看了源代码就知道的。都是做并发控制的。并发的情况下,性能表现并不会提升。
18 楼 香克斯 2009-09-23  
bohemia 写道
lcllcl987 写道
所谓log的性能, 在鄙人看来就是对程序本身几乎没有影响,就是最大的性能。
而不是写log是1ms还是10ms


不同人看法不同吧。
如你所说,性能必须是可量化的才是可测量的。 所以数字更能说明问题。
如果同样的环境下,log从10ms到1ms。就意味着有提升。

另外,你提到的最大的性能。我没见到过。任何日志记录实现(只要是消耗CPU的),就不会“几乎没有影响”。


他说的没错啊,其实很多系统中,log的性能就看它对现有系统是不是有影响,特别是那种log很多的系统,异步的log输出是非常有用的,所谓对cpu的影响,只想说对于现在的硬件来说,基本是没影响.并且现在多数的系统其实对cpu的要求都不算高,性能问题主要都出现在io(数据库,硬盘读写)上.
17 楼 macadam 2009-09-23  
xieyongwei 写道
呵呵  以前一直想说的一句话
ray_linn 这个人的说话风格太符合他的头像了
也许正是这种风格而选择了这种头像吧

一般也不太会注意头像,不知道为什么他的头像特别显眼。



一般不太会注意头像  恐怕原因是很多人都没有头像..

16 楼 bohemia 2009-09-23  
lcllcl987 写道
所谓log的性能, 在鄙人看来就是对程序本身几乎没有影响,就是最大的性能。
而不是写log是1ms还是10ms


不同人看法不同吧。
如你所说,性能必须是可量化的才是可测量的。 所以数字更能说明问题。
如果同样的环境下,log从10ms到1ms。就意味着有提升。

另外,你提到的最大的性能。我没见到过。任何日志记录实现(只要是消耗CPU的),就不会“几乎没有影响”。
15 楼 lcllcl987 2009-09-23  
所谓log的性能, 在鄙人看来就是对程序本身几乎没有影响,就是最大的性能。
而不是写log是1ms还是10ms
14 楼 bohemia 2009-09-23  
回楼上。
我本地的前段时间测试的数据依据不在了。
不过JE上有位同学也有一些数据。
http://littcai.iteye.com/blog/316605

13 楼 lcllcl987 2009-09-23  
bohemia 写道
lcllcl987 写道
我只想说一句:
log4j可以设置异步打印(org.apache.log4j.AsyncAppender,要提升性能, 请试一下这个), 可以支持log格式为html格式,可以把log配置打印到数据库...


这个异步,一般情况下并不能提高多少效率。
当并发线程很多的时候,线程的同步也是很大的消耗。并不会提高很多。

你说的,正是异步打印log的原因。
和你说话, 感觉毫无逻辑可言。是否提高效率,那是靠数字说话的。
12 楼 xieyongwei 2009-09-23  
呵呵  以前一直想说的一句话
ray_linn 这个人的说话风格太符合他的头像了
也许正是这种风格而选择了这种头像吧

一般也不太会注意头像,不知道为什么他的头像特别显眼。
11 楼 flyfan 2009-09-23  
如果争论这个的话,不如用logback,更快
10 楼 bohemia 2009-09-23  
lcllcl987 写道
我只想说一句:
log4j可以设置异步打印(org.apache.log4j.AsyncAppender,要提升性能, 请试一下这个), 可以支持log格式为html格式,可以把log配置打印到数据库...


这个异步,一般情况下并不能提高多少效率。
当并发线程很多的时候,线程的同步也是很大的消耗。并不会提高很多。
9 楼 lcllcl987 2009-09-23  
我只想说一句:
log4j可以设置异步打印(org.apache.log4j.AsyncAppender,要提升性能, 请试一下这个), 可以支持log格式为html格式,可以把log配置打印到数据库...
8 楼 saltfish 2009-09-23  
楼主的精神值得学习
四楼的思维不要被禁锢了,我们使用一个框架有时候只需要使用它对我们开发或者思想带来好处的东西,不能生搬硬套
7 楼 daimojingdeyu 2009-09-22  
大家的思维有点发散呀,我做这个测试的主要目的是测试log4j和jdk logger之间的性能差距究竟有多大,因我想既然都是用纯java写的,性能应该差别不大。
至于两个哪个好用应该有好多文章表扬过log4j了,嘿嘿~~~
不过jdk logger也有一些可取地方,像它自带的格式化输出会打印出调用的函数和方法,这个功能虽然有些性能的损失,但是感觉这个挺有用的,和log4j的%F %L有得一拼~~~
6 楼 youngJiang 2009-09-22  
ray_linn 写道
walle1027 写道
log4j最大的缺点在于它是静态的,不能通过被注入,如果我想集成写log得老老实实的这样写Log log = LogFactory.getLog(getClass()),很苦闷



有点搞笑了...连上个厕所是否都要注入额?

引入注入的目的是为了分离关注点和解除依赖,为什么要在log中注入哪,可以在你的业务逻辑中

相关推荐

    Apache Log4j_1.2.17 完整依赖包

    Apache Log4j_1.2.17 完整依赖包,在jdk1.8.201中测试通过。使用教程https://www.tutorialspoint.com/springmvc/springmvc_log4j.htm

    Java Log4j所需Jar包

    Java Log4j 1,2 所需Jar...用于日志记录的技术很多,如 jdk 的 logger 技术,apache 的 log4j、log4j2 技术等。 Log4j 的全称为 Log for java,即,专门用于 java 语言的日志记录工具。其目前有两个版 本:Log4j 与 Log4j2。

    log4j使用例子和文档

    log4j使用,这个里面包含了一个例子,一个文档,例子里面既介绍了jdk中的Logger又有Log4j的例子,而文档则是全部介绍的Log4j的使用的,非常全面,值得一看。

    java-color-loggers:用于log4j和jdk的颜色控制台日志记录

    用于log4j和jdk的颜色控制台日志记录 用法 从下载最新的颜色记录器jar或自行构建 下载可选,请参见下文( jansi-1.18是此时的最新版本,但我没什么花哨的东西,所以我不希望其他版本感到惊讶) 确保上面提到的jar...

    Log4j配置使用

    所以单独的slf4j是不能工作的,必须搭配其他具体的日志实现方案,比如 apache 的 org.apache.log4j.Logger,JDK 自带的 java.util.logging.Logger 以及 log4j 等 POM org.slf4j slf4j-log4j12 1.7.25 log4j....

    eclipse/myeclipse log4e 插件 2.0.0 pro

    What is Log4E? Since version 2.0.0 Log4E is free now! Log4E is a free Eclipse Plugin which helps you to use your ... It has active support for Log4j, Log4j 2, SLF4J, Commons Logging and JDK 1.4 logging.

    java swing用Logger输出错误日志.docx

    java swing用Logger输出错误日志

    Log4j日志体系结构

    我们在写日志的时候首先要获取logger,在每一个使用log4j的项目都有很多个地方要获取logger,这些logger是真实的被实例化的Logger对象,他们有可能被分散在无数不同的类中,日志体系结构讲的是这些logger对象是如何...

    JdkLoggerUtils.java

    * 封装了日志输出的的各种方法,本类模仿了log4j的输出格式,定义 * 了1、日志输出到控制台,2、日志输出到文件,3、日志发送邮件, * 4、日志存入数据库,5、 日志发送邮件并存入库,6、日志发送邮件和输出到...

    commons-logging-1.1.3.jar

    用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库。当然,common-logging内部有一个Simple logger的...

    java.util.logging.Logger使用详解

    详细介绍了java.util.logging.Logger的用法和结构,对如果扩展Logger起到抛砖引玉的作用!尊重劳动成果,亲下载了要给个评价!

    commons-logging.jra包

    在 sun 开发 logger 前,apache 项目已经开发了功能强大的 log4j 日志工具,并向 sun 推荐将其纳入到 jdk 的一部分,可是 sun 拒绝了 apache 的提议,sun 后来自己开发了一套记录日志的工具。可是现在的开源项目都...

    JFinal所需的Jar

    14:log4j-1.2.16.jar 支持 log4j 日志,当此文件不存在时,自动切换至 JDK Logger, 注意,log4j需要相应的配置文件 log4j.properties,否则当log4j-1.2.16.jar 存在 而log4j.properties 不存在时无日志输出。jdk...

    Logback所需的jar包

    logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging。() logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能。...

    jexcelapi_2_6_12.zip

    Java Excel API—用于读取、写入和修改Excel电子表格的Java API JExcelApi Java Excel API是一个成熟的开放源码Java API,允许开发...支持使用Jakarta Commons logging、log4j、JDK 1.4 Logger等进行日志记录 更多...

    J2EE--Log日志

    Log日志:主要用于记录程序运行的情况,以便于程序在部署之后的排错调试等等!也有利于将这些信息进行持久化(如果不将日志信息保存到文件或数据库,则信息便会丢失) Java Logging API 需JDK1.4版本以上才能支持。...

    短信猫西门子TC35测试

    1、如果报了如下错误: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger 那是因为没有把log4j-1.2.13.jar倒入到工程中。 2、如果报了如下错误: org.smslib.GatewayException:...

    LBLogger java日志记录信息

    java已经有很多的logger jar,但是使用和配置起来都存在一定复杂性,不适合程序的调试和开发 本人在实际的工作根据实际需要提供以下简便的...建议大家使用 nsf4j 加 log4j,我算是重复发明轮子了。供大家学习吧!

    commons-logging-1.0.3.jar

    用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库。当然,common-logging内部有一个Simple logger的...

    《程序天下:J2EE整合详解与典型案例》光盘源码

    6.2 建立Log4j的开发环境 6.2.1 下载Log4j 6.2.2 配置Log4j 6.3 Log4j的使用方法 6.3.1 配置Log4j 6.3.2 配置根Logger 6.3.3 指定日志输出位置 6.3.4 指定日志输出格式 6.3.5 指定日志输出优先级 6.3.6 在代码中使用...

Global site tag (gtag.js) - Google Analytics