Apache Log4j 学习笔记

Apache Logging Project Homepage: http://logging.apache.org
Log4j的类图
 
•    Logger - 日志写出器,供程序员输出日志信息
•    Appender - 日志目的地,把格式化好的日志信息输出到指定的地方去
•    ConsoleAppender - 目的地为控制台的Appender
•    FileAppender - 目的地为文件的Appender
•    RollingFileAppender - 目的地为大小受限的文件的Appender
•    Layout - 日志格式化器,用来把程序员的logging request格式化成字符串
•    PatternLayout - 用指定的pattern格式化logging request的Layout
Logger:日志写出器
Logger对象是用来取代System.out或者System.err的日志写出器,用来供程序员输出日志信息。
Logger的输出方法
Logger类对象提供一系列方法供程序员输出日志信息:
•    public void debug(Object msg);
•    public void debug(Object msg, Throwable t);
•    public void info(Object msg);
•    public void info(Object msg, Throwable t);
•    public void warn(Object msg);
•    public void warn(Object msg, Throwable t);
•    public void error(Object msg);
•    public void error(Object msg, Throwable t);
•    public void fatal(Object msg);
•    public void fatal(Object msg, Throwable t);
Logger的命名规则
Logger由一个String类的名字识别,logger的名字是大小写敏感的,且名字之间具有继承的关系,子名有父名作为前缀,用点号.分隔。如:x.y是x.y.z的父亲。
根logger (root logger)是所有logger的祖先,它具有如下属性:1) 它总是存在的;2) 它不可以通过名字获得。
通过调用public static Logger Logger.getRootLogger()获得root logger;通过调用public static Logger Logger.getLogger(String name)或者public static Logger Logger.getLogger(Class clazz)获得(或者创建)一个named logger。后者相当于调用Logger.getLogger(clazz.getName())。
在某对象中,用该对象所属的类为参数,调用Logger.getLogger(Class clazz)以获得logger被认为是目前所知的最理智的命名logger的方法。
Log level
每个logger都被分配了一个日志级别 (log level),用来控制日志信息的输出。未被分配level的logger将继承它最近的父logger的level。
每条输出到logger的日志请求(logging request)也都有一个level,如果该request的level大于等于该logger的level,则该request将被处理(称为enabled);否则该request将被忽略。故可得知:
•    logger的level越低,表示该logger越详细
•    logging request的level越高,表示该logging request越优先输出
Level类中预定义了五个level,它们的大小关系如下:
 Level.DEBUG < Level.INFO < Level.WARN < Level.ERROR < Level.FATAL
          
示例代码
以下代码将用自己所属的类为参数,创建一个logger,启用默认配置,设置其level并向其输出若干logging request。
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;

public class Log4jTest {
    public static void main(String argv[]) {
    
        // Create a logger by the name of class Log4jTest.
        Logger logger = Logger.getLogger(Log4jTest.class);

        // Use the default configuration.
        BasicConfigurator.configure();

        // Set the logger level to Level.INFO
        logger.setLevel(Level.INFO);

        // This request will be disabled since Level.DEBUG < Level.INFO.
        logger.debug("This is debug.");

        // These requests will be enabled.
        logger.info("This is an info.");
        logger.warn("This is a warning.");
        logger.error("This is an error.");
        logger.fatal("This is a fatal error.");
        
        return;
    }
}
          
关于logger的两点说明
•    用同名参数调用Logger.getLogger(String name)将返回同一个logger的引用。故可以在一个地方配置logger,在另外一个地方获得配置好的logger,而无须相互间传递logger的引用。
•    logger的创建可以按照任意的顺序,即,父logger可以后于子logger被创建。log4j将自动维护logger的继承树。
Appender:日志目的地
每个logger都可以拥有一个或者多个appender,每个appender表示一个日志的输出目的地,比如console或者某个文件。可以使用Logger.addAppender(Appender app)为logger增加一个appender;可以使用Logger.removeAppender(Appender app)为logger移除一个appender。
默认情况下,logger的additive标志被设置为true,表示子logger将继承父logger的所有appenders。该选项可以被重新设置,表示子logger将不再继承父logger的appenders。
root logger拥有目标为system.out的consoleAppender,故默认情况下,所有的logger都将继承该appender。
// Log4j APIs : class Logger
      
// 为logger对象增加或者移除一个Appender对象
public void appAppender(Appender app);
public void removeAppender(Appender app);

