Log4j简明手册(二)

  Log4j简明手册(二)
4.                  配置
 插入日志请求到应用程序的代码中需要大量的预先计划和最终努力。观察显示大约4%的代码是用来输出的。
因此,大小适度的程序都被嵌入有成千个日志输出语句。为了以无需手工的方式管理这些日志的输出状态,给日志输出以编号和规范变得势在必行。 
Log4j在程序中有充分的可配置性。然而,用配置文件配置Log4j具有更大的弹性。目前,它的配置文件支持xml和java properties(key=value)文件两种格式。
让我们以一个例子来演示它是如何做的。假定有一个用了Log4j的程序MyApp。

import com.foo.Bar;
 // Import Log4j classes.
 import org.apache.Log4j.Logger;
 import org.apache.Log4j.BasicConfigurator;
 public class MyApp {
   // Define a static logger variable so that it references the
   // Logger instance named "MyApp".
   static Logger logger = Logger.getLogger(MyApp.class);
   public static void main(String[] args) {
    // Set up a simple configuration that logs on the console.
     BasicConfigurator.configure();
       logger.info("Entering application.");
     Bar bar = new Bar();
     bar.doIt();
     logger.info("Exiting application.");
   }
 }
MyApp以引入Log4j的相关类开始,接着它定义了一个静态logger变量,并给予值为"MyApp"类的全路径名称。
MYApp用了定义在包com.foo中的类Bar.
 package com.foo;
 import org.apache.Log4j.Logger;
 public class Bar {
   static Logger logger = Logger.getLogger(Bar.class);
   public void doIt() {
     logger.debug("Did it again!");
   }
 }
调用BasicConfigurator.configure()方法创建了一个相当简单的Log4j的设置。它加入一
个ConsoleAppender到根logger。输出将被采用了"%-4r [%t] %-5p %c %x - %m%n"模式
的PatternLayout所格式化。
注意,根logger默认被分配了Level.DEBUG的级别。
MyApp的输出为:
0     [main] INFO MyApp - Entering application.
36    [main] DEBUG com.foo.Bar - Did it again!
51    [main] INFO MyApp - Exiting application.
随后的图形描述了在调用 BasicConfigurator.configure()方法后MyApp的对象图。
 
一边要提醒的是,Log4j的子logger只连接到已经存在的它们的父代。特别的是,名为
com.foo.bar的logger是直接连接到根logger,而不是围绕着没用的com或com.foo
logger。这显著的提高了程序性能并且减少的内存占用。
MyApp类配置Log4j是通过调用BasicConfigurator.configure 方法。其它的类仅仅
需要引入org.apache.Log4j.Logger 类,找到它们希望用的logger,并且用它就行。
以前的例子通常输出同样的日志信息。幸运的是,修改MyApp是容易的,以便日志输
出可以在运行时刻被控制。这里是一个小小修改的版本。
 
 import com.foo.Bar;
 import org.apache.Log4j.Logger;
 import org.apache.Log4j.PropertyConfigurator;
 public class MyApp {
   static Logger logger = Logger.getLogger(MyApp.class.getName());
   public static void main(String[] args) {
     // BasicConfigurator replaced with PropertyConfigurator.
     PropertyConfigurator.configure(args[0]);
     logger.info("Entering application.");
     Bar bar = new Bar();
     bar.doIt();
     logger.info("Exiting application.");
   }
 }
修改后的 MyApp通知程序调用PropertyConfigurator()方法解析一个配置文件,并且根
据这个配置文件来设置日志。
 这里是一个配置文件的例子,它将产生同以前BasicConfigurator 基本例子一样
 的输出结果。
 # Set root logger level to DEBUG and its only appender to A1.
