`
heteronomy
  • 浏览: 5765 次
  • 来自: 广州
社区版块
存档分类
最新评论

log4j的简要介绍

阅读更多

摘要

log4j是一个开源的工程,开发人员可以随意控制输出控制语句。它使用外部配置文件,可完全在运行时配置。极为重要的是它的学习周期极短。

介绍

几乎所有的大型应用程序都有自己的日志和追踪API。基于此,早在1996年,EU SEMPER项目决定写自己的追踪API。在无数的改进之后,它成为了java的一个流行的日志包log4j。这个包是Apache软件许可下发布的,它是一个非常成熟的开源许可证书。最新的log4j,包括源代码,class文件和文档,能在http://logging.apache.org/log4j/下载。顺便提一下,log4j已经支持C, C++, C#, Perl, Python, Ruby和Eiffel。

往代码里插入日志语句进行调试是非常低级的,但是也可能是唯一的方式,因为并不是总有调试器或者调试器不可用。多线程和分布式程序尤其如此。

经验表明,记录日志是开发过程中的一个非常重要的环节。它有几大优势。它能提供一个精确的应用程序运行的上下文。插入代码之后,生成日志输出就不需要人为干预了。并且日志输出能存储在持久化介质中以便日后研究。除了在开发中的用途之外,大量的日志也可当作审计工具。

尽管Brian W. Kernighan和Rob Pike在他们的优秀著作《编程实践》中指出:

就个人而言,我们倾向于不使用调试器进行堆栈跟踪或者获取一两个变量的值。原因之一是很容易在复杂的数据结构和控制流的细节中迷失;我们发现一步一步地走完程序没有深思熟虑之后在关键地方加上输出语句和自检查代码效率高。在语句上来回点击比扫视精心布置的打印输出要耗时。即使我们知道关键代码的位置,单步调试到那个地方也比放置打印语句要耗时。更重要的是,调试用的语句和程序在一起,而调试会话是瞬时的。

 

记录日志也有它的缺点。它会降低程序的运行速度。假如输出太详细,会导致屏幕闪动。为了缓解这些担忧,log4j设计得可靠、快速和可扩展。既然记录日志基本不是应用程序的主要关注点,log4jAPI致力于易于理解和使用。

Logger, Appender和Layout

Log4j有3个主要的部分:Logger, Appender和Layout。它们协同合作,使开发人员可以根据消息的类型和级别来记录日志并在运行时控制这些消息的格式和报告位置。

 

Logger层级结构

任何一个记录日志的API相比于普通的System.out.println的第一个也是最重要的优势在于禁用一些日志语句而不影响其他的语句。这种特性假设日志空间,也就是所有可能的记录日志语句的空间,是根据某些开发人员选定的标准分类的。这种结论以前让我们将类别作为包的中心概念。但是自从log4j版本1.2以来,Logger类已经替代了Category类。对于那些熟悉log4j以前版本的人来说,Logger类可被当作仅仅是Category类的一个别名而已。

Logger是命名的实体。它们的名字区分大小写,并遵守层级命名规则:

命名的层级体系

如果一个logger的名字加上后面的点是子logger名字的前缀,那么这个logger就称为那个logger的祖先。如果一个logger和子logger之间没有祖先logger,这个logger就称为那个logger的母logger。

 

例如,叫“com.foo”的logger是叫“com.foo.Bar”的logger的母logger。同样的,“java”是“java.util”的母logger,是“java.util.Vector”的祖先。这种命名方式大多数开发者都熟悉。

根logger在logger层级结构的顶端。它有两点特别:

  1. 它总是存在
  2. 它不能通过名字检索到

调用Logger.getRootLogger可以检索到它。所有其他的logger都是通过Logger.getLogger实例化和检索的。该方法用希望得到的logger的名字作为参数。Logger类的一些基本方法列举如下:

 

package org.apache.log4j;

  public class Logger {

    // Creation & retrieval methods:
    public static Logger getRootLogger();
    public static Logger getLogger(String name);

    // printing methods:
    public void trace(Object message);
    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);

    // generic printing method:
    public void log(Level l, Object message);
}
 

 

  Logger可以被赋予级别。可能的级别集合如下:

TRACE, DEBUG,INFO,WARN,ERROR和FATAL

 它们定义在org.apache.log4j.Level类中。虽然我们并不鼓励这样做,但是你可以通过建立Level类的子类定义你自己的级别。稍后介绍一种更好的方式。

如果某个logger没有赋予级别,那么它继承最近的有级别的祖先的级别。正式的定义如下:

级别继承

对于给定的logger C,它继承的级别等于logger层级体系中从C开始向上至根logger第一个不为null的级别。

为了确保所有的logger能最终继承一个级别,根logger总是有一个赋予的级别。

 

以下是四张表,说明了各种赋予的级别值以及根据以上规则产生的继承的级别值:

例一

Logger name Assigned
level
Inherited
level
root Proot Proot
X none Proot
X.Y none Proot
X.Y.Z none Proot

例一中,只有根logger赋予了级别。这个级别值,Proot,被其他的logger x, x.y和x.y.z继承。

 

例二

 Logger name  Assigned
level
 Inherited
level
 root  Proot  Proot
 X  Px  Px
 X.Y  Pxy  Pxy
 X.Y.Z  Pxyz Pxyz 

 例二中,所有的logger都赋予了级别值。不需要级别继承。

 

例三

 Logger name  Assigned
level
 Inherited
level
 root  Proot  Proot
 X  Px  Px
 X.Y  none  Px
 X.Y.Z  Pxyz Pxyz 

 例三中,root、x和x.y.z被分别赋予了级别值Proot、Px和Pxyz。logger x.y从它的母logger x继承了级别值。

 

通过调用logger实例的某一个打印方法发出记录日志请求。这些打印方法有debug, info, warn, error, fatal and log

根据定义,打印方法决定了日志请求的级别。例如,如果c是一个logger实例,那么 c.info("..") 语句是一个级别为INFO的日志请求。

如果一个日志请求的级别高于或者等于logger的级别,那么称这个请求为启用的。否则为禁用的。规则总结如下:

 

基本选择规则

某个级别(赋予的或者继承的,只要合适)为q的logger中级别为p的日志请求是启用的当 p >= q。

 

这个规则是log4j的核心。它假定级别是有序的。对于标准的级别,我们有DEBUG < INFO < WARN < ERROR < FATAL。

 

如下是这个规则的一个例子:

// get a logger instance named "com.foo"
   Logger  logger = Logger.getLogger("com.foo");

   // 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);

   Logger barlogger = Logger.getLogger("com.foo.Bar");

   // This request is enabled, because WARN >= INFO.
   logger.warn("Low fuel level.");

   // This request is disabled, because DEBUG < INFO.
   logger.debug("Starting search for nearest gas station.");

   // 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.");

   // This request is disabled, because DEBUG < INFO.
   barlogger.debug("Exiting gas station search");

 用同一个名字调用getLogger方法总是返回对用一个logger对象的引用。

 

 

例如,在

 

 

Logger x = Logger.getLogger("wombat");
Logger y = Logger.getLogger("wombat"); 

x和y引用完全相同的logger对象。
因此,可以先配置一个logger,然后在代码中的某处检索同一个实例,而不用到处传递引用。与生物学亲子关系中父母总是先于子女出现根本矛盾的是,log4j中的logger可以以任意顺序创建和配置。特别是,即使母logger在它的子logger之后实例化,它仍然能够找到并连接到它们。
典型的情况是log4j环境的配置在应用程序初始化时完成的。偏向于读取配置文件。Log4j使用软件组件使命名logger更容易。这可以通过在每个类中静态地实例化一个logger来实现,这个logger的名字和这个类的全名一样。这是一种有用并且直观的定义logger的方法。因为输出的日志带有logger的名字,这种命名策略使识别日志消息源变得简单。但是这虽然常见,但仅仅是一种可能的命名logger的策略。Log4j并不限制logger可能的集合。开发人员可以随心所欲地命名logger。
不管怎样,以logger所在的类来命logger似乎是目前已知的最好的策略。

Appender和Layout

基于logger选择性地启用或禁用记录日志请求并不是全部。log4j允许日志请求将信息打印到多个地方。一个打印输出目的地在log4j里称为appender。目前,针对控制台、文件、GUI组件、远程socket服务器、JMS、NT事件Logger和远程UNIX Syslog守护进程。它也可以异步记录日志。

 

可以附加多个appender到同一个logger。

 

addAppender方法添加一个appender到一个给定的logger。一个给定的logger的每一个启用的记录日志请求都会转发到那个logger的所有appender和层次体系上更高的appender。换句话说,appender照着logger的层次体系被附加地继承了。例如,如果一个控制台appender被添加到根logger,那么所有启用的记录日志请求至少将在控制台打印出来。如果除了一个文件appender被添加到一个logger,假设为C,那么C和C的子logger的启用的记录日志请求将会打印在这个文件和控制台上。可以通过设置additivity flag为假,覆盖这种默认的行为,使appender的积聚不再是附加的。

Appender Additivity

logger C日志语句的输出进入到C及其祖先的所有appender里面。这是属于"appender additivity"的意思。

但是,如果logger C的一个祖先,比如P,的additivity flag被设为了false,那么C的输出将会直接进入到C及沿着层次体系往上至P(包括P)的所有祖先logger中的所有appender,而不包括任何P的祖先中的appender。

Logger的additivity flag默认为true

下表是一个示例:

 

Logger
Name Added
Appenders Additivity
Flag Output Targets Comment
root A1 不适用 A1 根logger是匿名的,但是能够通过Logger.getRootLogger()方法访问。没有默认的appender附加在根上。
x A-x1, A-x2 true A1, A-x1, A-x2 "x"和root的appender
x.y none true A1, A-x1, A-x2 "x"和root的appender
x.y.z A-xyz1 true A1, A-x1, A-x2, A-xyz1 "x.y.z", "x"和root的appender
security A-sec false A-sec 既然additivity flag被设为了false,没有appender积聚
security.access none true A-sec 因为"security"中additivity flag被设为了false,所以只有"security"的appender

 

-------------------------------------------------------精彩未完待续-------------------------------------------------------------

 
分享到:
评论

相关推荐

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

    下面我们将从配置文件类型、核心JAR包、文件渲染和Log调用四个方面来比较Log4j和Log4j2的区别。 配置文件类型 Log4j通过一个.properties文件作为主配置文件,而Log4j2则弃用了这种方式,采用的是.xml、.json或者....

    log4j简单使用

    标题"Log4j简单使用"表明我们即将探讨的是日志记录库Log4j的基础应用。Log4j是Apache软件基金会开发的一个开源项目,它为Java应用程序提供了一个灵活的日志系统,允许开发者自定义日志级别、输出格式以及存储位置等...

    SpringBoot框架配置log4j和log4j2的配置代码

    本文将详细介绍如何在SpringBoot项目中配置Log4j和Log4j2。 ### SpringBoot与Log4j Log4j是Apache的一个开源项目,用于生成日志。它的核心功能包括定义日志级别(如DEBUG、INFO、WARN、ERROR),配置日志输出目的...

    log4j 使用介绍

    【log4j 使用介绍】 log4j 是一个广泛使用的 Java 日志框架,它提供了一种高效、灵活的方式来记录应用程序中的事件。这篇介绍旨在帮助初学者理解 log4j 的核心概念和使用方法。 **1. 简介** 日志记录在软件开发中...

    log4j-API-最新稳定版本log4j-1.2.17

    标题提及的是"log4j-API-最新稳定版本log4j-1.2.17",这表明我们关注的是日志框架Log4j的一个特定版本,即1.2.17。Log4j是Apache软件基金会开发的一个用于Java应用程序的日志记录工具,它提供了灵活的日志记录功能,...

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

    总的来说,`log4j.properties`是Log4j的核心,通过灵活配置,可以满足不同项目的需求,无论是简单的调试还是复杂的日志管理,都能得心应手。了解并熟练掌握这个配置文件,对于提升Java项目的可维护性和问题排查效率...

    log4j-1.2.15.jar

    《深入理解Log4j 1.2.15.jar:日志管理的基石》 在IT行业中,日志管理是一项至关重要的任务,它对于系统监控、故障排查以及性能优化起着不可忽视的作用。Log4j作为Java平台上的一个经典日志记录框架,因其强大的...

    Log4j将System.out搞到log4j中输出四

    在《Log4j将System.out搞到log4j中输出四》这篇博文中,作者可能详细讨论了这些步骤,并可能分享了一些实战经验。通过学习这篇博文,读者可以更深入地了解如何在实际项目中实现这一转换,提升日志管理的效率。 总结...

    log4j jar包

    《深入理解Log4j:Apache日志框架的基石》 在Java编程领域,日志记录是不可或缺的一部分,它为开发者提供了程序运行时的详细信息,帮助调试和追踪问题。而Log4j,作为Apache软件基金会的一个项目,是Java平台上的一...

    log4j实用配置扩展

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

    log4j简单demo

    **Log4j组件介绍** 1. **配置文件(Config File)**:Log4j的核心在于其配置文件,通常为`log4j.properties`或`log4j.xml`。这个文件定义了日志输出的级别、格式、目的地等。 2. **Logger**:Logger是日志系统中的...

    Log4j2介绍和使用

    **Log4j2介绍** Log4j2是Apache软件基金会的一个开源项目,它是一个用于日志记录的Java框架。作为Log4j的升级版本,Log4j2在性能、灵活性和可配置性方面都有显著提升。它提供了丰富的日志级别(如DEBUG、INFO、WARN...

    log4j-1.2.16下载

    四、Log4j-1.2.16的优化与维护 1. **日志级别管理**:在生产环境中,通常会将日志级别设置为WARN或ERROR,以减少不必要的日志输出,提高性能。 2. **日志分割**:为了便于管理和分析,可以配置Log4j按日期分割日志...

    Log4j2结合Slf4j配置使用

    Log4j2 结合 Slf4j 配置使用 Log4j2 是一个功能强大且广泛使用的日志记录工具,它提供了灵活的日志记录机制和高性能的日志记录能力。Slf4j 则是一个简单的日志记录门面,提供了统一的日志记录接口。今天,我们将...

    log4j多个简单实例

    本篇文章将深入探讨Log4j的多个简单实例,帮助你理解和掌握其基本用法。 首先,Log4j由三个主要组件构成:配置器(Configuration)、日志器(Logger)和布局(Layout)。配置器定义了日志信息的输出格式和位置;...

    log4j.1.2.17

    本文将重点围绕Log4j 1.2.17版本展开,详细介绍其核心概念、使用方法以及配置细节。 1. **Log4j简介** Log4j是Apache组织提供的一款开源日志框架,最初由Ceki Gülcü设计。它为Java应用程序提供了丰富的日志功能...

    [简单]log4jdbc-log4j2配置简记

    标题中的“log4jdbc-log4j2配置简记”指的是在Java开发中使用log4jdbc-log4j2库来监控和记录SQL查询的过程。log4jdbc是一个开源项目,它允许开发者通过日志系统来追踪数据库操作,而log4j2是log4j的升级版,提供了更...

    log4j的简单介绍

    Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;

    log4j 1.2.17版本jar包

    **日志框架Log4j详解** Log4j是Apache组织提供的一款开源的日志记录框架,广泛应用于Java应用程序中。在1.2.17版本中,Log4j为开发者提供了强大的日志处理能力,帮助他们追踪程序运行时的错误、警告和其他相关信息...

    The Complete Log4j Manual

    通常,一本完整的手册会包括以下几个部分:介绍Log4j的基础知识、详细说明如何配置和使用Log4j、示例和最佳实践、高级配置技巧、性能优化建议、以及Log4j的二次开发等方面内容。读者可以根据个人需要,找到对应章节...

Global site tag (gtag.js) - Google Analytics