有关tomcat的日志文件(二)

最近在测试一个系统,才想到要弄个测试文件,可以记录控制台的输出,问了下同学,她告诉我Log4j可以有这种效果,于是跑去官网上看了一圈,发现自己真是孤陋寡闻呀。。。。对于log4j的学习笔记整理如下。

http://logging.apache.org/log4j/1.2/manual.html

一、Log4j有三个主要的组成部分:

loggers, appenders, layouts


这三部分使得开发者可以根据message的类型和等级,来记录messages,并且控制在运行期间,这些消息如何形成,并且输出到哪里去。


1. Logger hierarchy(Logger 层)


(1)Logger中的一些基本方法:

[java]  view plain copy
  1. package org.apache.log4j;  
  2.   
  3.   public class Logger {  
  4.   
  5.     // Creation & retrieval methods:  
  6.     public static Logger getRootLogger();  
  7.     public static Logger getLogger(String name);  
  8.   
  9.     // printing methods:  
  10.     public void trace(Object message);  
  11.     public void debug(Object message);  
  12.     public void info(Object message);  
  13.     public void warn(Object message);  
  14.     public void error(Object message);  
  15.     public void fatal(Object message);  
  16.   
  17.     // generic printing method:  
  18.     public void log(Level l, Object message);  
  19. }  


(2)可以给Loggers制定等级。可能的等级包括:

TRACE, DEBUG, INFO, WARN, ERROR, FATAL(均定义在org.aache.log4j.Level类中)

同时也可以通过继承Level类来自定义等级,但不推荐

如果某一logger并未制定等级,那么它就继承于他最近的被指定等级的父类。

记录日志是通过调用logger实例中的一个打印的方法来实现的。

Logger的等级:DEBUG<INFO<WARN<ERROR<FATAl

E.G.:

[java]  view plain copy
  1. // get a logger instance named "com.foo"  
  2.    Logger  logger = Logger.getLogger("com.foo");  
  3.   
  4.    // Now set its level. Normally you do not need to set the  
  5.    // level of a logger programmatically. This is usually done  
  6.    // in configuration files.  
  7.    logger.setLevel(Level.INFO);  
  8.   
  9.    Logger barlogger = Logger.getLogger("com.foo.Bar");  
  10.   
  11.    // This request is enabled, because WARN >= INFO.  
  12.    logger.warn("Low fuel level.");  
  13.   
  14.    // This request is disabled, because DEBUG < INFO.  
  15.    logger.debug("Starting search for nearest gas station.");  
  16.   
  17.    // The logger instance barlogger, named "com.foo.Bar",  
  18.    // will inherit its level from the logger named  
  19.    // "com.foo" Thus, the following request is enabled  
  20.    // because INFO >= INFO.  
  21.    barlogger.info("Located nearest gas station.");  
  22.   
  23.    // This request is disabled, because DEBUG < INFO.  
  24.    barlogger.debug("Exiting gas station search");  



(3)调用getLogger方法,使用同一名字,来创建的不同实例,返回同一logger object

eg:

[java]  view plain copy
  1. Logger x = Logger.getLogger("wombat");  
  2. Logger y = Logger.getLogger("wombat");  


其中,x和y指向同一logger object


2. Appenders和Layouts

(1)appenders

Log4j允许将logging请求打印到不同的目的地之中。

在log4j中,输出的目的地叫做 appender。目前,appender可以是控制台(console), 文件(files), 图形界面化组件(GUI components), 远程socket服务器(remote socket servers),JAVA 消息服务(JMS),NT事件记录器(NT Event Loggers),远程UNIX系统日志进程。并且可以异步记录。


可同时制定将一个logger输出到不同的appender中。


添加appender的方法:addAppender方法

它将一个appender添加到制定的Logger上。对于某一指定的logger,每一个可用的logging request都会被提交到这一logger的所有appender中,以及更高层次中的appenders中。也就是说,appender同logger一起继承下来。但是也可以通过“setting the additivity flag”,将additivity flag这一属性变为false,来禁止这种继承关系。


