Log4j简明手册(2/3)

来源:互联网 发布:快速解出数独的软件 编辑:程序博客网 时间:2024/06/05 04:14
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
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.fooLogger。这显著的提高了程序性能并且减少的内存占用。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.PatternLayoutLog4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n假设我们不在对com.foo包的任何类的输出感兴趣的话,随后的配置文件向我们展示了实现这个目的的方法之一。Log4j.rootLogger=DEBUG, A1Log4j.appender.A1=org.apache.Log4j.ConsoleAppenderLog4j.appender.A1.layout=org.apache.Log4j.PatternLayout# Print the date in ISO 8601 formatLog4j.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, RLog4j.appender.stdout=org.apache.Log4j.ConsoleAppenderLog4j.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%nLog4j.appender.R=org.apache.Log4j.RollingFileAppenderLog4j.appender.R.File=example.LogLog4j.appender.R.MaxFileSize=100KB# Keep one backup fileLog4j.appender.R.MaxBackupIndex=1Log4j.appender.R.layout=org.apache.Log4j.PatternLayoutLog4j.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 tryingif(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方法中定义它。<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
原创粉丝点击