`
herman_liu76
  • 浏览: 99586 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

log4j使用、源码简析与怎么出炉呢

 
阅读更多
    本文根据log4j-1.2.17,先介绍开发J2EE中使用,后面是深入源码分析,主要是如何Head first来弄这个log。

    Apache的log4j是最常用的java日志处理工具,通常用起来非常容易,看到不少人还喜欢用System.out.println(),强烈建议不要用了。有人说jsp里怎么办?下面介绍。

一、简单使用
    通常很简单,写一个配置文件,把log4j-1.2.17.jar扔到lib里,你的类定义一个对象就可以了,日常在配置中设置下输出模块与级别就行了。
1.写一个log4j.properties放在WEB-INF/classes下面,文件内容简单如下:
  # 根日志的级别与输出去向,这句有两个去向。
  log4j.rootLogger=WARN, stdout, R
  # 去向stdout的配置情况,这里是去控制台。
  log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
  # 去向R的配置情况,这里是记录在一个文件中。
  log4j.appender.R=org.apache.log4j.RollingFileAppender
  log4j.appender.R.File=example.log
  log4j.appender.R.MaxFileSize=100KB
  log4j.appender.R.MaxBackupIndex=1
  log4j.appender.R.layout=org.apache.log4j.PatternLayout
  log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
  # 我要输出的地方与级别,一般开发中只调整这里。很简单吧~
  log4j.logger.我的模块1包=INFO
    log4j.logger.我的模块2包=DEBUG


    由于包时原LogManager的静态初始化方法中会加载属性,所以不需要人工做什么,只要写好这个配置文件。

2.在类中的使用
    在你的每一个需要日志的类中,import org.apache.log4j.Logger后,在类写一句属性对象:
   
private static final Logger log= Logger.getLogger({你的类名}.class);


    后面在需要日志的地方,用log.debut...或者  log.info...或者log.error等输出日志就行了。从名字看出,在调试时,都用debug,正式运行时要输出的用info,出错用error。以后在上面的配置文件中就可以控制输出级别了。正式运行时你用info级别,所有的debug日志就不会出现了,干净很多。

3.在jsp中使用
     一般来说不需要jsp中写,特别是使用各种前台框架的项目。但我们的项目中,jsp中也会写不少后台代码,所以免不了用日志,很多人就用System.out.println了,而我认为还是用log4j。网上也没找到合适的,自己调试一下,这样写:
   
final Logger log= Logger.getLogger("jsp.项目名.文件夹1级.文件夹2级.页面名_jsp");

     加了static不可以,一定要有final,我只记得匿名内部类使用一个在其外部定的对象,那么编译器会要求其参数引用是final的。不知道内部处理jsp到class时,是不是有这方面的原因呢?不去深究了。
     Log的名字,与页面在文件夹中的层次关系一样,中间用.分隔开,最后的文件后缀的.换成了_,因为包中用.区分层次。实际上log内部关系也是用.来区分的,所以这样处理一下。配置文件中可以用类似这样的语句控制文件夹1级下的页面的输出级别:
log4j.logger.{jsp.项目名.文件夹1级}=INFO



二、log4j源码是什么样?
1.主要的两个对象
    居然不用Hashmap而用Hashtable?不用ArrayList而用vector?好老啊。简单看了一下,主要是Category.java与Hierarchy.java两个类,Category实际上就是具体的日志类,Hierarchy是个容器,里面主要是用hashtable来放日志类。
    Hierarchy作为日志对象,属性有:名字,级别,父级日志对象,国际化资源,指向日志的容器,输出的动向表,是否附加父级的去向。
    看到了吧,每个日志对象都可以分开配置自己独特的级别,去向等内容。再看一下,日志对象与父级对象都有啥关系?


    整个项目中找到4个与父亲有关的地方,分别是要父级的:去向,国际化资源,级别。所以一个子日志对象,可以继承父日志对象的很多内容。

    那么,什么是父级对象呢?实际上就是按日志的名字来区分的,重点就是包分隔用的.来区分。

2.处理父子日志对象的巧妙之处
    root日志对象是所有日志对象的根对象。用getLogger("a.b.c.d.e.f")举例吧。如果你只用到f这个类,那f类的日志对象名字就是"a.b.c.d.e.f",它的父类日志对象应该是"a","a.b", "a.b.c", "a.b.c.d", "a.b.c.d.e" 这么几个,但父类日志对象目前不存在啊,那就建这些节点的虚拟对象,有点象空文件夹,每级的日志虚拟对象里存着实际上存在的这个日志对象,那f的日志对象目前的直接父类是root日志。
    而以后如果中间某个日志对象有了,也许它的名字与子包名字一毛一样,这样就要替换掉那个虚拟对象,再把虚拟对象中临时存放的f日志对象的父亲,换成新出现的这个日志对象,而新出现的这个的父级将变成f原来的父对象,那就是root对象了。
    这样才能实现在配置中,日志级别按包名字级别,来控制子对象,甚至自定义每个级别的去向,级别了。这个很少用到,但看了源码就知道非常的灵活了。
    为什么配置文件可以那么简单?上面分析可以看出,通常只配置root的级别与去向就行了。子日志对象就直接继承下来了,实际用的时候,我们最多改动就是输出那个位置的日志与输出的级别,所以通常只改一下想输出的部分,一句话设置一个模块就够了。


3.其它几个对象
    另外去向是一个appender对象,常用的有控制台去向,日志文件去向,包括每天产生一个的DailyRollingFileAppender,还有一个什么JDBCAppender, JMSAppender, SocketAppender 等等,后面这些以前没听到过。
    还有什么Layout的对象,看名字就知道是布局格式之类的,比如:SimpleLayout, xmlLayer, HTMLLayer...,上面的配置中有:layout=org.apache.log4j.PatternLayout。
    其它对象都不太重要了,不深看了。

三、分析完源码,分析一下如何设计日志
    看完源码,感觉太完善了太灵活了。除了用Hashtable,用vector太老之外,现在嘛,不考虑并发用Hashmap,并发用concurrentHashmap。vector加锁效率太低,不过CopyOnWriteArrayList 使用也受限。
    假设一下:比如老板说,目前的日志太乱了,但当时log4j还没出生,怎么办?也许此法可以开拓思路,尝试经历一下那个log4j开发人员所经历的思考,提升我们未来处理问题的能力。
1. 专门的人做专门的事
    面向对象的语言,我喜欢从现实生活中对比。社会中,如果通用的功能,会找一个专职人员。比如会议签到,每个与会人员去那里登记一下。如果开始到处自己写syso,那么第一步,我会设计一个类,专门处理各个类产生的日志,甚至是一个静态类。谁要处理,把信息传给我就行了,当然都要引用到这个静态类。由我统一syso。

2.部署时,要擦去好多syso
    开发时写了很多,实际部署不要那么多日志,但有时候找问题又要,那必须有一个级别来控制,那专职日志对象要求传过来日志级别。

3.不能总看控制台,还要有文件
    那就需要配置一下了,把日志同时写到文件中,可以控制文件大小,也可以控制每天一个,也可以控制只生成重要的日志。

4.有的包要输出,有的包不需要
    老板的想法又进一步,想想是合理的,每人做一块,只想看自己的DEBUG日志,其它的不想看,这就比前面那些麻烦多了。如同考核在不在岗位,有的部门一直在的,有的是需要出去跑业务的。好的,那搞一个名单,每个考核人登记时告诉名字,查找部门,如果在要考核部门,那就登记。这个名单???怎么弄,怎么起名字??好吧,对象的全名字不就行了,配置时弄个包的部分前缀,可以用indexOf来判断。

5.按类的命名起名字不错,能不能再灵活,不同级别都灵活定义?
    这个真正复杂起来了,每个包都配置不一样?一个统一的日志类貌似不合理了,要分裂出很多的日志类了。一个统一的日志员,通过查名单表不行了,每人一个移动日志员。每一个日志类对象都有自己不同的属性,记录自己的配置。
    这时候可能还是用indexOf来判断,如果某层与下层,与下下层,与下下...层都不一样,那indexOf实在是太乱了,也许这时候想到日志对象串起来,只用.来串效率太差了,但串起来是依据.来的。把.的级别关系换成父子引用的关系,运行起来更快。缺失的节点补成特别节点,有点象文件夹与文件的关系了。
    其它的什么去向,格式啊都与特定的日志对象有关,当然可以从父级拿到,如果没有就是从root中拿,所以配置文件中必须有一个root的级别与去向的配置。

6.如果通常使用的情况下,这个日志是不是复杂了?
    如果你的类层次很多,一般只按级别与模块输出,那产生的日志对象(包括虚拟对象)貌似有点多。所以如果根据实际情况(我们项目几乎都很用的简单配置),去掉一些几乎不用的灵活性,是不是可以只用一个日志root对象,加上点简单的判断,固定上几乎不变的输出去向内容,做一个非常小的日志工具呢?软件毕竟不同于现实中的低配版,高配版。
  • 大小: 63.6 KB
分享到:
评论

相关推荐

    log4j源码 log4j源码

    在Log4j的源码中,"org"可能包含了所有源代码的顶级包结构,如"org.apache.log4j",这包含了Log4j的各个主要组件和类。具体的学习过程中,我们可以逐层展开这个包,了解每一个类的功能和它们之间的关系,这对于理解...

    log4j 1.2.15 源码

    《深入解析log4j 1.2.15源码》 在软件开发领域,日志记录是一个不可或缺的环节,而log4j作为Java平台上最广泛使用的日志框架之一,其重要性不言而喻。本文将深入探讨log4j 1.2.15的源码,帮助开发者更好地理解其...

    log4j 源码包 日志包 2.11.0

    《深入解析Log4j 2.11.0源码》 Log4j,作为Java领域最常用的日志框架之一,其2.11.0版本的发布为开发者提供了更加强大、高效和灵活的日志处理能力。源码包的获取,对于开发者深入理解其工作原理、定制化需求以及...

    log4j学习源码教程

    本教程将通过源码分析,深入讲解log4j的工作原理和使用方法。 **1. log4j的基本概念** - **Logger**: 日志记录器,是log4j的核心接口,用于生成不同级别的日志事件。 - **Level**: 日志级别,包括DEBUG、INFO、...

    log4j-1.2.17含源码

    《深入理解Log4j 1.2.17:源码与JAR包解析》 在软件开发领域,日志记录是一项至关重要的任务,它帮助开发者跟踪程序运行状态,定位和解决问题。Log4j作为Apache组织的一个开源项目,是Java平台上最常用的日志框架之...

    Log4j工程官方源码

    下面将详细解释Log4j的核心概念、功能以及如何在Eclipse中使用这些源码。 1. **Log4j的核心概念** - **Logger**: 日志器是Log4j中最基本的组件,用于记录日志信息。开发者可以通过获取特定级别的Logger来记录不同...

    Log4j_1.2.15 源码

    Log4j是Apache组织开发的一款广泛使用的Java日志框架,版本1.2.15是其历史的一个稳定版本。这个源码包包含了Log4j的核心组件和相关配置,便于开发者研究其内部工作原理,理解日志处理机制,以及进行定制化开发。 1....

    老生常谈Log4j和Log4j2的区别(推荐)

    然后使用Logger.getLogger()方法获取日志记录器,而Log4j2需要import org.apache.logging.log4j.Level、org.apache.logging.log4j.LogManager和org.apache.logging.log4j.Logger,使用LogManager.getLogger()方法...

    log4j 1.2.8 jar 包含源码

    **Log4j 1.2.8 源码解析** Log4j 是一个广泛使用的 Java 日志框架,由 Apache 软件基金会开发。它为应用程序提供了灵活的日志记录功能,允许开发者调整日志级别,定制日志格式,以及将日志输出到不同的目的地,如...

    Apache Log4j 2 源代码( apache-log4j-2.17.1-src.zip)

    Apache Log4j 2 源代码( apache-log4j-2.17.1-src.zip) 是对 Log4j 的升级,它比其前身 Log4j 1.x 提供了重大改进,并提供了 Logback 中可用的许多改进,同时修复了 Logback 架构中的一些固有问题。修复了安全漏洞...

    log4j使用教程(详解)

    本文将深入探讨Log4j的基本概念、配置与使用方法。 1. **什么是Log4j** Log4j是一个基于Java的日志记录工具,它提供了灵活的控制来记录日志信息,包括日志级别(DEBUG、INFO、WARN、ERROR、FATAL)、日志输出格式...

    若依框架使用的log4j2.16.0,修复log4j漏洞log4j2下载最新log4j2.16.0下载

    Log4j是一个广泛使用的Java日志记录框架,它允许开发者在应用程序中轻松地记录各种级别的日志信息,如DEBUG、INFO、WARN、ERROR等。在2021年底,一个重大的安全漏洞(CVE-2021-44228)被发现在Log4j2的早期版本中,...

    apache-log4j-1.2.17源码

    在深入分析`apache-log4j-1.2.17`源码之前,我们需要了解日志框架在软件开发中的基本作用和Log4j的一些核心特性。 1. **日志框架的作用** - 错误跟踪:记录程序运行过程中的异常信息,帮助开发者快速定位问题。 -...

    Log4j2简介及与Log4j效率对比

    与Log4j 1.x相比,Log4j2在设计上进行了重大改进,并解决了Logback等其他日志框架中存在的某些体系结构问题。 #### 特性概述 1. **审计功能**:Log4j2设计时考虑到了审计需求,这意味着即使在配置更新过程中,它也...

    The Complete Log4j Manual

    这意味着在手册中讨论的所有配置和使用方法都与Log4j的1.2版本及以上版本兼容。用户在使用手册内容时,需要确保自己的项目中也使用了相同或更高版本的Log4j库。 2. 版权声明和使用授权 《The Complete Log4j ...

    log4j-1.2.13-src

    Apache Log4j是Java平台上广泛使用的日志记录框架,其1.2.13版本的源码为我们提供了深入了解这个强大工具的机会。本文将围绕log4j的核心概念、设计模式、主要组件以及其实现细节进行详细的探讨。 一、Log4j概述 ...

    log4j简单使用

    "源码"标签暗示我们将讨论Log4j的内部机制或如何查看和理解其代码,这对于学习和定制Log4j功能很有帮助。而"工具"标签则表明Log4j是一个开发者常用的工具,它的使用和配置是提高开发效率的关键。 **压缩包文件名称...

    Log4j2效率测试源码

    Log4j2是一款广泛使用的Java日志框架,它在日志处理方面提供了高效、灵活且可扩展的解决方案。本测试源码着重关注Log4j2的性能表现,这对于理解和优化日志系统的性能至关重要。Log4j2的设计目标是提供比其前一代Log4...

    log4j.properties(完整版) log4j.properties(精简版)

    **日志框架Log4j详解** 在Java开发中,日志记录是一项不可或缺的功能,它能够帮助开发者追踪程序运行状态,定位错误,优化性能,并为后期维护提供重要信息。Log4j是Apache组织开发的一个强大的、灵活的日志记录框架...

    logging-log4j2-log4j-2.15.0-rc2.zip maven 资源库

    针对Log4j 2 远程代码执行漏洞,需要用到的升级资源包,适用于maven资源库,包括log4j,log4j-core,log4j-api,log4j-1.2-api,log4j-jpa等全套2.15.0 maven资源库jar包。如果是maven本地仓库使用,需要将zip包解压...

Global site tag (gtag.js) - Google Analytics