如:loggerC的输出日志,会被写入C的所有appender中,并且也会被写入C的所有父类(包括父类的父类等)中的appender中。这就是所谓的"appender additivity"。但是如果C的一个父类P,将additivity flag设为flase, 那么C的输出就直接记录在C的所有appender中,输出到C的父类(包括P)的appender中,但是不会记录在P的父类中了;additivity flag默认为true.


(2)PatternLayout

用户常常希望定义输出内容的格式=>PatternLayout

例如:

如果定义PatternLayout为格式“%r [%t] %-5p %c -%m%n”,那么输出的内容将会是:

176 [main] INFO org.foo.Bar -Located nearest gas station

176:表示自从程序启动后到输出这句话的时间差,单位为milliseconds(毫秒)

[main]:发出logging请求的线程

INFO:log描述的等级

org.foo.Bar:处理该logging请求的logger名字

Located nearest gas station:   "-"后面的内容是想要输出的信息


(3)没看懂。。。

Just as importantly, log4j will render the content of the log message according to user specified criteria. For example, if you frequently need to log Oranges, an object type used in your current project, then you can register an OrangeRenderer that will be invoked whenever an orange needs to be logged.

Object rendering follows the class hierarchy. For example, assuming oranges are fruits, if you register a FruitRenderer, all fruits including oranges will be rendered by theFruitRenderer, unless of course you registered an orange specific OrangeRenderer.

Object renderers have to implement the ObjectRendererinterface.



3. 配置

配置文件可以写成XML文件或是JAVA properties文件(KEY=VALUE)中。

例子如下,

(1)MyApp:使用BasicConfigurator

[java]  view plain copy
  1. import com.foo.Bar;  
  2.   
  3. <span style="color:#ff0000;"// Import log4j classes.</span>  
  4.  import org.apache.log4j.Logger;  
  5.  import org.apache.log4j.BasicConfigurator;  
  6.   
  7.  public class MyApp {  
  8.   
  9.    // Define a static logger variable so that it references the  
  10.    // Logger instance named "MyApp".  
  11.    <span style="color:#ff0000;">static Logger logger = Logger.getLogger(MyApp.class);</span>  
  12.   
  13.    public static void main(String[] args) {  
  14.   
  15.      // Set up a simple configuration that logs on the console.  
  16.      BasicConfigurator.configure();  
  17.   
  18.      logger.info("Entering application.");  
  19.      Bar bar = new Bar();  
  20.      bar.doIt();  
  21.      logger.info("Exiting application.");  
  22.    }  
  23.  }  

Bar:

[java]  view plain copy
  1. package com.foo;  
  2.  import org.apache.log4j.Logger;  
  3.   
  4.  public class Bar {  
  5.    static Logger logger = Logger.getLogger(Bar.class);  
  6.   
  7.    public void doIt() {  
  8.      logger.debug("Did it again!");  
  9.    }  
  10.  }  

控制台输出:

0 [main] INFO com.test.MyApp  - Entering application.
2 [main] DEBUG com.test.Bar  - Did it again!
2 [main] INFO com.test.MyApp  - Exiting application.


调用BasicConfigurator.configure方法,是创建了一个相对于简单的log4j setup。这种方法直接给root logger分配了一个consoleAppender;并且输出将采用 “%-4r [%t] %-5p %c %x - %m%n"类型的patternLayout。

默认情况下,root logger被设定为Level.DEBUG


使用BasicConfigurator.configure方法,只能是输出相同的Log信息。而使用PropertyConfigurator则可以使用配置文件log4j.properties.

(2)MyApp:(Bar类并未修改)使用PropertyConfigurator

