Log4j (log for java)

来源:互联网 发布:js设置button隐藏 编辑:程序博客网 时间:2024/06/02 03:21

Log4j

Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务 器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就 是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

如何配置Log4j

第一步:加入log4j-1.2.8.jar到lib下

第二步:在CLASSPATH下建立log4j.properties

第三步:相应的修改其中属性,修改之前就必须知道这些都是干什么的,在第二部分讲解。

第四步:在要输出日志的类中加入相关语句:

    定义属性:protected final Log log = LogFactory.getLog(getClass());

    在相应的方法中:

    if (log.isDebugEnabled()) 

    {

       log.debug(“System …..”);

    }

log4j.properties配置文件

log4j.rootCategory=INFO, stdout , R

此句为将等级为INFO的日志信息输出到stdout和R这两个目的地,stdout和R的定义在下面的代码,可以任意起名。等级可分为OFF、 FATAL、ERROR、WARN、INFO、DEBUG、ALL,如果配置OFF则不打出任何信息,如果配置为INFO这样只显示INFO, WARN, ERROR的log信息,而DEBUG信息不会被显示,具体讲解可参照第三部分定义配置文件中的logger。

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

此句为定义名为stdout的输出端是哪种类型,可以是

org.apache.log4j.ConsoleAppender(控制台),

org.apache.log4j.FileAppender(文件),

org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),

org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)

org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

具体讲解可参照第三部分定义配置文件中的Appender。

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

或  log4j.appender.R.layout=org.apache.log4j.PatternLayout

此句为定义名为stdout的输出端的layout是哪种类型,可以是

org.apache.log4j.HTMLLayout(以HTML表格形式布局),

org.apache.log4j.PatternLayout(可以灵活地指定布局模式),

org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),

org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

具体讲解可参照第三部分定义配置文件中的Layout。

log4j.appender.stdout.layout.ConversionPattern= [QC] %p [%t] %C.%M(%L) | %m%n

或  log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n

如果使用pattern布局就要指定的打印信息的具体格式ConversionPattern,打印参数如下:

%m 输出代码中指定的消息

%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL

%r 输出自应用启动到输出该log信息耗费的毫秒数

%c 输出所属的类目,通常就是所在类的全名

%t 输出产生该日志事件的线程名

%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”

%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921

%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。

[QC]是log信息的开头,可以为任意字符,一般为项目简称。

输出的信息

[TS] DEBUG [main] AbstractBeanFactory.getBean(189) | Returning cached instance of singleton bean 'MyAutoProxy'

具体讲解可参照第三部分定义配置文件中的格式化日志信息。

log4j.appender.R=org.apache.log4j.DailyRollingFileAppender

此句与第3行一样。定义名为R的输出端的类型为每天产生一个日志文件。

log4j.appender.R.File=D:/Tomcat 5.5/logs/qc.log

此句为定义名为R的输出端的文件名为D:/Tomcat 5.5/logs/qc.log

可以自行修改。

文章整理:学网 http://www.xue5.com 

 log4j.logger.com. neusoft =DEBUG

指定com.neusoft包下的所有类的等级为DEBUG。

可以把com.neusoft改为自己项目所用的包名。

log4j.logger.com.opensymphony.oscache=ERROR

log4j.logger.net.sf.navigator=ERROR

这两句是把这两个包下出现的错误的等级设为ERROR,如果项目中没有配置EHCache,则不需要这两句。

log4j.logger.org.apache.commons=ERROR

log4j.logger.org.apache.struts=WARN

这两句是struts的包。

 log4j.logger.org.displaytag=ERROR

这句是displaytag的包。(QC问题列表页面所用)

 log4j.logger.org.springframework=DEBUG

此句为Spring的包。

log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN

log4j.logger.org.hibernate=DEBUG

此两句是hibernate的包。

定义配置文件

Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件log4j.propertiesspan(即键-值方式)

下面将介绍使用log4j.properties文件作为配置文件的方法:

、配置根Logger
Logger 负责处理日志记录的大部分操作。
其语法为:
log4j.rootLogger = [ level ] , appenderName, appenderName, …