// 获得和设置additive标志:是否继承父logger的appenders
// 注意:在设置additive标志为false时,必须保证已经为该logger设置了新的appender,
// 否则log4j将报错:log4j:WARN No appenders could be found for logger (x.y.z).
public boolean getAdditivity();
public void setAdditivity(boolean additive);
        
ConsoleAppender
可以使用ConsoleAppender对象把日志输出到控制台。每个ConsoleAppender都有一个target,表示它的输出目的地。它可以是System.out,标准输出设备(缓冲显示屏);或者是System.err,标准错误设备(不缓冲显示屏)。ConsoleAppender的使用方法参考如下API:
// Log4j APIs : class ConsoleAppender extends WriterAppender
      
// 构造方法,使用一个Layout对象构造一个ConsoleAppender对象
// 默认情况下,ConsoleAppender的target是System.out
public ConsoleAppender(Layout layout);

// 构造方法,使用一个Layout对象和一个target字符串构造ConsoleAppender对象
// target的可能取值为ConsoleAppender.SYSTEM_OUT和ConsoleAppender.SYSTEM_ERR
public ConsoleAppender(Layout layout, String target);
          
FileAppender
可以使用FileAppender对象把日志输出到一个指定的日志文件中去。使用方法可以参考如下的API:
// Log4j APIs : class FileAppender extends WriterAppender
      
// 构造方法,使用一个Layout对象和日志文件名构造一个FileAppender对象
public FileAppender(Layout layout, String filename)
throws IOException;
public FileAppender(Layout layout, String filename, boolean append)
throws IOException;
          
RollingFileAppender
可以使用FileAppender的子类RollingFileAppender对象,把日志输出到一个指定的日志文件中。不同的是该日志文件的大小受到限制,当日志内容超出最大的尺寸时,该文件将向上滚动(最老的日志被擦除)。还可以在该类对象中指定为日志文件做多少个备份。具体使用方法参考如下API:
// Log4j APIs : class RollingFileAppender extends FileAppender
      
// 构造方法,使用一个Layout对象和日志文件名构造一个RollingFileAppender对象
public RollingFileAppender(Layout layout, String filename)
throws IOException;
public RollingFileAppender(Layout layout, String filename, boolean append)
throws IOException;

// 获得和设置日志备份文件的个数
public int getMaxBackupIndex();
public void setMaxBackupIndex(int index);

// 获得和设置滚动日志文件的最大尺寸
public long getMaximumFileSize();
public void setMaximumFileSize(long size);
          
Layout:日志格式化器
每个appender都和一个layout相联系;layout的任务是格式化用户的logging request,appender的任务是把layout格式化好的输出内容送往指定的目的地。
PatternLayout
PatternLayout是Layout的一个子类,用来使用类似C语言的printf函数中使用的格式控制字符串来控制日志的输出格式。使用方法参考如下API:
// Log4j APIs : class PatternLayout extends Layout
      
// 无参数构造方法,使用DEFAULT_CONVERSION_PATTERN构造一个PatternLayout
// 注意:DEFAULT_CONVERSION_PATTERN为"%m%n",只打印消息信息
public PatternLayout();

// 构造方法,使用自定义的pattern构造一个PatternLayout
public PatternLayout(String pattern);

// 获得和设置PatternLayout对象的日志pattern
public String getConversionPattern();
public void setConversionPattern(String pattern);
          
patterns in PatternLayout
c  category的名称,可使用{n}限制输出的精度。例如:logger名为"a.b.c",%c{2}将输出"b.c"。

C  产生log事件的java完全限定类名。可使用{n}限制输出的精度。例如:“org.apache.xyz.SomeClass”,%C{2}将输出“SomeClass”。

d  时间和日期的输出格式,例如:%d{yyyy MM dd HH:mm:ss,SS},可不带后面的日期格式字符。

F  产生log事件的java源文件名,带“.java”后缀及包名称。

l  log发生位置的详细描述,包括方法名、文件名及行号。

L  log发生在源文件中的位置。

m  log事件的消息内容。

M  log发生时所在的方法名称。

n  根据所运行的平台输出相应的行分隔字符。

p  log事件的级别。

r  自程序运行至log事件产生所经过的时间。

t  产生log的线程名称。

x

X

%  “%%”将输出单个“%”。

