log4j

Log4j简介

第1章.     Log4j 的优点


Log4jApache的一个开放源代码项目,通过使用 Log4j,我们可以控制日志信息输送的;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
log4j的好处在于:
1)        通过修改配置文件,就可以决定 log信息的目的地——控制台、文件、 GUI组件、甚至是套接口服务器、 NT的事件记录器、 UNIX Syslog守护进程等
2)        通过修改配置文件,可以定义每一条日志信息的级别,从而控制是否输出。在系统开发阶段可以打印详细的 log信息以跟踪系统运行情况 ,而在系统稳定后可以关闭 log输出 ,从而在能跟踪系统运行情况的同时 ,又减少了垃圾代码( System.out.println(...... ))
3)        使用 log4j,需要整个系统有一个统一的 log机制,有利于系统的规划。

第2章.     配置文件


Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式。日志信息的优先级从高到低有 FATALERRORWARNINFODEBUG,分别用来指定这条日志信息的重要程度;日志信息的输出目的地指定了日志将打印到控制台还是文件中;而输出格式则控制了日志信息的显示内容。

2.1.   日志信息的优先级


分为 OFFFATALERRORWARNINFODEBUGALL或者您定义的级别。
Log4j建议只使用四个级别,优先级从高到低分别是 ERRORWARNINFODEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。
假如在一个级别为 qLogger中发生一个级别为 p的日志请求,如果 p>=q,那么请求将被启用。这是 Log4j的核心原则。
比如在这里定义了 INFO级别,则应用程序中所有 DEBUG级别的日志信息将不被打印出来;

2.2.   输出源的使用


有选择的能用或者禁用日志请求仅仅是 Log4j的一部分功能。 Log4j允许日志请求被输出到多个输出源。用 Log4j的话说,一个输出源被称做一个 Appender
Appender包括 console(控制台) , files(文件) , GUI components(图形的组件) , remote socket serverssocket 服务) , JMSjava信息服务) , NT Event LoggersNT的事件日志) , and remote UNIX Syslog daemons(远程 UNIX的后台日志服务)。它也可以做到异步记录。
一个 logger可以设置超过一个的 appender
addAppender 方法添加一个 appender到一个给定的 logger。对于一个给定的 logger它每个生效的日志请求都被转发到该 logger所有的 appender上和该 logger的父辈 loggerappender上。

2.2.1.  ConsoleAppender


如果使用 ConsoleAppender,那么 log信息将写到 Console。效果等同于直接把信息打印到 System.out上了。

2.2.2.  FileAppender


使用 FileAppender,那么 log信息将写到指定的文件中。这应该是比较经常使用到的情况。
相应地,在配置文件中应该指定 log输出的文件名。如下配置指定了 log文件名为dglog. txt
log4j.appender.A2.File=dglog.txt
注意将 A2替换为具体配置中 Appender的别名。

2.2.3.  DailyRollingAppender


使用 FileAppender可以将 log信息输出到文件中,但是如果文件太大了读起来就不方便了。这时就可以使用 DailyRollingAppenderDailyRollingAppender可以把 Log信息输出到按照日期来区分的文件中。配置文件就会每天产生一个 log文件,每个 log文件只记录当天的 log信息:
log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.file=dglog
log4j.appender.A2.DatePattern='.'yyyy-MM-dd
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern= %5r %-5p %c{2} - %m%n

2.2.4.  org.apache.log4j.RollingFileAppender


文件大小到达指定尺寸的时候产生一个新的文件。
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File= ../logs/dglog.log
# Control the maximum log file size
log4j.appender.R.MaxFileSize=100KB
# Archive log files (one backup file here)
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
这个配置文件指定了输出源R,是一个轮转日志文件。最大的文件是100KB,当一个日志文件达到最大尺寸时,Log4J会自动把example.log重命名为dglog.log.1,然后重建一个新的dglog.log文件,依次轮转。

2.2.5.  org.apache.log4j.WriterAppender


将日志信息以流格式发送到任意指定的地方。

2.3.  Layout的配置


Layout指定了 log信息输出的样式。

2.3.1.  布局样式


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

2.3.2.  格式


%m 输出代码中指定的消息
%p 输出优先级,即 DEBUGINFOWARNERRORFATAL
%r 输出自应用启动到输出该 log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符, Windows平台为" rn", Unix平台为" n"
%d 输出日志时间点的日期或时间,默认格式为 ISO8601,也可以在其后指定格式,比如: %d{yyy MMM dd HH:mm:ss,SSS},输出类似: 20021018 221028921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例: Testlog4.main(Test Log4.java:10)

2.3.3.  例子


例子 1:显示日期和 log信息
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %m%n
打印的信息是:
2002-11-12 11:49:42,866 SELECT * FROM Role WHERE 1=1 order by createDate desc