[java]  view plain copy
  1. import com.foo.Bar;  
  2.   
  3.  import org.apache.log4j.Logger;  
  4.  import org.apache.log4j.PropertyConfigurator;  
  5.   
  6.  public class MyApp {  
  7.   
  8.    static Logger logger = Logger.getLogger(MyApp.class.getName());  
  9.   
  10.    public static void main(String[] args) {  
  11.   
  12.   
  13.      // BasicConfigurator replaced with PropertyConfigurator.  
  14.     // PropertyConfigurator.configure(args[0]);  
  15.     //注意此处configure里面的参数是指配置文件的名字(包括路径)  
  16.     //若为java web工程,那么应该放在WEB-INF/classes文件夹里面  
  17.      PropertyConfigurator.configure(.\\src\\com\\foo\\log4j.properties);  
  18.      logger.info("Entering application.");  
  19.      Bar bar = new Bar();  
  20.      bar.doIt();  
  21.      logger.info("Exiting application.");  
  22.    }  
  23.  }  



添加log4j.properties配置文件:

[plain]  view plain copy
  1. # Set root logger level to DEBUG and its only appender to A1.  
  2. log4j.rootLogger=DEBUG, A1  
  3.   
  4. # A1 is set to be a ConsoleAppender.  
  5. log4j.appender.A1=org.apache.log4j.ConsoleAppender  
  6.   
  7. # A1 uses PatternLayout.  
  8. log4j.appender.A1.layout=org.apache.log4j.PatternLayout  
  9. log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n  

也可以改变输出格式,并且设定想要输出的log等级

[plain]  view plain copy
  1. log4j.rootLogger=DEBUG, A1  
  2. log4j.appender.A1=org.apache.log4j.ConsoleAppender  
  3. log4j.appender.A1.layout=org.apache.log4j.PatternLayout  
  4.   
  5. # Print the date in ISO 8601 format  
  6. log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n  
  7.   
  8. # Print only messages of level WARN or above in the package com.foo.  
  9. log4j.logger.com.foo=WARN  

(3)使用多个appender

例如:

[java]  view plain copy
  1. log4j.rootLogger=debug, stdout, R  
  2.   
  3. //两个输出目的地:stdout和R,分别指定为控制台输出(ConsoleAppender),以及文件输出(RollingFileAppender)  
  4. log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
  5. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
  6.   
  7. # Pattern to output the caller's file name and line number.  
  8. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n  
  9.   
  10. log4j.appender.R=org.apache.log4j.RollingFileAppender  
  11. log4j.appender.R.File=example.log  
  12.   
  13. log4j.appender.R.MaxFileSize=100KB      //这一文件example.log当大小达到100KB时,自动roll over(重新存储?)  
  14.                         //而当roll over发生时,之前的example.log自动存储为example.log.1  
  15. # Keep one backup file  
  16. log4j.appender.R.MaxBackupIndex=1  
  17.   
  18. log4j.appender.R.layout=org.apache.log4j.PatternLayout  
  19. log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n  



4、默认初始化步骤

Log4j库对于运行环境没有要求。尤其是,没有默认的log4j appender。在某些设定良好的环境中,Logger类的静态初始器将会尝试自动的配置log4j。而java语言保证这一初始器在向内存中装载类时,仅且调用一次。注意:不同的类装载器可能会装载同一类的不同copy。而这些copy在JVM下被认为是无任何关联的。

所以在有一些环境(应用的准确入口点取决于运行环境)中的默认初始化是非常重要的。例如,同一应用可悲用为单一运行的应用,作为applet,或者作为一个web server中的servlet。

准确的默认初始化算法定义如下:

(1)将log4j.defaultInitOverride参数设为除false外的任何值,将导致log4j跳过初始化

(2)将resource字符串变量设为Log4j.configuration的值。这是在设定默认初始化文件。如果log4j.configuration没有定义,那么将resource字符串变量设为默认值:default value

(3)将resource变量转化成一个URL

(4)如果resource变量无法转化成一个URL(例如有MalformedURLException),

那么调用org.apache.log4j.helpers.Loader.getResource(resource,Logger.class),

它会从classpath中搜索resource,并返回一个URL.

 Note that the string "log4j.properties" constitutes a malformed URL.