其 中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义的级别。

Log4j建议只使用四个级别,优 先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定 义了INFO级别,只有等于及高于这个级别的才进行处理,则应用程序中所有DEBUG级别的日志信息将不被打印出来。ALL:打印所有的日志,OFF:关 闭所有的日志输出。 

appenderName就是指定日志信息输出到哪个地方。可同时指定多个输出目的地。

、配置日志信息输出目的地 Appender
Appender 负责控制日志记录操作的输出。
其语法为:
log4j.appender.appenderName = fully.qualified.name.of.appender.class

log4j.appender.appenderName.option1 = value1



log4j.appender.appenderName.optionN = valueN

这里的appenderName为在①里定义的,可任意起名。

其中,Log4j提供的appender有以下几种:
org.apache.log4j.ConsoleAppender(控制台),
org.apache.log4j.FileAppender(文件),
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
org.apache.log4j.RollingFileAppender(文 件大小到达指定尺寸的时候产生一个新的文件),可通过 log4j.appender.R.MaxFileSize=100KB设置文件大小,还可通过 log4j.appender.R.MaxBackupIndex=1设置为保存一个备份文件。
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

例如:log4j.appender.stdout=org.apache.log4j.ConsoleAppender
定义一个名为stdout的输出目的地,ConsoleAppender为控制台。 

、配置日志信息的格式(布局)Layout
Layout 负责格式化Appender的输出。
其语法为:
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class

log4j.appender.appenderName.layout.option1 = value1

log4j.appender.appenderName.layout.optionN = valueN

其中,Log4j提供的layout有以下几种:
org.apache.log4j.HTMLLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:
%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。 

我们在需要输出日志信息的类中做如下的三个工作:
1)导入所有需的commongs-logging类:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; 

2)在自己的类中定义一个org.apache.commons.logging.Log类的私有静态类成员:
private final Log log = LogFactory.getLog(getClass());
LogFactory.getLog()方法的参数使用的是当前类的class。

3)使用org.apache.commons.logging.Log类的成员方法输出日志信息:

if (log.isDebugEnabled())
{  

log.debug("111");
}
if (log.isInfoEnabled())
{
log.info("222");
}
if (log.isWarnEnabled())
{
log.warn("333");
}
if (log.isErrorEnabled())
{
log.error("444");
}
if (log.isFatalEnabled())
{
log.fatal("555")
}   

log4j在初始化的时候 会先在classpath中寻找 log4j.porperties,当找不到该文件时,会接着寻找log4j.xml 

如果采用xml配置的方法,直接放在WEB-INF目录下 

研究一下xml配置文件的书写方式,下面提供一个样例,具体的可以参考 log4j.dtd

通过<logger></logger>的定义可以将各个包中的类日志输出到不同的日志文件中

以下是完整的log4j.xml 

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">    

   

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

        <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">    

            <layout class="org.apache.log4j.PatternLayout">    

                <param name="ConversionPattern"   

                    value="[%d{dd HH:mm:ss,SSS/} %-5p] [%t] %c{2/} - %m%n" />    

            </layout>    

        </appender>    

     

        <appender name="activex_appender" class="org.apache.log4j.DailyRollingFileAppender">    

            <param name="File" value="E:/activex.log" />    

            <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />    

            <layout class="org.apache.log4j.PatternLayout">    

                <param name="ConversionPattern" value="[%d{MMdd HH:mm:ss SSS/} %-5p] [%t] %c{3/} - %m%n" />    

            </layout>    

        </appender>    

            

        <logger name="com.runway.bssp.activeXdemo" additivity="false">    

            <level value="debug" />    

            <appender-ref ref="activex_appender" />    

        </logger>    

        <root>    

            <appender-ref ref="STDOUT"/>    

        </root>    

    </log4j:configuration>   

步骤:

先配置log4i.xml 文件

建好xml文件后 要写一个servlet类继承actionservlet,当工程初始化时自动加载xml配置文件 

最后在web.xml中配置action信息 就可以实现加载