Configuration:配置
对log4j环境的配置就是对root logger的配置,包括把root logger设置为哪个级别(level);为它增加哪些appender,等等。这些可以通过设置系统属性的方法来隐式地完成,也可以在程序里调用XXXConfigurator.configure()方法来显式地完成。
默认的log4j初始化过程
Logger类的静态初始化块(static initialization block)中对log4j的环境做默认的初始化。注意:如果程序员已经通过设置系统属性的方法来配置了log4j环境,则不需要再显式地调用XXXConfigurator.configure()方法来配置log4j环境了。
Logger的静态初始化块在完成初始化过程时将检查一系列log4j定义的系统属性。它所做的事情如下:
•    检查系统属性log4j.defaultInitOverride,如果该属性被设置为false,则执行初始化;否则(只要不是false,无论是什么值,甚至没有值,都是否则),跳过初始化。
•    把系统属性log4j.configuration的值赋给变量resource。如果该系统变量没有被定义,则把resource赋值为"log4j.properties"。注意:在apache的log4j文档中建议使用定义log4j.configuration系统属性的方法来设置默认的初始化文件是一个好方法。
•    试图把resource变量转化成为一个URL对象url。如果一般的转化方法行不通,就调用org.apache.log4j.helpers.Loader.getResource(resource, Logger.class)方法来完成转化。
•    如果url以".xml"结尾,则调用方法DOMConfigurator.configure(url)来完成初始化;否则,则调用方法PropertyConfigurator.configure(url)来完成初始化。如果url指定的资源不能被获得,则跳出初始化过程。
BasicConfigurator.configure()
BasicConfigurator.configure()方法使用最简的方法配置log4j环境。注:所谓配置log4j环境,就是指配置root logger,因为所有其它的logger都是root logger的后代,所以它们(默认情况下)都将继承root logger的性质。
BasicConfigurator.configure()完成的任务是:
•    用默认pattern创建PatternLayout对象p:
PatternLayout p = new PatternLayout("%-4r[%t]%-5p%c%x - %m%n");
•    用p创建ConsoleAppender对象a,目标是system.out,标准输出设备:
ConsoleAppender a = new ConsoleAppender(p,ConsoleAppender.SYSTEM_OUT);
•    为root logger增加一个ConsoleAppender p:
rootLogger.addAppender(p);
•    把root logger的log level设置为DEBUG级别:
rootLogger.setLevel(Level.DEBUG);
xml格式的log4j配置文件概述
xml格式的log4j配置文件需要使用org.apache.log4j.xml.DOMConfigurator.configure()方法来读入。对xml文件的语法定义可以在log4j的发布包中找到:org/apache/log4j/xml/log4j.dtd。
log4j的xml配置文件的树状结构
log4j的xml配置文件的树状结构如下所示,注意下图只显示了常用的部分。
xml declaration and DTD
 |
log4j:configuration
 |
 +-- appender (name, class)
 |     |
 |     +-- param (name, value)
 |     +-- layout (class)
 |           |
 |           +-- param (name, value)
 +-- logger (name, additivity)
 |     |
 |     +-- level (class, value)
 |     |     |
 |     |     +-- param (name, value)
 |     +-- appender-ref (ref)
 +-- root
 |
 +-- param (name, class)
 +-- level
 |     |
 |     +-- param (name, value)
 +-- appender-ref (ref)  
          
xml declaration and DTD
xml配置文件的头部包括两个部分:xml声明和DTD声明。头部的格式如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
          
