背景 最简单的做法就是在代码中嵌入许多的打印语句,但是这样打印语句会充斥代码的主体,显然不是一个好方法。因此,使用成熟的框架例如Log4j,则会更具灵活性。 Log4j简介 Log4j由三个重要的部件构成:记录器(Loggers)、输出源(Appenders)和布局(Layouts)。 记录器按照布局中指定的格式把日志信息写入一个或多个输出源。输出源可以是控制台、文本文件、XML文件或Socket,甚至还可以把信息写入到Windows事件日志或通过电子邮件发送。我们可以通过配置文件来部署这些组件。 其实您也可以完全不使用配置文件,而是在代码中配置Log4j环境。但是,使用配置文件将使您的应用程序更加灵活。本文从描述 log4j 体系结构的主要组件着手。然后是描述基本用法和配置的简单示例。 定义配置文件 一、 配置记录器。 Log4j允许程序员定义多个记录器,每个记录器有自己的名字。但有一个记录器叫根记录器,它永远存在,且不能通过名字检索或引用,在配置文件中,可以如下定义根记录器: log4j.rootLogger = [ level ] , appenderName, appenderName, …
Level是记录器的级别,它是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别:ERROR、WARN、INFO、DEBUG: DEBUG < INFO < WARN < ERROR < FATAL
右边的级别比左边的高。如果一条log信息的级别,大于等于记录器的级别值,那么记录器就会记录它。例如level被设置为INFO级别,那么应用程序中所有的DEBUG的日志信息将不被打印出来。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。 appenderName是输出源的名字,它指定日志信息输出到哪个地方。您可以为一个记录器指定多个输出源。 在一些配置文件中,你可能会看到下面的语句: log4j.rootCategory = [ level ] , appenderName, appenderName, …
在早期的Log4j版本中,org.apache.Category实现了记录器的功能,为了提高向后兼容 性,Logger扩展了Category,因此rootCategory和rootLogger是可以互换的,但最后Category将从类库中删除,因 此请使用Logger类。 除了根记录器之外,log4j允许程序员定义多个记录器,每个记录器有自己的名字: log4j.logger.loggerName = [ level ] , appenderName, appenderName, …
在Log4J中Logger是具有层次关系的,Log4j支持配置的记录器之间的“父子关系”,记录器之间 通过名字来表明隶属关系(或家族关系),它们有一个共同的根,位于最上层,其它Logger遵循类似包的层次:记录器a.b,与记录器a.b.c之间是父 子关系,而记录器a与a.b.c之间是祖先与后代的关系。例如: static Logger root = Logger.getRootLogger();
static Logger log1 = Logger.getLogger("cc");
static Logger log2 = Logger.getLogger("cc.ejb");
static Logger log3 = Logger.getLogger("cc.ejb.my.TestApp");
上面代码中,log1是log2的父亲,是log3的祖先,而root是所有log1、log2、 log3的祖先,它们都从root中继承。所以,一般情况下,仅需要配置好rootLogger,其它子记录器都会从中继承rootLogger的配置。 如果修改了rootLogger的配置,其它所有的子记录器也会继承这种变化。这样就大大地方便了配置。
如果一个应用中包含了上千个类都需要日志,那么我们是否需要配置上千个Logger呢?我们通过一个简 单的办法来解决这个问题: 用每一个java类文件名(包含该类的包名)定义一个记录器,这是一种有用并且直观的记录器实例名的定义方式。例如在配置文件 中定义了一个com.foo的记录器:
log4j.logger.com.foo=WARN
在com.foo中的一个java类bar,我们通过其本类的名字获得一个记录器“com.foo.Bar”:
package com.foo; class Bar{ static Logger log=Logger.getLogger(bar.Class.getName()); ..... } 由于记录器com.foo.Bar 没有指定的级别,它从com.foo(在配置文件中其级别设置成WARN) 继承级别。并且这样我们就能方便的从大量log信息中判断出它们各自的来源。当然了,这不是硬性规定的,实际上Log4j没有对设置记录器的实例名做什么 限制,程序员可以根据自己的喜好随意定义。 二、日志信息输出源Appender 配置日志信息输出源,其语法为: log4j.appender.appenderName = fully.qualified.name.of.appender.class log4j.appender.appenderName.option1 = value1 … log4j.appender.appenderName.option = valueN Log4j提供的appender有以下几种:
请注意,可以通过覆盖缺省行为,这样就不再附加累积的输出源: log4j.additivity.loggerName=false
注意,不要把一个输出源附加到多个记录器上,否则会得到“Attempted to append to closed appender named xxx”的信息。
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
…
log4j.appender.appenderName.layout.option = valueN
其中,Log4j提供的layout有以下几种:
如果采用了PatternLayout, 则Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:
四、例子 log4j.rootLogger=debug, stdout, R log4j.appender.stdout=org.apache.log4j.FileAppender log4j.appender.stdout.File=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Pattern to output the caller's file name and line number. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=example.log log4j.appender.R.MaxFileSize=100KB # Keep one backup file 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.cc.ejb.my=error,out log4j.appender.out=org.apache.log4j.ConsoleAppender log4j.appender.out.layout=org.apache.log4j.PatternLayout log4j.appender.out.layout.ConversionPattern=%p %t %c - %m%n log4j.logger.cc.ejb.my.son=debug log4j.additivity.cc.ejb.my.son=false 在代码中使用Log4j 一、得到记录器 public static Logger getLogger( String name)
通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。Name一般取本类的名字,比如: static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )
二、读取配置文件 //自动快速地使用缺省Log4j环境。 BasicConfigurator.configure (); //读取使用Java的特性文件编写的配置文件 PropertyConfigurator.configure ( String configFilename); //读取XML形式的配置文件 DOMConfigurator.configure ( String filename ); 三、插入记录信息(格式化日志信息) Logger.debug ( Object message ) ;
Logger.info ( Object message ) ;
Logger.warn ( Object message ) ;
Logger.error ( Object message ) ;
四、例子 我们通过下面这个简单的例子,来演示在程序如何使用Log4j,您可以修改配置文件以得到不同日志信息。 package cc.ejb.my; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import my.son.Foo; public class TestApp { static Logger logger=Logger.getLogger(TestApp.class.getName()); public static void main(String[] args) { PropertyConfigurator.configure("log4j.properties"); logger.info("Applcaiton Starts"); logger.warn("Bar Starts"); Bar bar=new Bar(); logger.error("Bar Errors"); bar.doIt(); logger.warn("Bar Exits"); logger.info("Foo Starts"); Foo foo=new Foo(); logger.error("Foo Errors"); foo.doit(); logger.warn("Foo exits "); logger.info("Applcaition Exits"); } } class Bar { static Logger logger = Logger.getLogger(Bar.class.getName()); public void doIt() { logger.debug("Did it again!"); } } package cc.ejb.my.son; import org.apache.log4j.Logger; public class Foo { private Logger log=Logger.getLogger(Foo.class.getName()); public Foo() { log.info("Foo Initialzie"); } public void doit() { log.debug("Do it in Foo"); } } |
log4j 作用及用法
最新推荐文章于 2022-04-07 13:53:29 发布