Log4j.rootLogger=DEBUG, A1
# A1 is set to be a ConsoleAppender.
Log4j.appender.A1=org.apache.Log4j.ConsoleAppender
# A1 uses PatternLayout.
Log4j.appender.A1.layout=org.apache.Log4j.PatternLayout
Log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
假设我们不在对com.foo包的任何类的输出感兴趣的话,随后的配置文件向我们展示
了实现这个目的的方法之一。
Log4j.rootLogger=DEBUG, A1
Log4j.appender.A1=org.apache.Log4j.ConsoleAppender
Log4j.appender.A1.layout=org.apache.Log4j.PatternLayout
# Print the date in ISO 8601 format
Log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
# Print only messages of level WARN or above in the package com.foo.
Log4j.logger.com.foo=WARN
以这个配置文件配置好的MyApp将输出如下:
2000-09-07 14:07:41,508 [main] INFO MyApp - Entering application.
2000-09-07 14:07:41,529 [main] INFO MyApp - Exiting application.
当logger com.foo.bar没有被分配一个级别,它将从com.foo继承,在配置文件中
它被设置了WARN的级别。在Bar.doIt方法中定义的log为DEBUG级别,低于WARN,
因此doIt() 方法的日志请求被禁用。
这里是另外一个配置文件,它使用了多个appenders.
Log4j.rootLogger=debug, stdout, R
Log4j.appender.stdout=org.apache.Log4j.ConsoleAppender
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
以这个配置文件调用加强了的MyApp类将输出如下信息.
INFO [main] (MyApp2.java:12) - Entering application.
DEBUG [main] (Bar.java:8) - Doing it again!
INFO [main] (MyApp2.java:15) - Exiting application.
另外,因为根logger有被分配第二个appender,所以输出也将被定向到example.log文件。
这个文件大小达到100kb时将自动备份。备份时老版本的example.log文件自动被移到
文件example.log.1中。
注意我们不需要重新编译代码就可以获得这些不同的日志行为。我们一样可以容易
的使日志输出到UNIX Syslog daemon, 重定向所有的com.foo到NT Event logger,
或者转发日志到一个远程的Log4j服务器,它根据本地server的策略来进行日志输出。例
如转发日志事件到第二个Log4j服务器.
 
5.                  默认的初始化过程
Log4j类库不对它的环境做任何假设。特别是没有默认的Log4j appender。在一些特别
的有着良好定义的环境下,logger的静态inializer将尝试自动的配置Log4j。
java语言的特性保证类的静态initializer当且仅当装载类到内存之时只会被调用一次。
要记住的重要一点是,不同的类装载器可能装载同一个类的完全不同的拷贝。
这些同样类的拷贝被虚拟机认为是完全不相干的。
默认的initialization是非常有用的,特别是在一些应用程序所依靠的运行环境被准确的
定位的情况下。例如,同一样的应用程序可以被用做一个标准的应用程序,或一个
applet,或一个在web-server控制下的servlet。
准确的默认的initialization原理被定义如下:
1.设置系统属性Log4j.defaultInitOverride为"false"以外的其它值,那么 Log4j将
跳过默认的initialization过程。
2.设置资源变量字符串给系统属性Log4j.configuration。定义默认initialization
文件的最好的方法是通过系统属性Log4j.configuration。万一系统属性
Log4j.configuration没有被定义,那么设置字符串变量resource 给它的默认值
Log4j.properties。
3.尝试转换resource 变量为一个URL。
4.如果变量resource的值不能被转换为一个URL,例如由于MalformedURLException违
例,那么 通过调用
org.apache.Log4j.helpers.Loader.getResource(resource, Logger.class) 方法从
classpath中搜索resource,它将返回一个URL,并通知"Log4j.properties"的值是一个错
误的URL。
看See Loader.getResource(java.lang.String) 查看搜索位置的列表。
5.如果没有URL被发现,那么放弃默认的initialization。否则用URL配置Log4j。
PropertyConfigurator将用来解析URL,配置Log4j,除非URL以".xml"为结尾。
在这种情况下的话DOMConfigurator将被调用。你可以有机会定义一个自定义的
configurator。
系统属性Log4j.configuratorClass 的值取自你的自定义的类名的全路径。
你自定义的configurator必须实现configurator接口。
 