See Loader.getResource(java.lang.String) for the list of searched locations.(没懂。。。。)


(5)如果仍然无法找到URL,那么放弃默认的初始化。否则,从URL中配置Log4j

可以使用PropertyConfigurator,来解析URL,并配置log4j;若URL是xml结尾的,那么要使用到DOMConfigurator。

也可以随机定义一个configurator,使用系统参数log4j.configuratorClass来指定configurator的类名。该类必须实现Configurator接口。


5. 例子

(1)使用servlet来初始化log4j

[java]  view plain copy
  1. <span style="font-size:18px;">package com.foo;  
  2.   
  3. import org.apache.log4j.PropertyConfigurator;  
  4. import javax.servlet.http.HttpServlet;  
  5. import javax.servlet.http.HttpServletRequest;  
  6. import javax.servlet.http.HttpServletResponse;  
  7. import java.io.PrintWriter;  
  8. import java.io.IOException;  
  9.   
  10. public class Log4jInit extends HttpServlet {  
  11.   
  12.   public void init() {  
  13.     String prefix =  getServletContext().getRealPath("/");  
  14.     String file = getInitParameter("log4j-init-file");  
  15.     // if the log4j-init-file is not set, then no point in trying  
  16.     if(file != null) {  
  17.       PropertyConfigurator.configure(prefix+file);  
  18.     }  
  19.   }  
  20.   
  21.   public void doGet(HttpServletRequest req, HttpServletResponse res) {  
  22.   }  
  23. }</span>  

(2) 在web.xml里面配置

[java]  view plain copy
  1. <servlet>  
  2.     <servlet-name>log4j-init</servlet-name>  
  3.     <servlet-class>com.foo.Log4jInit</servlet-class>  
  4.   
  5.     <init-param>  
  6.       <param-name>log4j-init-file</param-name>  
  7.       <param-value>WEB-INF/classes/log4j.lcf</param-value>  
  8.     </init-param>  
  9.   
  10.     <load-on-startup>1</load-on-startup>  
  11.   </servlet>  

最近在测试一个系统,才想到要弄个测试文件,可以记录控制台的输出,问了下同学,她告诉我Log4j可以有这种效果,于是跑去官网上看了一圈,发现自己真是孤陋寡闻呀。。。。对于log4j的学习笔记整理如下。

http://logging.apache.org/log4j/1.2/manual.html

一、Log4j有三个主要的组成部分:

loggers, appenders, layouts


这三部分使得开发者可以根据message的类型和等级,来记录messages,并且控制在运行期间,这些消息如何形成,并且输出到哪里去。


1. Logger hierarchy(Logger 层)


(1)Logger中的一些基本方法:

[java]  view plain copy
  1. package org.apache.log4j;  
  2.   
  3.   public class Logger {  
  4.   
  5.     // Creation & retrieval methods:  
  6.     public static Logger getRootLogger();  
  7.     public static Logger getLogger(String name);  
  8.   
  9.     // printing methods:  
  10.     public void trace(Object message);  
  11.     public void debug(Object message);  
  12.     public void info(Object message);  
  13.     public void warn(Object message);  
  14.     public void error(Object message);  
  15.     public void fatal(Object message);  
  16.   
  17.     // generic printing method:  
  18.     public void log(Level l, Object message);  
  19. }  


(2)可以给Loggers制定等级。可能的等级包括:

TRACE, DEBUG, INFO, WARN, ERROR, FATAL(均定义在org.aache.log4j.Level类中)

同时也可以通过继承Level类来自定义等级,但不推荐

如果某一logger并未制定等级,那么它就继承于他最近的被指定等级的父类。

记录日志是通过调用logger实例中的一个打印的方法来实现的。

Logger的等级:DEBUG<INFO<WARN<ERROR<FATAl

E.G.:

