LOG4J 入门
我们在编程时经常不可避免地要使用到一些日志操作,比如开发阶段的调试信息、运行时的日志记录及审计。调查显示,日志代码占代码总量的4%。通常大家可以简单地使用System.out.println()语句输出日志信息,但是在发布时,通常不想在正式的版本中打印这些开发时的调试信息,于是又要手工地把这些语句删除,所以大量的这样的System.out.println()调试语句会带来麻烦。更多做法是把它封闭一个简单的输出,比如:
这样就可把代码中要用System.out.println()输出调试信息的地方全用Debug.println()替代,当在发布时只需把Debug类中的debugOn改成false即可。这样做虽然在一定程度上解决了问题,但如果需要的是更复杂的日志系统呢,比如把日志信息保存为文件等别的形式;又或是当系统在试运行了一段时间后我们又要更改某些试运行时的测试信息。如果真的遇到这样的情况,也行就只有修改代码了,这样又给开发工作带来了麻烦。
Log4J是Apache软件基金会Jakarta项目下的一个子项目,是用Java编写的优秀日志工具包。通过Log4J可以在不修改代码的情况下,方便、灵活地控制任意粒度的日志信息的开启或关闭,然后使用定制的格式,把日志信息输出到一个或多个需要的地方。并且,Log4J还有一条平滑的学习曲线,在三分钟内就可学会它的简单使用。随着使用深入,你会发现Log4J功能的强大,几乎可以满足日志方面的所有需要。
让我们从现在开始记时,看完成第一个log4j程序要不要3分钟。首先log4j-1.2.7.jar考到你的类路径下。然后创建一个类,代码如下:
最后运行这个类,你就会看到运行结果为:
0 [main] DEBUG TestLog4j.TestLog4j - Start of the main() in TestLog4j
10 [main] INFO TestLog4j.TestLog4j - Just testing a log message with priority set to INFO
10 [main] WARN TestLog4j.TestLog4j - Just testing a log message with priority set to WARN
21 [main] ERROR TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR
21 [main] FATAL TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL
111 [main] DEBUG TestLog4j.TestLog4j - Testing a log message use a alternate form
111 [main] DEBUG TestLog4j.TestLog4j - End of the main() in TestLog4j
好了,看一看你的表,应该不到3分钟吧。在这短短的3分钟里,我们做了些什么呢?下面我们来分析一下代码。
1) 首先代码(1)先通过Logger类的getLogger()方法得到一个Logger类的对象。在getLogger()方法中,通常把所在的类的Class对象或是所在类的全名作为参数。运用log4j输出日志要用到Logger对象。
2) 然后代码(2)进行一些必要的初始化,如要把调试信息输出到哪。当用System.out.println()时可以很明确的知道要把信息输出到标准输出设备且只能输出到那里。运用log4j,我们可以输出到许多地方,如控制台、文件、HTML文件等,至于要输出到哪里,就要自己进行初始化。在代码(2),我们调用自带的初始化方法来完成初始化。用这个方法进行初始化就不能体现出log4j的灵活性,所以基本上不会这样做。Log4j提供了用XML文件或Java配置文件来配置设置的方法,在下面我们将进行介绍。
3) 接着代码(3)就是输出信息的代码了。你可以看到代码(3)中尝试了用几种不同的方法来输出信息,对于这几种信息的作用,我会在下面进行介绍,你现在只需把它当成是输出语句就行。
最后,我们来看一下运行结果(日志信息)的意义。第一个数字是指程序开始运行到运行该日志语句所经历的毫秒数(用来做一点运行效率分析也不错),“[main]”是日志事件发生的线程,随后的“DEBUG”、“INFO”等信息是相应日志信息的优先级别,“TestLog4j.TestLog4”是当前TestLog4所在的包和名称,最后是日志信息。
虽然完成了第一程序了,但程序中的内容还是不太了解。好,现在我就对上面的例子用到的log4j的原理进行讲解。在以后的章节中,我都会采取这种先实例,再根据实例来介绍所涉及的log4j原理的方法。
Logger类是在log4j1.2以后才有的,以前是用Category类来实现现在的Logger类的功能的。从API可知,Logger类是Category类的子类。Logger类的代码如下:
在讨论Logger类中的方法之前,我先讲一下log4j中的级别(level)的概念。
Log4j中的日志级别分为五种:DEBUG、INFO、WARN、ERROR和FATAL,这五种级别从左到右级别依次增加。
对于每一个记录器,我们都可对它赋于一定的级别,而打印函数打印的即是相应级别的信息。当对一个级别为A的Logger调用级别为B的打印方法时,只有当B>=A时才会进行打印。例如,如果有一个级别为WARN的Logger对象logger,只有对它调用logger.warn (message)、logger.error (message)和logger.fatal (message)这三个打印函数才会打印信息;而调用logger.debug (message)和logger.info (message)则不会打印信息,因为debug()函数只有当logger的级别为DEBUG时才打印信息,info()函数只有当logger的级别为INFO时才打印信息。
除了对应于每一个级别有一个打印函数外,在Logger类中还有一个log(),它可以让你通过参数来指定一个打印信息的打印级别。
引入级别后就可通过修改调试的级别来控制某个调试信息是否输出。假设我们有的信息是在开发时才需要输出的(称为测试信息),那么我们把输出测试信息的Logger的级别在开发时设为DEBUG级别的,并用debug(Object message)函数来进行打印。当要发布系统时,只需把相应的Logger的级别调高就可以屏蔽掉测试信息。
这样就可把代码中要用System.out.println()输出调试信息的地方全用Debug.println()替代,当在发布时只需把Debug类中的debugOn改成false即可。这样做虽然在一定程度上解决了问题,但如果需要的是更复杂的日志系统呢,比如把日志信息保存为文件等别的形式;又或是当系统在试运行了一段时间后我们又要更改某些试运行时的测试信息。如果真的遇到这样的情况,也行就只有修改代码了,这样又给开发工作带来了麻烦。
Log4J是Apache软件基金会Jakarta项目下的一个子项目,是用Java编写的优秀日志工具包。通过Log4J可以在不修改代码的情况下,方便、灵活地控制任意粒度的日志信息的开启或关闭,然后使用定制的格式,把日志信息输出到一个或多个需要的地方。并且,Log4J还有一条平滑的学习曲线,在三分钟内就可学会它的简单使用。随着使用深入,你会发现Log4J功能的强大,几乎可以满足日志方面的所有需要。
第一个log4j程序及其原理
1 第一个log4j程序
让我们从现在开始记时,看完成第一个log4j程序要不要3分钟。首先log4j-1.2.7.jar考到你的类路径下。然后创建一个类,代码如下:
- package TestLog4j;
- import org.apache.log4j.Logger;
- import org.apache.log4j.BasicConfigurator;
- import org.apache.log4j.PropertyConfigurator;
- import org.apache.log4j.Priority;;
- public class TestLog4j
- {
- //代码(1)
- static Logger logger = Logger.getLogger(TestLog4j.class.getName());
- public TestLog4j(){}
- public static void main(String[] args)
- {
- //代码(2)
- BasicConfigurator.configure();
- //代码(3)
- logger.debug("Start of the main() in TestLog4j");
- logger.info("Just testing a log message with priority set to INFO");
- logger.warn("Just testing a log message with priority set to WARN");
- logger.error("Just testing a log message with priority set to ERROR");
- logger.fatal("Just testing a log message with priority set to FATAL");
- logger.log(Priority.DEBUG, "Testing a log message use a alternate form");
- logger.debug("End of the main() in TestLog4j");
- }
- }
最后运行这个类,你就会看到运行结果为:
0 [main] DEBUG TestLog4j.TestLog4j - Start of the main() in TestLog4j
10 [main] INFO TestLog4j.TestLog4j - Just testing a log message with priority set to INFO
10 [main] WARN TestLog4j.TestLog4j - Just testing a log message with priority set to WARN
21 [main] ERROR TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR
21 [main] FATAL TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL
111 [main] DEBUG TestLog4j.TestLog4j - Testing a log message use a alternate form
111 [main] DEBUG TestLog4j.TestLog4j - End of the main() in TestLog4j
好了,看一看你的表,应该不到3分钟吧。在这短短的3分钟里,我们做了些什么呢?下面我们来分析一下代码。
1) 首先代码(1)先通过Logger类的getLogger()方法得到一个Logger类的对象。在getLogger()方法中,通常把所在的类的Class对象或是所在类的全名作为参数。运用log4j输出日志要用到Logger对象。
2) 然后代码(2)进行一些必要的初始化,如要把调试信息输出到哪。当用System.out.println()时可以很明确的知道要把信息输出到标准输出设备且只能输出到那里。运用log4j,我们可以输出到许多地方,如控制台、文件、HTML文件等,至于要输出到哪里,就要自己进行初始化。在代码(2),我们调用自带的初始化方法来完成初始化。用这个方法进行初始化就不能体现出log4j的灵活性,所以基本上不会这样做。Log4j提供了用XML文件或Java配置文件来配置设置的方法,在下面我们将进行介绍。
3) 接着代码(3)就是输出信息的代码了。你可以看到代码(3)中尝试了用几种不同的方法来输出信息,对于这几种信息的作用,我会在下面进行介绍,你现在只需把它当成是输出语句就行。
最后,我们来看一下运行结果(日志信息)的意义。第一个数字是指程序开始运行到运行该日志语句所经历的毫秒数(用来做一点运行效率分析也不错),“[main]”是日志事件发生的线程,随后的“DEBUG”、“INFO”等信息是相应日志信息的优先级别,“TestLog4j.TestLog4”是当前TestLog4所在的包和名称,最后是日志信息。
2 实例原理
虽然完成了第一程序了,但程序中的内容还是不太了解。好,现在我就对上面的例子用到的log4j的原理进行讲解。在以后的章节中,我都会采取这种先实例,再根据实例来介绍所涉及的log4j原理的方法。
2.1 记录器Logger
Logger类是在log4j1.2以后才有的,以前是用Category类来实现现在的Logger类的功能的。从API可知,Logger类是Category类的子类。Logger类的代码如下:
- package org.apache.log4j;
- public class Logger {
- // 创建和取回方法:
- public static Logger getRootLogger();
- public static Logger getLogger(String name);
- public static Logger getLogger(Class class1);
- // 打印方法:
- 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);
- // 常用打印方法:
- public void log(Level l, Object message);
- }
在讨论Logger类中的方法之前,我先讲一下log4j中的级别(level)的概念。
2.1.1 级别Level
Log4j中的日志级别分为五种:DEBUG、INFO、WARN、ERROR和FATAL,这五种级别从左到右级别依次增加。
2.1.2 Logger中的打印函数与级别
对于每一个记录器,我们都可对它赋于一定的级别,而打印函数打印的即是相应级别的信息。当对一个级别为A的Logger调用级别为B的打印方法时,只有当B>=A时才会进行打印。例如,如果有一个级别为WARN的Logger对象logger,只有对它调用logger.warn (message)、logger.error (message)和logger.fatal (message)这三个打印函数才会打印信息;而调用logger.debug (message)和logger.info (message)则不会打印信息,因为debug()函数只有当logger的级别为DEBUG时才打印信息,info()函数只有当logger的级别为INFO时才打印信息。
除了对应于每一个级别有一个打印函数外,在Logger类中还有一个log(),它可以让你通过参数来指定一个打印信息的打印级别。
引入级别后就可通过修改调试的级别来控制某个调试信息是否输出。假设我们有的信息是在开发时才需要输出的(称为测试信息),那么我们把输出测试信息的Logger的级别在开发时设为DEBUG级别的,并用debug(Object message)函数来进行打印。当要发布系统时,只需把相应的Logger的级别调高就可以屏蔽掉测试信息。