<?xml version="1.0" encoding="GB2312" ?><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

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

 <appender name="FILE“  class="org.apache.log4j.RollingFileAppender">
  <!-- 设置通道file和输出方式:org.apache.log4j.RollingFileAppender -->
  <param name="File" value="D:/zhaotj/all.output.log" /><!-- 设置File参数:日志输出文件名 -->
  <param name="Append" value="true" /><!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
  <param name="MaxBackupIndex" value="10" />
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%p (%c:%L)- %m%n" /><!-- 设置输出文件项目和格式 -->
  </layout>
 </appender>

  <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">  <!-- 设置监视器输出方式 -->
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern"
    value="%-4r [%t] %-5p %c %x - %m%n" />
  </layout>
    <!--滤镜设置输出的级别-->
  <filter class="org.apache.log4j.varia.LevelRangeFilter">
   <param name="levelMin" value="info" />
   <param name="levelMax" value="info" />
   <param name="AcceptOnMatch" value="true" />
  </filter>
 </appender>

 <root> <!-- 设置接收所有输出的通道 -->
  <priority value="info" />
  <appender-ref ref="FILE" /><!-- 与前面的通道id相对应 -->
  <appender-ref ref="STDOUT" />
 </root></log4j:configuration>

写一个servlet类继承actionservlet,工程初始化时自动加载xml配置文件

package com.asiainfo;
import javax.servlet.ServletException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.xml.DOMConfigurator;
import org.apache.struts.action.ActionServlet;

public class ExtendedActionServlet extends ActionServlet {
        private Log log = LogFactory.getLog(this.getClass().getName());

        public ExtendedActionServlet() {}

        public void init() throws ServletException {
            log.info(
                    "Initializing, My MyActionServlet init this System's Const Variable");
            String prefix = this.getServletConfig().getServletContext().getRealPath(
                    "/");//读取项目的路径
            String file = this.getServletConfig().getInitParameter("log4j");
                       //读取log4j相对路径
            String filePath = prefix + file; 
            DOMConfigurator.configure(filePath);//加载.xml文件       
            log.info("Initializing, end My Init");
            super.init();//应用了struts,此方法不能省,ActionServlet覆盖了的此方法中有很多重要操作
        }
}

Log4j.xml路径获取

我们可以看到 在此类中用了相对路径来加载xml的方法,首先通过prefix 读取了项目的路径,然后再通过读取web.xml中的log4j变量,获得log4j.xml的相对路径,两者结合 就是他的绝对路径拉 

Web.xml的配置如下:

<servlet>
  <servlet-name>action</servlet-name>
  <servlet-class> com.asiainfo.ExtendedActionServlet </servlet-class>
  <init-param>
      <param-name>config</param-name>
      <param-value>/WEB-INF/struts-config.xml</param-value>
  </init-param>

          <!-- tsExtend  -->
  <init-param>
      <param-name> config/tsextend </param-name>  <!--设备检测子模块-->
      <param-value> /WEB-INF/tsextend/struts-config.xml </param-value>
  </init-param>
  <init-param>
       <param-name> log4j </param-name>  <!--log4j.xml的路径-->
       <param-value>  /WEB-INF/log4j.xml </param-value>
  </init-param>
  <init-param>
     <param-name> info </param-name>
     <param-value>3</param-value>
  </init-param>
  <init-param>
     <param-name> detail </param-name>
     <param-value> 3 </param-value>
  </init-param>
     <load-on-startup> 0 </load-on-startup>  <!--设置当工程初始时便执行-->

      </servlet>

       <servlet-mapping>
     <servlet-name> action </servlet-name>
     <url-pattern> *.do </url-pattern>
 </servlet-mapping>

Log4j总结

Log4j三大组件

Logger      (~what)记录器

Appender  (~where)日志记录到哪儿

Layout       (~how)用什么格式写入日志

把纪录语句放在代码之中,是一种低端的调试方法,不过有时却不得不 说是很有效,也是必需的。毕竟很多时候,调试器并不见得很适用。特别是在多线程应用程序(multithread application)或分布式应用程序(distributed application) 