例子 2:显示日期, log发生地方和 log信息
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %l "#" %m%n
2002-11-12 11:51:46,313 cn.net.unet.weboa.system.dao.RoleDAO.select(RoleDAO.java:409) "#"
SELECT * FROM Role WHERE 1=1 order by createDate desc
  
例子 3:显示 log级别 ,时间 ,调用方法 ,log信息
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS}
method:%l%n%m%n
log信息 :
[DEBUG] 2002-11-12 12:00:57,376
method:cn.net.unet.weboa.system.dao.RoleDAO.select(RoleDAO.java:409)
SELECT * FROM Role WHERE 1=1 order by createDate desc

2.4.   配置文件的例子:


log4j.rootLogger=DEBUG
#DAOlog记录到 DAOLog,allLog
log4j.logger.DAO=DEBUG,A2,A4
#将逻辑层 log记录到 BusinessLog,allLog
log4j.logger.Businesslog=DEBUG,A3,A4

#A1--打印到屏幕上
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-5p [%t] %37c %3x - %m%n

#A2--打印到文件 DAOLog--专门为 DAO层服务
log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.file=DAOLog
log4j.appender.A2.DatePattern='.'yyyy-MM-dd
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS}
method:%l%n%m%n

#A3--打印到文件 BusinessLog--专门记录逻辑处理层服务 log信息
log4j.appender.A3=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A3.file=BusinessLog
log4j.appender.A3.DatePattern='.'yyyy-MM-dd
log4j.appender.A3.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS}
method:%l%n%m%n

#A4--打印到文件 alllog--记录所有 log信息
log4j.appender.A4=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A4.file=alllog
log4j.appender.A4.DatePattern='.'yyyy-MM-dd
log4j.appender.A4.layout=org.apache.log4j.PatternLayout
log4j.appender.A4.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS}
method:%l%n%m%n

第3章.     API使用


log4j使用步骤有 3个:

3.1.   初始化

3.1.1.  Tomcat下的初始化


默认的 Log4j initialization典型的应用是在 web-server 环境下。在 tomcat3.xtomcat4.x下,你应该将配置文件 Log4j.properties放在你的 web应用程序的 WEB-INF/classes 目录下。
Log4j将发现属性文件,并且以此初始化。这是使它工作的最容易的方法。
你也可以选择在运行 tomcat前设置系统属性 Log4j.configuration 。对于 tomcat 3.xTOMCAT_OPTS 系统变量是用来设置命令行的选项。对于 tomcat4.0,用系统环境变量 CATALINA_OPTS 代替了 TOMCAT_OPTS
UNIX 命令行
export TOMCAT_OPTS="-DLog4j.configuration=foobar.txt"
告诉 Log4j用文件 foobar.txt作为默认的配置文件。这个文件应该放在 WEB-INF/classes 目录下。这个文件将被 PropertyConfigurator所读。每个 web-application将用不同的默认配置文件,因为每个文件是和它的 web-application 相关的。
1. export TOMCAT_OPTS="-DLog4j.debug -DLog4j.configuration=foobar.xml" export TOMCAT_OPTS="-DLog4j.debug -DLog4j.configuration=foobar.xml"
告诉 Log4j输出 Log4j-internal的调试信息,并且用 foobar.xml作为默认的配置文件。这个文件应该放在你的 web-applicationWEB-INF/classes 目录下。因为有 .xml的扩展名,它将被 DOMConfigurator所读。每个 web-application将用不同的默认配置文件。因为每个文件都和它所在的 web-application 相关的。
2. set TOMCAT_OPTS=-DLog4j.configuration=foobar.lcf
-DLog4j.configuratorClass=com.foo.BarConfigurator
告诉 Log4j用文件 foobar.lcf作为默认的配置文件。这个文件应该放在你的 web-applicationWEB-INF/classes 目录下。因为定义了 Log4j.configuratorClass 系统属性,文件将用自定义的 com.foo.barconfigurator类来解析。每个 web-application将用不同的默认配置文件。因为每个文件都和它所在的 web-application 相关的。
3. set TOMCAT_OPTS=-DLog4j.configuration=file:/c:/foobar.lcf 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-applicationLog4j配置没有用到同样的系统资源。

3.1.2.  Servlet 的初始化