[java]  view plain copy
  1. // get a logger instance named "com.foo"  
  2.    Logger  logger = Logger.getLogger("com.foo");  
  3.   
  4.    // Now set its level. Normally you do not need to set the  
  5.    // level of a logger programmatically. This is usually done  
  6.    // in configuration files.  
  7.    logger.setLevel(Level.INFO);  
  8.   
  9.    Logger barlogger = Logger.getLogger("com.foo.Bar");  
  10.   
  11.    // This request is enabled, because WARN >= INFO.  
  12.    logger.warn("Low fuel level.");  
  13.   
  14.    // This request is disabled, because DEBUG < INFO.  
  15.    logger.debug("Starting search for nearest gas station.");  
  16.   
  17.    // The logger instance barlogger, named "com.foo.Bar",  
  18.    // will inherit its level from the logger named  
  19.    // "com.foo" Thus, the following request is enabled  
  20.    // because INFO >= INFO.  
  21.    barlogger.info("Located nearest gas station.");  
  22.   
  23.    // This request is disabled, because DEBUG < INFO.  
  24.    barlogger.debug("Exiting gas station search");  



(3)调用getLogger方法,使用同一名字,来创建的不同实例,返回同一logger object

eg:

[java]  view plain copy
  1. Logger x = Logger.getLogger("wombat");  
  2. Logger y = Logger.getLogger("wombat");  


其中,x和y指向同一logger object


2. Appenders和Layouts

(1)appenders

Log4j允许将logging请求打印到不同的目的地之中。

在log4j中,输出的目的地叫做 appender。目前,appender可以是控制台(console), 文件(files), 图形界面化组件(GUI components), 远程socket服务器(remote socket servers),JAVA 消息服务(JMS),NT事件记录器(NT Event Loggers),远程UNIX系统日志进程。并且可以异步记录。


可同时制定将一个logger输出到不同的appender中。


添加appender的方法:addAppender方法

它将一个appender添加到制定的Logger上。对于某一指定的logger,每一个可用的logging request都会被提交到这一logger的所有appender中,以及更高层次中的appenders中。也就是说,appender同logger一起继承下来。但是也可以通过“setting the additivity flag”,将additivity flag这一属性变为false,来禁止这种继承关系。


如:loggerC的输出日志,会被写入C的所有appender中,并且也会被写入C的所有父类(包括父类的父类等)中的appender中。这就是所谓的"appender additivity"。但是如果C的一个父类P,将additivity flag设为flase, 那么C的输出就直接记录在C的所有appender中,输出到C的父类(包括P)的appender中,但是不会记录在P的父类中了;additivity flag默认为true.


(2)PatternLayout

用户常常希望定义输出内容的格式=>PatternLayout

例如:

如果定义PatternLayout为格式“%r [%t] %-5p %c -%m%n”,那么输出的内容将会是:

176 [main] INFO org.foo.Bar -Located nearest gas station

176:表示自从程序启动后到输出这句话的时间差,单位为milliseconds(毫秒)

[main]:发出logging请求的线程

INFO:log描述的等级

org.foo.Bar:处理该logging请求的logger名字

Located nearest gas station:   "-"后面的内容是想要输出的信息


(3)没看懂。。。

Just as importantly, log4j will render the content of the log message according to user specified criteria. For example, if you frequently need to log Oranges, an object type used in your current project, then you can register an OrangeRenderer that will be invoked whenever an orange needs to be logged.

Object rendering follows the class hierarchy. For example, assuming oranges are fruits, if you register a FruitRenderer, all fruits including oranges will be rendered by theFruitRenderer, unless of course you registered an orange specific OrangeRenderer.

Object renderers have to implement the ObjectRendererinterface.



3. 配置

配置文件可以写成XML文件或是JAVA properties文件(KEY=VALUE)中。

例子如下,

(1)MyApp:使用BasicConfigurator