经验告诉我们,在软件开发生命周期中,日志系统是一个非常重要的组件。当然,日志系统也有其自身的问题,过多的日志纪录会降低系统运行的速度。

Logger:记录器层次(Logger hierarchy) 

几乎任何纪录日志的API得功能都超越了简单的 System.out.print语句。允许有选择控制的输出日志信息,也就是说,某的时候,一些日志信息允许输出,而另一些则不允许输出。这就假设日志 纪录信息之间是有分别的,根据开发者自己定义的选择标准,可以对日志信息加以分类。

纪录器的命名是依据实体的。形象的解释,比如存在记录器 a.b.c,记录器a.b,记录器a。那么a就是a.b的ancestor,而a.b就是a.b.c的parent,而a.b.c就是a.b的child 

根纪录器(root logger)是记录器层次的顶端。它有两个独特点:

(1)总是存在的

(2)能够被重新找回。可以通过访问类的静态方法 Logger.getRootLogger 重新得到。其他的纪录器通过访问静态方法 Logger.getLogger 被实例话或被得到,这个方法将希望获得的记录器的名称作为参数。一些Logger类的方法描述如下: 

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(Level l, Object message);

 

记录器被赋予级别,这里有一套预定的级别标准:DEBUG, INFO, WARN, ERROR and FATAL ,这些是在 org.apache.log4j.Level 定义的。你可以通过继承Level类定义自己的级别标准,虽然并不鼓励这么做。 

如果给定的记录器没有被赋予级别,则其会从离其最近的拥有级别的ancestor处继承得到。如果ancestor也没有被赋予级别,那么就从根记录器继 承。所以通常情况下,为了让所有的记录器最终都能够被赋予级别,跟记录器都会被预先设定级别的。比如我们在操作properties文件中,会写这么一 句:log4j.rootLogger=DEBUG, A1 。实际上就这就指定了root Logger和root Logger level。

Appenders 

Log4j允许记录信息被打印到多个输出目的地,一个输出目的地叫 做Appender。目前的Log4j存在的输出目的地包括:控制台(Console),文件(File),GUI Componennt,Remote Socket Server,JMS,NT Event Logger,and Remote Unix Syslog daemons。

多个Appender可以绑定到一个记录器上(Logger) 
通过方法 addAppender(Logger.addAppender)可以将一个Appender附加到一个记录器上。每一个有效的发送到特定的记录器的记录请求都被转送到那个与当前记录器所绑定的Appender 上。换句话说,Appender的继承层次是附加在记录器继承层次上的。

举个例子:如果一个Console Appender被绑定到根记录器(root Logger),那么所有的记录请求都可以至少被打印到Console。另外,把一个file Appender绑定到记录器C,那么针对记录器C(或C的子孙)的记录请求都可以至少发送到Console Appender和file Appender。当然这种默认的行为方式可以跟改,通过设定记录器的additivity flag(Logger.setAdditivity)为false,从而可以使得Appender的不再具有可加性(Additivity)。 

下面简要介绍一下Appender Additivity。 
Appender Additivity:记录器C所记录的日志信息将被发送到与记录器C以及其祖先(ancestor)所绑定的所有Appender。 
但是,如果记录器C的祖先,叫做P,它的additivity flag被设定为false。那么,记录信息仍然被发送到与记录器C及其祖先,但只到达P这一层次,包括P在内的记录器的所有Appender。但不包括P祖先的。 
通常,记录器的additivity flag的被设置为true。

Layouts 

这一块主要是介绍输出格式的

PatternLayout是Log4j标准的分配器

可以让开发者依照Conversion patterns去定义输出格式。Conversion patterns有点像c语言的打印函数。 
参看配置文件的java properties,如下面的两行: 
log4j.appender.A1.layout=org.apache.log4j.PatternLayout 
log4j.appender.A1.layout.ConversionPattern=%d %-5p [%t] %C{2} (%F:%L) - %m%n 
第一行就指定了分配器,第二行则指定了输出的格式。 
有关输出格式的定义可以参考/org/apache/log4j/PatternLayout.html 

原创粉丝点击