用一个特别的 servlet来做 Log4j的初始化也是可以的。如下是一个例子:
public class Log4jInit extends HttpServlet {
public void init() {
String prefix = getServletContext().getRealPath("/");
String file = getInitParameter("Log4j-init-file");
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>xx.xx.Log4jInit</servlet-class>
<init-param>
<param-name>Log4j-init-file</param-name>
<param-value>WEB-INF/classes/Log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
写一个初始化的 servlet是最有弹性的初始化 Log4j的方法。代码中没有任何限制,你可以在 servletinit方法中定义它。

3.2.   根据配置文件初始化log4j


log4j可以使用 3中配置器来初始化: BasicConfigurator,DOMConfigurator,PropertyConfigurator
其语法为:
BasicConfigurator.configure () 自动快速地使用缺省 Log4j环境。
PropertyConfigurator.configure ( String configFilename) :读取使用 Java的特性文件编写的配置文件。
DOMConfigurator.configure ( String filename ) :读取 XML形式的配置文件。
这里用的是 PropertyConfigurator。使用 PropertyConfigurator适用于所有的系统。如下的语句:
PropertyConfigurator.configure("log4j.properties");
就以 log4j.properties为配置文件初始化好了 log4j环境。
注意一点:这个语句只需要在系统启动的时候执行一次。例如,在 ActionServletinit()方法中调用一次。
public class ActionServlet extends HttpServlet{
...
/**
* Initialize global variables
*/
public void init() throws ServletException {
// 初始化 Action资源
try{
initLog4j();
...
}catch(IOException e){
throw new ServletException("Load ActionRes is Error");
}
}
...
protected void initLog4j(){
PropertyConfigurator.configure("log4j.properties");
}
...
}//end class ActionServlet

3.3.   在需要使用log4j的地方获取Logger实例


使用 Log4j,首先就是获取日志记录器,这个记录器将负责控制日志信息。其语法为:
public static Logger getLogger( String name)
通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。 Name一般取本类的名字,比如:
static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () ) ;
     Log4j使得通过软件组件命名 logger很容易。我们可以通过 Logger的静态的初始化方法在每一个类里定义一个 logger,令 logger的名字等于类名的全局名,而实现 logger的命名。这是一个实效的简单的定义一个 logger的方法。因为日志输出带有产生日志的类的名字,这个命名策略使得我们更容易定位到一个日志信息的来源。虽然普通,但却是命名 logger的常用策略之一。
Log4j没有限制定义 logger的可能。开发员可以自由的按照它们的意愿定义 logger的名称。
然而,以类的所在位置来命名 Logger好象是目前已知的最好方法。

3.4.   使用Logger对象的debug,info,fatal...方法


log.debug("it is the debug info");

第4章.     优化


一个经常引用的依靠于 logging的参数是可以计算的花费。这是一个合理的概念,一个适度的应用程序可能产生成千上万个日志请求。许多努力花在测量和调试 logging的优化上。 Log4j要求快速和弹性:速度最重要,弹性是其次。

4.1.   日志为禁用时,日志的优化。


当日志被彻底的关闭,一个日志请求的花费等于一个方法的调用加上整数的比较时间。在 233mhzPentium II 机器上这个花费通常在 5-50纳秒之间。
然而,方法调用包括参数构建的隐藏花费。
例如,对于 logger catlogger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
引起了构建信息参数的花费,例如,转化整数 ientry[i]到一个 string,并且连接中间字符串,不管信息是否被输出。这个参数的构建花费可能是很高,它主要决定于被调用的参数的大小。
避免参数构建的花费应如下,

if(logger.isDebugEnabled())
{
        logger.debug("result is" + result );
}

如果 loggerdebug被关闭这将不会招致参数构建的花费。另一方面,如果 loggerdebug的话,它将产生两次判断 logger是否能用的花费。一次是在 debugenabled,一次是 debug。这是无关紧要的,因为判断日志的能用 只占日志实际花费时间的约 1%
Log4j里,日志请求在 Logger 类的实例里。 Logger 是一个类,而不是一个接口。这大量的减少了在方法调用上的弹性化的花费。
当然用户采用预处理或编译时间技术去编译出所有的日志声明。这将导致完美的执行成效。然而因为二进制应用程序不包括任何的日志声明的结果,日志不可能对那个二进制程序开启。以我的观点,以这种较大的代价来换取较小的性能优化是不值得的。

4.2.   当日志状态为启用时,日志的优化。


这是本质上的优化 logger的层次。当日志状态为开, Log4j依然需要比较请求的级别与 logger的级别。然而, logger可能没有被安排一个级别;它们将从它们的 father继承。这样,在继承之前, logger可能需要搜索它的 ancestor
这里有一个认真的努力使层次的搜索尽可能的快。例如,子 logger仅仅连接到它的存在的 father logger
在先前展示的 BasicConfigurator 例子中,名为 com.foo.bar logger是连接到跟根 logger,因此绕过 了不存在的 logger comcom.foo。这将显著的改善执行的速度,特别是解析 logger的层结构时。
典型的层次结构的解析的花费是 logger彻底关闭时的三倍。

4.3.   日志信息的输出时,日志的优化。


这是主要花费在日志输出的格式化和发送它到它的输出源上。这里我们再一次的付出努力以使格式化执行的尽可能快。同 appender一样。实际上典型的花费大约是 100-300毫秒。
详情看 org.apache.log4.performance.Logging
虽然 Log4j有许多特点,但是它的第一个设计目标还是速度。一些 Log4j的组件已经被重写过很多次以改善性能。不过,投稿者经常提出了新的优化。你应该满意的知道,以 SimpleLayout的配置执行测试已经展示了 Log4j的输出同 System.out.println一样快。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值