`
daimojingdeyu
  • 浏览: 274888 次
  • 性别: 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中注入哪,可以在你的业务逻辑中

相关推荐

    log4j所依赖jar包

    Log4j是一个广泛使用的Java日志框架,由Apache软件基金会开发。它为应用程序提供了一种灵活的日志记录机制,使得开发者能够控制日志信息的输出格式、级别以及目的地。在Java应用程序中,日志功能是必不可少的,因为...

    JDK Logger 简介

    虽然JDK Logger在简单场景下已经足够使用,但在大型项目中,可能需要更强大和灵活的日志框架,如Log4j或Logback。这些框架提供了更多功能,如异步日志处理、更高级的过滤规则和更丰富的插件体系。 ### 总结 JDK ...

    Java Log4j使用详解

    本篇文章旨在详细介绍如何在Java中使用Log4j来管理日志,包括其配置方法以及与其他日志框架(如Commons Logging和JDK自带Logger)的对比。 #### 二、Jakarta Commons Logging (JCL) ##### 2.1 概述 Jakarta ...

    log4j-1.2.16

    《Apache Log4j详解——基于log4j-1.2.16版本》 Apache Log4j是一款广泛使用的Java日志记录框架,它为开发者提供了一种灵活且强大的日志处理机制,使得在应用程序开发中可以方便地进行日志记录、管理和分析。Log4j...

    log4j实用配置扩展

    #### 四、log4j的核心组件 log4j的核心组件主要包括**Loggers(记录器)**、**Appenders(输出源)**和**Layouts(布局)**。 1. **Loggers (记录器)**:负责生成日志信息,并决定是否发送日志信息到Appenders。记录器...

    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。

    mybatis,log4j打印日志到后台和文件

    在 MyBatis 中,我们通常会依赖日志框架如 Log4j、Logback 或 JDK 内置的日志系统。Log4j 以其强大的功能和灵活性深受开发者喜爱。首先,确保你的项目已经包含 Log4j 的依赖,如果是 Maven 项目,可以在 `pom.xml` ...

    log4J学习笔记

    #### 一、Apache Commons Logging与log4j及JDK Logger的关系 **Apache Commons Logging** 的设计初衷是为了提供一个简洁统一的日志接口,它并不直接实现日志功能,而是通过桥接的方式支持多种底层日志框架。这种...

    log4j快速入门与精通

    最简单的方法是直接将 log4j.jar 文件放置在 JDK 的 `%java_home%/lib/ext` 目录下。 - **创建示例项目**:创建一个名为 `TestLogging.java` 的文件,并编写如下代码: ```java import org.apache.log4j.*; public...

    slf4j+log4j所需jar包(三个1.6版本)

    1. **SLF4J API**:这个jar包是SLF4J的核心,它提供了一组API供开发者在代码中调用,如`org.slf4j.Logger`和`org.slf4j.LoggerFactory`。这些API不会直接执行任何日志操作,而是作为代理,根据实际的日志实现(这里...

    springboot整合log4j入门程序

    # springboot整合log4j入门... log4j配置文件详细日志配置文件在resources下的log4j-spring.properties: log4j.logger.DEBUG=DEBUGlog4j.appender.DEBUG=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.DEB

    log4j使用方法及简单配置

    它的自动选择机制可以根据环境找到最适合的日志实现,如果没有配置,会按顺序尝试Log4j、JDK内置日志、SimpleLog等。只需将Log4j的库添加到classpath,就能实现commons-logging与Log4j的整合。 在代码中,使用Log4j...

    tomcat6 配置log4j步骤

    ### Tomcat 6 配置 Log4j 步骤详解 #### 一、引言 在 Java Web 开发中,日志记录对于调试程序、跟踪错误以及系统维护来说至关重要。Log4j 是一个开放源代码的日志记录工具,它允许开发者自定义日志输出格式、输出...

    log4j2.zip

    1. **Async Logger**:这是Log4j 2的一大亮点,通过使用Java的并发工具,如ExecutorService,实现了日志事件的异步处理,避免了同步日志记录可能引起的阻塞。 2. **Layouts and Patterns**:提供了多种布局模式,如...

    Log4j工程官方源码

    Log4j是Apache组织开发的一款广泛使用的Java日志框架,它的全名是Apache Log4j 2。这个压缩包文件包含的是Log4j的官方源码,对于开发者来说,能够直接导入到Eclipse中进行学习和研究,或者进行二次开发,具有很高的...

    日志记录(log4j等)介绍.doc

    #### 四、Log4j 的配置与使用 1. **基本配置**:将 log4j.jar 添加到类路径中,并在类路径根目录下创建一个名为 log4j.properties 的配置文件。 2. **配置文件详解**: - **配置 logger**: - `log4j.rootLogger=...

    log4j配置.doc

    在log4j推出时,其优异性能曾引起Sun公司注意,甚至考虑将其纳入JDK1.4中替代原有的日志工具,但因JDK1.4接近完成而未能实现。尽管如此,log4j凭借其优势在Java开发中占据了主导地位,成为首选的日志记录解决方案。 ...

    log4j日志文件

    - Commons-Logging:提供了一个统一的日志接口,可以根据环境自动选择合适的日志实现(如Log4j、JDK内置日志等)。在程序中使用`Log`和`LogFactory`,无需直接引用Log4j的类。 在实际应用中,根据项目需求,可以...

Global site tag (gtag.js) - Google Analytics