6.                  配置范例
6.1               Tomcat下的初始化
默认的Log4j initialization典型的应用是在web-server 环境下。在tomcat3.x和tomcat4.x
下,你应该将配置文件Log4j.properties放在你的web应用程序的WEB-INF/classes 目录
下。
Log4j将发现属性文件,并且以此初始化。这是使它工作的最容易的方法。
你也可以选择在运行tomcat前设置系统属性Log4j.configuration 。对于tomcat 3.x,
TOMCAT_OPTS 系统变量是用来设置命令行的选项。对于tomcat4.0,用系统环境变
量CATALINA_OPTS 代替了TOMCAT_OPTS。
Example 1
UNIX 命令行
export TOMCAT_OPTS="-DLog4j.configuration=foobar.txt"
告诉Log4j用文件foobar.txt作为默认的配置文件。这个文件应该放在WEB-INF/classes
目录下。这个文件将被PropertyConfigurator所读。每个web-application将用不同的默认
配置文件,因为每个文件是和它的web-application 相关的。
Example 2
UNIX 命令行
export TOMCAT_OPTS="-DLog4j.debug -DLog4j.configuration=foobar.xml"
告诉Log4j输出Log4j-internal的调试信息,并且用foobar.xml作为默认的配置文件。
这个文件应该放在你的web-application的WEB-INF/classes 目录下。因为有.xml的
扩展名,它将被DOMConfigurator所读。每个web-application将用不同的默认
配置文件。因为每个文件都和它所在的web-application 相关的。
Example 3
UNIX 命令行
set TOMCAT_OPTS=-DLog4j.configuration=foobar.lcf -DLog4j.configuratorClass=com.foo.BarConfigurator
告诉Log4j用文件foobar.lcf作为默认的配置文件。这个文件应该放在你的
web-application的WEB-INF/classes 目录下。因为定义了Log4j.configuratorClass 系统属
性,文件将用自定义的com.foo.barconfigurator类来解析。每个web-application将用不
同的默认配置文件。因为每个文件都和它所在的web-application 相关的。
Example 4
UNIX 命令行
set TOMCAT_OPTS=-DLog4j.configuration=file:/c:/foobar.lcf
告诉Log4j用文件foobar.lcf作为默认的配置文件。这个配置文件用URL file:/c:/foobar.lcf
定义了全路径名。这样同样的配置文件将被所有的web-application所用。
不同的web-application将通过它们自己的类装载器来装载Log4j。这样,每个Log4j的环
境将独立的运作,而没有任何的相互同步。例如:在多个web-application中定义了
完全相同的输出源的FileAppenders将尝试写同样的文件。结果好象是缺乏安全性的。
你必须确保每个不同的web-application的Log4j配置没有用到同样的系统资源。
 
6.2               Servlet 的初始化
用一个特别的servlet来做Log4j的初始化也是可以的。如下是一个例子:
package com.foo;
import org.apache.Log4j.PropertyConfigurator;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.IOException;
public class Log4jInit extends HttpServlet {
 public void init() {
    String prefix = getServletContext().getRealPath("/");
    String file = getInitParameter("Log4j-init-file");
    // if the Log4j-init-file is not set, then no point in trying
    if(file != null) {
      PropertyConfigurator.configure(prefix+file);
    }
 }
  public void doGet(HttpServletRequest req, HttpServletResponse res) {
 }
}
在web.xml中定义随后的servlet为你的web-application。
 <servlet>
    <servlet-name>Log4j-init</servlet-name>
    <servlet-class>com.foo.Log4jInit</servlet-class>
    <init-param>
      <param-name>Log4j-init-file</param-name>
      <param-value>WEB-INF/classes/Log4j.lcf</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
 </servlet>
写一个初始化的servlet是最有弹性的初始化Log4j的方法。代码中没有任何限制,你可
以在servlet的init方法中定义它。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值