[java]  view plain copy
  1. import com.foo.Bar;  
  2.   
  3. <span style="color:#ff0000;"// Import log4j classes.</span>  
  4.  import org.apache.log4j.Logger;  
  5.  import org.apache.log4j.BasicConfigurator;  
  6.   
  7.  public class MyApp {  
  8.   
  9.    // Define a static logger variable so that it references the  
  10.    // Logger instance named "MyApp".  
  11.    <span style="color:#ff0000;">static Logger logger = Logger.getLogger(MyApp.class);</span>  
  12.   
  13.    public static void main(String[] args) {  
  14.   
  15.      // Set up a simple configuration that logs on the console.  
  16.      BasicConfigurator.configure();  
  17.   
  18.      logger.info("Entering application.");  
  19.      Bar bar = new Bar();  
  20.      bar.doIt();  
  21.      logger.info("Exiting application.");  
  22.    }  
  23.  }  

Bar:

[java]  view plain copy
  1. package com.foo;  
  2.  import org.apache.log4j.Logger;  
  3.   
  4.  public class Bar {  
  5.    static Logger logger = Logger.getLogger(Bar.class);  
  6.   
  7.    public void doIt() {  
  8.      logger.debug("Did it again!");  
  9.    }  
  10.  }  

控制台输出:

0 [main] INFO com.test.MyApp  - Entering application.
2 [main] DEBUG com.test.Bar  - Did it again!
2 [main] INFO com.test.MyApp  - Exiting application.


调用BasicConfigurator.configure方法,是创建了一个相对于简单的log4j setup。这种方法直接给root logger分配了一个consoleAppender;并且输出将采用 “%-4r [%t] %-5p %c %x - %m%n"类型的patternLayout。

默认情况下,root logger被设定为Level.DEBUG


使用BasicConfigurator.configure方法,只能是输出相同的Log信息。而使用PropertyConfigurator则可以使用配置文件log4j.properties.

(2)MyApp:(Bar类并未修改)使用PropertyConfigurator

[java]  view plain copy
  1. import com.foo.Bar;  
  2.   
  3.  import org.apache.log4j.Logger;  
  4.  import org.apache.log4j.PropertyConfigurator;  
  5.   
  6.  public class MyApp {  
  7.   
  8.    static Logger logger = Logger.getLogger(MyApp.class.getName());  
  9.   
  10.    public static void main(String[] args) {  
  11.   
  12.   
  13.      // BasicConfigurator replaced with PropertyConfigurator.  
  14.     // PropertyConfigurator.configure(args[0]);  
  15.     //注意此处configure里面的参数是指配置文件的名字(包括路径)  
  16.     //若为java web工程,那么应该放在WEB-INF/classes文件夹里面  
  17.      PropertyConfigurator.configure(.\\src\\com\\foo\\log4j.properties);  
  18.      logger.info("Entering application.");  
  19.      Bar bar = new Bar();  
  20.      bar.doIt();  
  21.      logger.info("Exiting application.");  
  22.    }  
  23.  }  



添加log4j.properties配置文件:

[plain]  view plain copy
  1. # Set root logger level to DEBUG and its only appender to A1.  
  2. log4j.rootLogger=DEBUG, A1  
  3.   
  4. # A1 is set to be a ConsoleAppender.  
  5. log4j.appender.A1=org.apache.log4j.ConsoleAppender  
  6.   
  7. # A1 uses PatternLayout.  
  8. log4j.appender.A1.layout=org.apache.log4j.PatternLayout  
  9. log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n  

也可以改变输出格式,并且设定想要输出的log等级

[plain]  view plain copy
  1. log4j.rootLogger=DEBUG, A1  
  2. log4j.appender.A1=org.apache.log4j.ConsoleAppender  
  3. log4j.appender.A1.layout=org.apache.log4j.PatternLayout  
  4.   
  5. # Print the date in ISO 8601 format  
  6. log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n  
  7.   
  8. # Print only messages of level WARN or above in the package com.foo.  
  9. log4j.logger.com.foo=WARN  

(3)使用多个appender

例如:

