Short introduction to log4j
Ceki Gülcü
March 2002
译者声明:<o:p></o:p>
1. 这是根据最新的log4j(jakarta-log4j-1.2.8)的开发包自带文档的manual翻译的<o:p></o:p>
2. 译者尽力保持原文格式,以便于读者查找原文<o:p></o:p>
3. 对一些关键词都带有原文单词,便于阅读<o:p></o:p>
4. 原文中比较生僻的单词,译者都是参考金山词霸,对找不到的组合词都是保持原文。<o:p></o:p>
5. 对比较拗口的说法,译者尽量采用意译的方法,同时保持原文。<o:p></o:p>
6. 有几个地方是log4j知识的深入探讨,翻译的不是很好,以后会重新修改<o:p></o:p>
2004.6.18<o:p></o:p>
译文:<o:p></o:p>
版权所有2000-2002Apache软件组织。保留一切权利。这个软件是在Apache软件许可证1.1版本条款的保护下发布的。这个协议的内容都包含在LICENSE.txt文件中随log4j一起发布的。这份文档是基于2000年11月JavaWorld发表的"Log4j delivers control over logging"文章。然而,目前这篇文章包含更详细的内容和最近的信息。这篇文章也从同一个作者所著的"The complete log4j manual"借鉴了一些内容。
摘要
这篇文章描述了Log4j的API、独一无二的特色和设计原理。Log4j是一个聚集了许多作者劳动成果的开源软件项目。它允许开发人眼以任意的粒度输出日志描述信息。它利用外部的配置文件,在运行时是完全可配置的。最厉害的是,log4j有一条平滑的学习曲线。当心:从用户的反馈表明,它是很容易上瘾的。
介绍
几乎每个大型的应用程序都包含有自己的日志记录或跟踪API。与这个原则一致,E.U. SEMPER项目决定写自己的跟踪API。这事发生在1996年。在多次改进以后,经过几次演化和大量的工作使之逐渐变成了log4j,一个流行java日志包。这个软件包是在apache软件许可证的保护下发布的,开源组织主动性保证了这是一个完整的开源许可证。最新的log4j版本包含了源代码、类文件和可以在http://jakarta.apache.org/log4j/找到的文档。顺便说一下,log4j已经被发展到了C, C++, C#, Perl, Python, Ruby,和Eiffel语言。
在代码里插入日志描述代码是一种低级的调试方法。由于调试器并不总是可用的或者可应用的,因此这可能是唯一的方法。这对多线程应用和分布式应用来说是非常普遍的现象。
经验表明日志是开发环节中一个重要的组件。它提供了好多的有点。对一个正在运行的应用程序而言,它可以提供准确的环境信息。一旦插入了代码,日志输出就不需要认为的干涉。还有,日志输出可以保存在永久的媒体中,供以后研究。包括它在开发环节的作用,一个高效的功能丰富的日志包可以被看作一款审计工具。
就像Brian W. Kernighan和Rob Pike在他们的扛鼎之作《编程实践》中写下的
鉴于每个人的选择,我们不提倡使用调试器,除非为了跟踪堆栈或者获得一个变量的值。一个原因是在复杂的数据结构和控制流中是很容易丢失细节的;第二个原因是,我们发现单步跟踪一个程序与仔细思考并在关键的地方添加代码输出描述与自我检查相比是没有效率的。查看所有的描述信息比扫描正确地方输出的信息将花费更多时间。决定在关键放置输出打印语句比单步跟踪更省时间,即使我们知道那在什么地方。跟重要的是,调试语句是和程序放在一起的;而调试会话是暂时的。
日志代码有它自己的缺点。它可能会导致应用程序运行变慢。假如输出太详细,可能会导致屏幕闪动(scrolling blindness)。为了减轻这些影响,log4j被设计为可依赖的,更快的和可扩展的。由于日志很少是应用程序关注的焦点,所以log4j API力争做到简单并易于理解和使用。
记录器(Loggers),输出源(Appenders)和布局器(Layouts)
Log4j包含三个首要组件:记录器,输出源和布局器。这三类组件一起工作使开发者可以按消息的类别和等级来输出消息,并且控制在运行时这些消息怎么格式化和在哪里输出这些信息。
记录器层次
任意一个log4j API最大的优点是平滑了System.out.println固有的能力,当允许其他人不受妨碍的打印时使某些日志语句不起作用。这个能力假定日志空间,也就是所有的可能的日志语句的空间,是可以按照开发者的标准来分类的。这个观察资料以前已经引导我们选择类别作为包的中心概念。然而,自从 log4j的1.2版本,记录器(Logger
)类已经取代了范围(Category
)类,对那些熟悉log4j早期版本的人来说,记录器(Logger
)类可以被认为仅仅是范围(Category
)类的别名(alias)。
记录器被命名为实体(Loggers are named entities),记录器(Logger)的命名是事件敏感的(case-sensitive),并且他们遵循层次的(hierarchical)命名规则:
按层次命名 假如一个记录器的名称后面跟着一个被认为是子记录器前缀的“.”号,那么它就被认为是另一个记录器的祖先 |
例如,名称为“com.foo
”的记录器是名称为“com.foo.Bar
”的父。相似的是,“java”是“java.util”的父,是“java.util.Vector”的祖先。这个命名规则对大多数的开发人员来说应该是很熟悉的
根记录器(root logger)处于记录器层次的顶端.在两种情况下,它是意外的。
1. 它总是存在
2. 它不可以通过名称获得
调用类的静态方法Logger.getRootLogger获得根类.所有其他类都被实例化,并且用类的静态方法Logger.getLogger获得这些实例。这个方法用期望的记录器作为参数。记录器类的一些基本方法如下:
package org.apache.log4j; <o:p></o:p> public class Logger { <o:p></o:p> // Creation & retrieval methods: public static Logger getRootLogger(); public static Logger getLogger(String name); <o:p></o:p> // printing methods: public void debug(Object message); public void info(Object message); public void warn(Object message); public void error(Object message); public void fatal(Object message); <o:p></o:p> // generic printing method: public void log(Level l, Object message); } |
记录器可以被设置级别。可能的级别包括DEBUG, INFO, WARN, ERROR和FATAL,这些级别被定义在org.apache.log4j.Level类中。尽管我们不鼓励,但是你还是可以通过子类化级别类来定义你自己的级别。一个更好的方法将在后面介绍
假如一个给定的记录器没有被设置级别,它可以集成一个最近的带有指定级别的祖先。更正式地:
Level Inheritance 级别继承 继承的级别被指定给记录器类C,在记录器层次中它是和第一个非空级别相等的 |
为了保证所有的记录器最终可以继承一个级别,根记录器总是有一个被指定的记录器。
下面是四个表,这些表带有不同指定级别值和参照上面规则的继承级别的结果
记录器名称<o:p></o:p> | 指定的级别<o:p></o:p> | 继承的级别<o:p></o:p> |
root<o:p></o:p> | Proot<o:p></o:p> | Proot<o:p></o:p> |
X <o:p></o:p> | none<o:p></o:p> | Proot<o:p></o:p> |
X.Y <o:p></o:p> | none<o:p></o:p> | Proot<o:p></o:p> |
X.Y.Z<o:p></o:p> | none<o:p></o:p> | Proot<o:p></o:p> |
范例 1<o:p></o:p> |
在上面的范例1中,仅仅根记录器被指定了级别。这个级别的值是Proot,它被其它的记录器X, X.Y和X.Y.Z继承
记录器名称<o:p></o:p> | 指定的级别<o:p></o:p> | 继承的级别<o:p></o:p> |
root<o:p></o:p> | Proot<o:p></o:p> | Proot<o:p></o:p> |
X <o:p></o:p> | Px<o:p></o:p> | Px<o:p></o:p> |
X.Y <o:p></o:p> | Pxy<o:p></o:p> | Pxy<o:p></o:p> |
X.Y.Z<o:p></o:p> | Pxyz<o:p></o:p> | Pxyz<o:p></o:p> |
范例 2<o:p></o:p> |
在范例2中所有的记录器都有一个指定的级别值,这就没有必要继承级别值了。
记录器名称<o:p></o:p> | 指定的级别<o:p></o:p> | 继承的级别<o:p></o:p> |
root<o:p></o:p> | Proot<o:p></o:p> | Proot<o:p></o:p> |
X <o:p></o:p> | Px<o:p></o:p> | Px<o:p></o:p> |
X.Y <o:p></o:p> | none<o:p></o:p> | Px<o:p></o:p> |
X.Y.Z<o:p></o:p> | Pxyz<o:p></o:p> | Pxyz<o:p></o:p> |
范例 3<o:p></o:p> |
在范例3中,所有的记录器,包括X 和 X.Y.Z都被分别指定记录器值为Proot、Px和Pxyz。记录器X.Y从它的父X继承它的级别值
记录器名称<o:p></o:p> | 指定的级别<o:p></o:p> | 继承的级别<o:p></o:p> |
root<o:p></o:p> | Proot<o:p></o:p> | Proot<o:p></o:p> |
X <o:p></o:p> | Px<o:p></o:p> | Px<o:p></o:p> |
X.Y <o:p></o:p> | none<o:p></o:p> | Px<o:p></o:p> |
X.Y.Z<o:p></o:p> | none<o:p></o:p> | Px<o:p></o:p> |
范例 4<o:p></o:p> |
<o:p></o:p>
在范例4中,记录器root和X分别被指定级别值为Proot和Px。记录器X.Y
和X.Y.Z从最接近它们的父X继承它们的级别值,这个父有一个指定的级别值…
通过调用一个记录器实例的打印方法来处理日志请求。这些打印方法是debug, info, warn, error, fatal和log.
通过定义,打印方法决定一个日志请求的级别。例如,假如c是一个记录器实例,语句c.info("..")是一个带有INFo级别的日志请求。
若日志请求的级等于或者大于日志记录器的级别,那么这个日志请求就是可行的,相反,请求将不能输出。一个没有被指定级别的日志记录器将从层次(hierarchy)继承。这些规则在下面总结。
基本的选择规则 在一个具有q级别的日志记录器中(指定和继承都是合适的)有一个具有p级别的日志请求,若p>=q,则这个日志请求是可以输出的。 |
这个规则是log4j的核心。假定级别是排序的,对标准的级别来说,我们设定DEBUG < INFO < WARN < ERROR < FATAL。
<o:p></o:p> // get a logger instance named "com.foo" Logger logger = Logger.getLogger("com.foo"); <o:p></o:p> // Now set its level. Normally you do not need to set the // level of a logger programmatically. This is usually done // in configuration files. logger.setLevel(Level.INFO); <o:p></o:p> Logger barlogger = Logger.getLogger("com.foo.Bar"); <o:p></o:p> // This request is enabled, because WARN >= INFO. logger.warn("Low fuel level."); <o:p></o:p> // This request is disabled, because DEBUG < INFO. logger.debug("Starting search for nearest gas station."); <o:p></o:p> // The logger instance barlogger, named "com.foo.Bar", // will inherit its level from the logger named // "com.foo" Thus, the following request is enabled // because INFO >= INFO. barlogger.info("Located nearest gas station."); <o:p></o:p> // This request is disabled, because DEBUG < INFO. barlogger.debug("Exiting gas station search"); |
用同一个名称调用getLogger方法将返回一个指向同一个记录器对象的引用
例如,
Logger x = Logger.getLogger("wombat"); Logger y = Logger.getLogger("wombat"); |
x
和y
指向同一个日志记录器对象
因此,配置一个日志记录器,不用在代码里转换引用就可以获得相同的实例是可能的。在生物学父时代的基本矛盾里面,总是可以preceed他们的孩子,log4j的日志记录器可以按一定的规则创建和配置。尤其是,即使一个“父”日志记录器在它的子孙后面被实例化,它仍然可以发现并连接到它的子孙
在应用程序初始化的时候,Log4j的配置被执行。最好的方法是通过读取一个配置文件。很快就会讨论这个方法
通过使用软件组件,log4j很容易命名日志记录器。这可以通过在每个类中静态实例化日志记录器来完成,日志记录器名是和完整的类名相同的。这是一个直截了当地定义日志记录器的有用方法。由于日志输出带有产生该日志的日志记录器的名称,命名策略让辨认产生日志消息的源头很容易。然而,这仅仅是是一个可能,虽然命名日后子记录器的策略很普通(However, this is only one possible, albeit common, strategy for naming loggers)。Log4j没有约束日志记录器可能趋势(Log4j does not restrict t
分享到:
相关推荐
### log4j中文手册知识点概览 #### 1. 简介 - **概述**:日志记录在软件开发中扮演着至关重要的角色。它不仅帮助开发者追踪问题,还能在生产环境中收集运行数据用于分析。传统的日志记录方式如`System.out.println...
《log4j中文手册》是Java开发人员必备的参考资料,它详细介绍了log4j这个广泛使用的日志记录框架。Log4j是Apache软件基金会开发的一个开源项目,主要用于生成应用程序运行时的日志信息,帮助开发者进行调试、性能...
**Log4j中文文档概述** Log4j是Java平台上的一个开源日志记录框架,它为应用程序提供了灵活的日志记录功能。这个文档主要是为那些英语水平不高,但在编程过程中需要理解和使用Log4j的开发者准备的。Log4j在Java世界...
标签:apache、logging、api、log4j、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译...
标签:apache、slf4j、logging、log4j、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...
标签:apache、logging、log4j、api、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译...
标签:apache、logging、log4j、slf4j、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...
标签:over、slf4j、log4j、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心...
### Log4j中文帮助文档知识点总结 #### 一、Log4j简介 - **Short introduction to log4j**(简短介绍) - Log4j是由Ceki Gülcü于2002年编写的,这是一份针对log4j(jakarta-log4j-1.2.8版本)的简短介绍文档。该...
标签:core、apache、logging、log4j、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译...
标签:apache、slf4j、logging、log4j、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明...
标签:apache、logging、log4j、core、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译...
标签:apache、logging、log4j、slf4j、impl、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明...
包含翻译后的API文档:log4j-core-2.9.1-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:org.apache.logging.log4j,artifactId:log4j-core,version:2.9.1 使用方法:解压翻译后的API文档,用浏览器...
包含翻译后的API文档:log4j-slf4j-impl-2.17.1-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org.apache.logging.log4j:log4j-slf4j-impl:2.17.1; 标签:apache、logging、log4j、slf4j、impl、中英...
标签:apache、extras、log4j、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译...
Log4j作为一个开源项目,拥有活跃的开发者社区和广泛的用户基础,这不仅确保了其持续的更新和完善,也为用户提供了丰富的文档和示例,帮助快速理解和使用。 总结来说,Log4j是一个强大且灵活的日志框架,它简化了...
标签:apache、logging、log4j、core、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译...
包含翻译后的API文档:log4j-slf4j-impl-2.12.1-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org.apache.logging.log4j:log4j-slf4j-impl:2.12.1; 标签:apache、logging、log4j、slf4j、impl、中英...