log4j:configuration (root element)
•    xmlns:log4j [#FIXED attribute] : 定义log4j的名字空间,取定值"http://jakarta.apache.org/log4j/"
•    appender [* child] : 一个appender子元素定义一个日志输出目的地
•    logger [* child] : 一个logger子元素定义一个日志写出器
•    root [? child] : root子元素定义了root logger
appender
appender元素定义一个日志输出目的地。
•    name [#REQUIRED attribute] : 定义appender的名字,以便被后文引用
•    class [#REQUIRED attribute] : 定义appender对象所属的类的全名
•    param [* child] : 创建appender对象时传递给类构造方法的参数
•    layout [? child] : 该appender使用的layout对象
layout
layout元素定义与某一个appender相联系的日志格式化器。
•    class [#REQUIRED attribute] : 定义layout对象所属的类的全名
•    param [* child] : 创建layout对象时传递给类构造方法的参数
logger
logger元素定义一个日志输出器。
•    name [#REQUIRED attribute] : 定义logger的名字,以便被后文引用
•    additivity [#ENUM attribute] : 取值为"true"(默认)或者"false",是否继承父logger的属性
•    level [? child] : 定义该logger的日志级别
•    appender-ref [* child] : 定义该logger的输出目的地
root
root元素定义根日志输出器root logger。
•    param [* child] : 创建root logger对象时传递给类构造方法的参数
•    level [? child] : 定义root logger的日志级别
•    appender-ref [* child] : 定义root logger的输出目的地
level
level元素定义logger对象的日志级别。
•    class [#IMPLIED attribute] : 定义level对象所属的类,默认情况下是"org.apache.log4j.Level类
•    value [#REQUIRED attribute] : 为level对象赋值。可能的取值从小到大依次为"all"、"debug"、"info"、"warn"、"error"、"fatal"和"off"。当值为"off"时表示没有任何日志信息被输出
•    param [* child] : 创建level对象时传递给类构造方法的参数
appender-ref
appender-ref元素引用一个appender元素的名字,为logger对象增加一个appender。
•    ref [#REQUIRED attribute] : 一个appender元素的名字的引用
•    appender-ref元素没有子元素
param
param元素在创建对象时为类的构造方法提供参数。它可以成为appender、layout、filter、errorHandler、level、categoryFactory和root等元素的子元素。
•    name and value [#REQUIRED attributes] : 提供参数的一组名值对
•    param元素没有子元素
在xml文件中配置appender和layout
创建不同的Appender对象或者不同的Layout对象要调用不同的构造方法。可以使用param子元素来设定不同的参数值。
创建ConsoleAppender对象
ConsoleAppender的构造方法不接受其它的参数。
... ... ... ...
<appender name="console.log" class="org.apache.log4j.ConsoleAppender">
  <layout ... >
    ... ...
  </layout>
</appender>
... ... ... ...
          
创建FileAppender对象
可以为FileAppender类的构造方法传递两个参数:File表示日志文件名;Append表示如文件已存在,是否把日志追加到文件尾部,可能取值为"true"和"false"(默认)。
... ... ... ...
<appender name="file.log" class="org.apache.log4j.FileAppender">
  <param name="File" value="/tmp/log.txt" />
  <param name="Append" value="false" />
  <layout ... >
    ... ...
  </layout>
</appender>
... ... ... ...
          
创建RollingFileAppender对象
除了File和Append以外,还可以为RollingFileAppender类的构造方法传递两个参数:MaxBackupIndex备份日志文件的个数(默认是1个);MaxFileSize表示日志文件允许的最大字节数(默认是10M)。
... ... ... ...
<appender name="rollingFile.log" class="org.apache.log4j.RollingFileAppender">
  <param name="File" value="/tmp/rollingLog.txt" />
  <param name="Append" value="false" />
  <param name="MaxBackupIndex" value="2" />
  <param name="MaxFileSize" value="1024" />
  <layout ... >
    ... ...
  </layout>
</appender>
... ... ... ...
          
创建PatternLayout对象
可以为PatternLayout类的构造方法传递参数ConversionPattern。
... ... ... ...
<layout class="org.apache.log4j.PatternLayout>
  <param name="Conversion" value="%d [%t] %p - %m%n" />
</layout>
... ... ... ...
          
我自己的一个使用xml文件配置log4j环境的很简单的例子
为WSOTA(Web Services Over The Air)项目开发java web start的胖客户端时,使用了如下的xml文件配置log4j环境(文件名为wsota-rc.log4j.xml):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

  <!-- ================================================================= -->
  <!--                     a rolling file appender                       -->
  <!-- ================================================================= -->
  <appender name="wsota-rc.file.log" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="/tmp/wsota-rc.log" />
    <param name="Append" value="false" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %p - %m%n" />
    </layout>
  </appender>

  <!-- ================================================================= -->
  <!--                       a console appender                          -->
  <!--     debug can be turned off by setting level of root to "off"     -->
  <!-- ================================================================= -->
  <appender name="wsota-rc.console.log" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %p - %m%n" />
    </layout>
  </appender>

  <!--  use this to turn on debug to a rolling file. -->
  <root>
    <level value="debug" />
    <appender-ref ref="wsota-rc.file.log" />
  </root>

  <!--  use this to turn on debug to console. -->
  <!--
  <root>
    <level value="off" />
    <appender-ref ref="wsota-rc.console.log" />
  </root>
  -->

  <!--  use this to turn off debug. -->
  <!--
  <root>
    <level value="off" />
    <appender-ref ref="wsota-rc.console.log" />
  </root>
  -->

</log4j:configuration>
        
在胖客户程序中使用了如下代码来使用外部xml文件配置log4j环境,注意该代码段位于程序的main class的静态初始化块中,含有以下代码的类和xml配置文件在同一个目录下:
import org.apache.log4j.xml.DOMConfigurator;
 
public class SapFrame extends JFrame {
    static {
        DOMConfigurator.configure(SapFrame.class.getResource("wsota-rc.log4j.xml"));
    }
    ... ... ... ...
}
        
Log4j的编码习惯
•    让每个类都拥有一个private static的Logger对象,用来输出该类中的全部日志信息
•    使用xml文件来完成对log4j环境的配置。在项目的main class中的静态初始化块里放log4j环境的配置代码。注意:在一个项目中,log4j环境只需要被配置一次,而不是在每个使用了logger的类里都需要调用一次
•    用MyClass.class作为参数创建该类的静态Logger对象
Fixme (heavyz)
To add more...
参考资料
Log4J使用完全手册
Log4J是Apache的一个开放源代码项目(http://logging.apache.org/log4j/docs/),它是一个日志操作包。通过使用Log4J,可以指定日志信息输出的目的地,控制每一条日志的输出格式,定义日志信息的级别。所有这些功能通过一个配置文件灵活进行配置。
一、LOG4J组成
  LOG4J主要由三大组件组成:
  . Logger: 决定什么日志信息应该被输出、什么日志信息应该被忽略;
  . Appender: 指定日志信息应该输出到什么地方, 这些地方可以是控制台、文件、网络设备;
  . Layout: 指定日志信息的输出格式;
  一个Logger可以有多个Appender,也就是说日志信息可以同时输出到多个设备上,每个Appender对应
  一种Layout(示例见下图)。
        ↗ Appender1 → Layout
  /   
  Logger
  ﹨
        ↘ Appender2 → Layout

二、Logger组件
  1. Logger组件提供的方法:
    Logger组件是LOG4J的核心组件,它代表了Log4J的日志记录器,它能够对日志信息进行分类筛选。它由org.apache.log4j.Logger类实现,提供了如下方法:

java 代码
package org.apache.log4j;   
 
public class Logger {   
 
      // Creation & retrieval methods:   
      public static Logger getRootLogger();   
      public static Logger getLogger(String name);   
 
      // 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);   
    
      // generic printing method:   
      public void log(Priority p, Object message);   
}   
  2. 在配置文件中配置Logger组件
    可在Log4J配置文件中配置自己的Logger组件,示例:
    log4j.logger.myLogger=WARN
    以上代码定义了一个Logger组件,名称为myLogger,日志级别为WARN。

  3. 日志级别种类:
    一共有五种,级别由高到低依次是:fatal、error、warn、info、debug。获得Logger实例后,我们可调用以下方法之一输出日志信息:
    public void debug(Object message);       //输出debug级别的日志信息;
    public void info(Object message);       //输出info级别的日志信息;
    public void warn(Object message);       //输出warn级别的日志信息;
    public void error(Object message);       //输出error级别的日志信息;
    public void fatal(Object message);       //输出fatal级别的日志信息;
    public void log(Priority p, Object message);//输出参数Priority指定级别的日志信息;
    以上方法只有当它的级别大于或等于Logger组件配置的日志级别时才调用。以前面我们配置的myLogger为例,它的日志级别为WARN, 那么在程序中,它的warn()、error()、fatal()方法会被执行。对于log()方法,只有当它的参数Priority指定的日志级别大于或等于WARN时,它才会被执行。
  4. 为什么需要对日志进行分级?
 
    在写程序的时候,为了调试程序,我们会在很多出错的地方输出大量的日志信息。当程序调试完,不需要这些信息时,将程序中这些输出日志信息代码删除吗?这样费时费力,对于大型程序几乎不可行。通过对日志分级,假如不想输出WARN级别的日志信息,则Logger组件的级别调高即可,省时省心。
  5. Logger组件的继承性
    Log4J提供了一个root Logger,它是所有Logger组件的“祖先”,它永远存在,且不能通过名字检索或引用,通过Logger.getRootLogger()方法取得它。配置root Logger代码:
    log4j.rootLogger=INFO,console
    可在配置文件中方便地配置存在继承关系的Logger组件,凡是在符号“.”后面的组件都会成为在符号“.”前面的Logger组件的子类。例如:
    log4j.apache.myLogger=WARN
    log4j.apache.myLogger.mySonLogger=,file
    以上代码中, mySonLogger是myLogger的子类Logger组件。Logger组件的继承关系:
    . 如果子类Logger组件没有定义日志级别,则将继承父类的日志级别;
    . 如果子类Logger组件定义了日志级别,就不会继承父类的日志级别;
    . 黙认情况下,子类Logger组件会继承父类所有的Appender,把它们加入到自己的Appener;
    . 如果把子类Logger组件的additivity标志设为false,那么它就不会继承父类Appender。additivity标志 默认值为false;
    以上配置的三个Logger继承关系示例如图:
 
    root Logger: 日志级别=INFO appender清单=console
                  ↑
    myLogger: 日志级别=WARN appender清单=null
                  ↑
    mySonLogger: 日志级别=null appender清单=file
    这三个Logger组件实际日志级别和Appender如下表:
    Logger组件       日志级别       Appender清单
    root Logger       INFO         console
    myLogger         WARN         console(继承)
    mySonLogger       WARN(继承)     file,console(继承)
    
三、Appender组件
  Appender组件决定将日志信息输出到什么地方。支持以下目的地:
  . 控制台(Console);
  . 文件(File);
  . GUI组件(GUI component);
  . 套接口服务器(Remote socket server);
  . NT的事件记录器(NT Event Logger);
  . UNIX Syslog守护进程(Remote UNIX Syslog daemon);
  一个Logger可同时对应多个Appender,示例:myLogger配置二个Appender: 一个file, 一个是console:
  log4j.logger.myAppender=WARN,file,console
  log4j.appender.file=org.apache.log4j.RollingFileAppender
  log4j.appender.file.File=log.txt
  log4j.apender.console=org.apache.log4j.ConsoleAppender
四、Layout组件
  Layout组件决定日志输出格式,有以下几种类型:
  . org.apache.log4j.HTMLLayout(以HTML表格形式布局);
  . org.apache.log4j.PatternLayout(可以灵活地指定布局模式);
  . org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串);
  . org.apache.log4j.TTCCLayout(包含日志产生的时间、线程和类别等信息);
 
  为名称为console的Appender配置SimpleLayout,代码如下:
  log4j.appender.console.layout=org.apache.log4j.SimpleLayout
  输出日志格式如下:
  WARN - This is a log message from the myLogger
 
  为名称为file的Appender配置PatternLayout,代码如下:
  log4j.appender.file.layout=org.apache.log4j.PatternLayout
  log4j.appender.file.layout.ConversionPattern=%t %p - %m%n
  输出日志格式如下:
  THREAD-1 WARN - This is a log message from the myLogger
  PatternLayout让开发者依照ConversionPattern定义输出格式。ConversionPattern中一些指定日志内容和格式的预定义符号说明如下:
  符号       描述
  %r       自程序开始后消耗的毫秒数
  %t       表示日志记录请求生成的线程
  %p       表示日专语句的优先级
  %r       与日志请求相关的类别名称
  %c       日志信息所在的类名
  %m%n       表示日志信息的内容
五、Log4J的基本用法
  1. 定义配置文件
    Log4J支持二种配置文件格式:XML和Java属性文件(采用“键=值”形式)。以下为Java属性文件
    格式配置文件:
    
    . 配置Logger组件
      
      配置root Logger语法为:log4j.rootLogger=[priority],appenderName,appenderName,...
      配置自定义Logger组件语法为:log4j.logger.loggerName=[priority],appenderName,appenderName,...
      其中:priority为日志级别,可选值包括FATAL、ERROR、WARN、INFO、DEBUG、ALL;
          appenderName指定Appender组件,可指定多个;       
    . 配置Appender组件
      配置日志信息输出目的地Appender, 语法为:
      log4j.appender.appenderName=fully.ualified.name.of.appender.class
      log4j.appender.appenderName.option1=value1
      ...
      log4j.appender.appenderName.optionN=valueN
      Log4J提供的Appender有以下几种:
      a. org.apache.log4j.ConsoleAppender(控制台);
      b. org.apache.log4j.FileAppender(文件);
      c. org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件);
      d. org.apache.log4j.RollingFileAppender(文件大小到指定尺寸产生一个新的文件);
      e. org.apache.log4j.WriteAppender(将日志信息以流格式发送到任意指定地方);
    . 配置Layout组件
      配置Layout组件语法为:
      log4j.appender.appenderName.layout=fully.ualified.name.of.appender.class
      log4j.appender.appenderName.layout.option1=value1
      ...
      log4j.appender.appenderName.layout.optionN=valueN
      下面为一配置文件示例,文件名为log4j.properties:
      ## LOGGERS ##
      #configure root logger
      log4j.rootLogger=INFO,console
      #define a logger named myLogger
      log4j.logger.myLogger=WARN
      #define a second logger that is a child to myLogger
      log4j.logger.myLogger.mySonLogger=,file
      ## APPENDERS ##
      #define an appender named console, which is set to be a ConsoleAppender
      log4j.appender.console=org.apache.log4j.ConsoleAppender
      # define an appender named file, which is set to be a RollingFileAppender
      log4j.appender.file=org.apache.log4j.FileAppender
      log4j.appender.file.File=log.txt
      ## LAYOUTS ##
      # assian a SimpleLayout to console appender
      log4j.appender.console.layout=org.apache.log4j.SimpleLayout
      # assian a PatternLayout to file appender
      log4j.appender.file.layout=org.apache.log4j.PatternLayout
      log4j.appender.file.layout.ConversionPattern=%t%p-%m%n
      
  2. 程序中使用Log4j
    . 获得日志记录器:
      获得rootLogger:Logger rootLogger=Logger.getRootLogger();
      获得自定义Logger:Logger myLogger = Logger.getLogger("log4j.logger.myLogger");
    . 读取日志记录器,配置Log4J环境;
      a. BasicConfigurator.configure(): 自动快速地使用默认Log4J环境;
      b. Property.configurator.configure(String configFilename): 读取使用Java属性格式的配置文件并配置Log4J环境;
      c. DOMConfigurator.configure(String filename): 读取XML形式的配置文件并配置LOG4J环境;
    . 输出日志信息;
      在程序代码中需要生成日志的地方,调用Logger的各种输出日志方法输出不同级别的日志,例如:
      
      myLogger.debug("Thie is a log message from the " + myLogger.getName());
      下面为一使用Log4J的程序,程序名为Test.java:
java 代码
import org.apache.log4j.Logger;   
import org.apache.log4j.PropertyConfigurator;   
 
public class Test {   
 
  public static void main(String[] args) {   
  //Get an instance of the myLogger   
  Logger myLogger = Logger.getLogger("myLogger");   
    
  //Get an instance of the childLogger   
  Logger mySonLogger = Logger.getLogger("myLogger.mySonLogger");   
  //Load the proerties using the PropertyConfigurator   
  PropertyConfigurator.configure("log4j.properties");   
 
  //Log Messages using the Parent Logger   
  myLogger.debug("Thie is a log message from the " + myLogger.getName());   
  myLogger.info("Thie is a log message from the " + myLogger.getName());   
  myLogger.warn("Thie is a log message from the " + myLogger.getName());   
  myLogger.error("Thie is a log message from the " + myLogger.getName());   
  myLogger.fatal("Thie is a log message from the " + myLogger.getName());   
 
  mySonLogger.debug("Thie is a log message from the " + mySonLogger.getName());   
  mySonLogger.info("Thie is a log message from the " + mySonLogger.getName());   
  mySonLogger.warn("Thie is a log message from the " + mySonLogger.getName());   
  mySonLogger.error("Thie is a log message from the " + mySonLogger.getName());   
  mySonLogger.fatal("Thie is a log message from the " + mySonLogger.getName());   
  }   
}   
    程序运行结果为:
    WARN - Thie is a log message from the myLogger
    ERROR - Thie is a log message from the myLogger
    FATAL - Thie is a log message from the myLogger
    WARN - Thie is a log message from the myLogger.mySonLogger
    ERROR - Thie is a log message from the myLogger.mySonLogger
    FATAL - Thie is a log message from the myLogger.mySonLogger
    另在Test.class所在的目录下看到一个log.txt文件,内容如下:
    WARN - Thie is a log message from the myLogger.mySonLogger
    ERROR - Thie is a log message from the myLogger.mySonLogger
    FATAL - Thie is a log message from the myLogger.mySonLogger
    如将配置文件log4j.properties中语句
log4j.logger.myLogger.mySonLogger=,file
改为
log4j.logger.myLogger.mySonLogger=,file,console
再次运行程序,结果如下:
    WARN - Thie is a log message from the myLogger
    ERROR - Thie is a log message from the myLogger
    FATAL - Thie is a log message from the myLogger
    WARN - Thie is a log message from the myLogger.mySonLogger
    WARN - Thie is a log message from the myLogger.mySonLogger
    ERROR - Thie is a log message from the myLogger.mySonLogger
    ERROR - Thie is a log message from the myLogger.mySonLogger
    FATAL - Thie is a log message from the myLogger.mySonLogger       
    FATAL - Thie is a log message from the myLogger.mySonLogger
    mySonLogger的日志在控制台上输出了二次,这是因为mySonLogger继承了父类console Appender,
    本身又定义了一个console Appender, 因而有二个console Appender。
六、在web应用中使用Log4J
  创建一个Servlet,在它初始化方法中读取Log4J配置文件并配置Log4J环境,这个Servlet在Web应用启
  动时候被加载和初始化,然后就可在其它Web组件中获取Logger对象并输出日志。
  1. 创建用于配置Log4J环境的Servlet
java 代码
import javax.servlet.*;   
import javax.servlet.http.*;   
import java.io.*;   
import java.util.*;   
 
import org.apache.log4j.PropertyConfigurator;   
 
public class Log4JServlet extends HttpServlet {   
    public void init() throws ServletException {   
      String path = getServletContext().getRealPath("/");   
      //getInitParameter("propfile")方法从web.xml文件中读取Log4J配置文件的名字"profile"。   
      String propfile = path + getInitParameter("propfile");   
      PropertyConfigurator.configure(propfile);   
    }   
}   
 
    该Servlet在web.xml中的配置如下:

xml 代码
<servlet>   
<servlet-name>log4jServlet</servlet-name>   
<servlet-class>Log4JServlet</servlet-class>   
<init-param>   
  <param-name>propfile</param-name>   
  <param-value>/WEB-INF/log4j.properties</param-value>   
</init-param>   
<load-on-startup>1</load-on-startup>   
</servlet>   
2. 在login.jsp中输出日志
    <[url=mailto:%@page]%@page import="org.apache.log4j.Logger"%>
    <html>
      <head>
      <title>login</title>
      </head>
      <body>
      <%
        Logger myLogger = Logger.getLogger("myLogger");
        Logger mySonLogger = Logger.getLogger("myLogger.mySonLogger");
        myLogger.debug("Thie is a log message from the " + myLogger.getName());
        myLogger.info("Thie is a log message from the " + myLogger.getName());
        myLogger.warn("Thie is a log message from the " + myLogger.getName());
        myLogger.error("Thie is a log message from the " + myLogger.getName());
        myLogger.fatal("Thie is a log message from the " + myLogger.getName());
        mySonLogger.debug("Thie is a log message from the " + mySonLogger.getName());
        mySonLogger.info("Thie is a log message from the " + mySonLogger.getName());
        mySonLogger.warn("Thie is a log message from the " + mySonLogger.getName());
        mySonLogger.error("Thie is a log message from the " + mySonLogger.getName());
        mySonLogger.fatal("Thie is a log message from the " + mySonLogger.getName());
      %>
      <br>
        <form name="loginForm" method="post" action="dispatcher">
        username: <input type="text" name="username">
        <br>
        password: <input type="text" name="password">
        <br>
        <input type="submit" name="submit" value="submit">
      </form>
      </body>
    </html>
          
  3. 发布运行使用Log4J的web应用
    1) 将Log4J的JAR文件拷贝至目录:<WEB应用所在目录>/WEB-INF/lib
    2) 创建Log4J的配置文件log4j.properties, 存放目录为:<WEB应用所在目录>/WEB-INF。内容同前面配置文件示例。
    3) 编译Log4JServlet, 存放至目录: <WEB应用所在目录>/WEB-INF/classes
    4) 修改web.xml文件,加入以下内容:

xml 代码
<servlet>   
<servlet-name>log4jServlet</servlet-name>   
<servlet-class>Log4JServlet</servlet-class>   
<init-param>   
  <param-name>profile</param-name>   
  <param-value>/WEB-INF/log4j.properties</param-value>   
</init-param>   
<load-on-startup>1</load-on-startup>   
</servlet>   
    5) 启动服务器,访问login.jsp页面,在服务器控制台上看到如下日志:
      WARN - Thie is a log message from the myLogger
      ERROR - Thie is a log message from the myLogger
      FATAL - Thie is a log message from the myLogger
      WARN - Thie is a log message from the myLogger.mySonLogger
      ERROR - Thie is a log message from the myLogger.mySonLogger
      FATAL - Thie is a log message from the myLogger.mySonLogger
      另在<WEB应用所在目录>/WEB-INF目录下看到一个log.txt文件,内容如下:
      WARN - Thie is a log message from the myLogger.mySonLogger
      ERROR - Thie is a log message from the myLogger.mySonLogger
      FATAL - Thie is a log message from the myLogger.mySonLogger


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值