[java]  view plain copy
  1. log4j.rootLogger=debug, stdout, R  
  2.   
  3. //两个输出目的地:stdout和R,分别指定为控制台输出(ConsoleAppender),以及文件输出(RollingFileAppender)  
  4. log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
  5. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
  6.   
  7. # Pattern to output the caller's file name and line number.  
  8. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n  
  9.   
  10. log4j.appender.R=org.apache.log4j.RollingFileAppender  
  11. log4j.appender.R.File=example.log  
  12.   
  13. log4j.appender.R.MaxFileSize=100KB      //这一文件example.log当大小达到100KB时,自动roll over(重新存储?)  
  14.                         //而当roll over发生时,之前的example.log自动存储为example.log.1  
  15. # Keep one backup file  
  16. log4j.appender.R.MaxBackupIndex=1  
  17.   
  18. log4j.appender.R.layout=org.apache.log4j.PatternLayout  
  19. log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n  



4、默认初始化步骤

Log4j库对于运行环境没有要求。尤其是,没有默认的log4j appender。在某些设定良好的环境中,Logger类的静态初始器将会尝试自动的配置log4j。而java语言保证这一初始器在向内存中装载类时,仅且调用一次。注意:不同的类装载器可能会装载同一类的不同copy。而这些copy在JVM下被认为是无任何关联的。

所以在有一些环境(应用的准确入口点取决于运行环境)中的默认初始化是非常重要的。例如,同一应用可悲用为单一运行的应用,作为applet,或者作为一个web server中的servlet。

准确的默认初始化算法定义如下:

(1)将log4j.defaultInitOverride参数设为除false外的任何值,将导致log4j跳过初始化

(2)将resource字符串变量设为Log4j.configuration的值。这是在设定默认初始化文件。如果log4j.configuration没有定义,那么将resource字符串变量设为默认值:default value

(3)将resource变量转化成一个URL

(4)如果resource变量无法转化成一个URL(例如有MalformedURLException),

那么调用org.apache.log4j.helpers.Loader.getResource(resource,Logger.class),

它会从classpath中搜索resource,并返回一个URL.

 Note that the string "log4j.properties" constitutes a malformed URL.

See Loader.getResource(java.lang.String) for the list of searched locations.(没懂。。。。)


(5)如果仍然无法找到URL,那么放弃默认的初始化。否则,从URL中配置Log4j

可以使用PropertyConfigurator,来解析URL,并配置log4j;若URL是xml结尾的,那么要使用到DOMConfigurator。

也可以随机定义一个configurator,使用系统参数log4j.configuratorClass来指定configurator的类名。该类必须实现Configurator接口。


5. 例子

(1)使用servlet来初始化log4j

[java]  view plain copy
  1. <span style="font-size:18px;">package com.foo;  
  2.   
  3. import org.apache.log4j.PropertyConfigurator;  
  4. import javax.servlet.http.HttpServlet;  
  5. import javax.servlet.http.HttpServletRequest;  
  6. import javax.servlet.http.HttpServletResponse;  
  7. import java.io.PrintWriter;  
  8. import java.io.IOException;  
  9.   
  10. public class Log4jInit extends HttpServlet {  
  11.   
  12.   public void init() {  
  13.     String prefix =  getServletContext().getRealPath("/");  
  14.     String file = getInitParameter("log4j-init-file");  
  15.     // if the log4j-init-file is not set, then no point in trying  
  16.     if(file != null) {  
  17.       PropertyConfigurator.configure(prefix+file);  
  18.     }  
  19.   }  
  20.   
  21.   public void doGet(HttpServletRequest req, HttpServletResponse res) {  
  22.   }  
  23. }</span>  

(2) 在web.xml里面配置

[java]  view plain copy
  1. <servlet>  
  2.     <servlet-name>log4j-init</servlet-name>  
  3.     <servlet-class>com.foo.Log4jInit</servlet-class>  
  4.   
  5.     <init-param>  
  6.       <param-name>log4j-init-file</param-name>  
  7.       <param-value>WEB-INF/classes/log4j.lcf</param-value>  
  8.     </init-param>  
  9.   
  10.     <load-on-startup>1</load-on-startup>  
  11.   </servlet>  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值