日志主要用于记录程序运行的情况,以便于程序在部署之后的排错调试等等!也有利于将这些信息进行持久化,否则信息便会丢失。很多时候,系统出现的异常都是碰巧的,很难再现的,所以需要实时监控,记录运行日志信息。

 

介绍下日志工具:logging,log4j,commons-logging。

loggingjava自带的,在JDKjava.util.logging.*包是日志记录API

Log4jJDK Logging更加成熟,是日志记录标准。

 

commons-logging,是一个接口抽象,底层的实现可以自动替换:

如果当前存在log4j,则使用log4j来实现

否则,使用JDKlogging来实现

否则,使用其自身的简单实现

 

通常使用Commons-log接口,使用log4j实现

 

一个日志工具,至少应该包括以下几个组成部分:

1Logger

Logger按照布局中指定的格式把日志信息写入一个或多个输出源,Log4j 允许开发人员定义多个Logger每个Logger拥有自己的名字,Logger之间通过名字来表明隶属关系

 

2Level

它还有一个重要的属性——日志级别。不管何种日志记录工具,大概包含如下几种日志级别,优先级由低到高:DEBUG,INFO,WARN,ERROR,FATAL

 

在程序中打印日志信息时,优先级别低于配置文件中指定的级别时,将不做任何处理;比如配置文件中指定优先级别是WARN,当程序中有代码logger.info(message),则对message不会进行处理(输出到控制台或者文件)

 

     log4j中,使用

log4j.rootLogger=[级别][使用哪个appender]

log4.logger.[logger的名称]=[级别][使用哪个appender]

     来对logger进行配置如果某个logger没有进行配置,那么就会使用rootLogger的配置信息。

 

3Appender

       一个Appender表示一个输出的目的地Appendr可以是控制台、文本文件、XML文件或Socket。一个Logger可以拥有多个Appender ,即可以将种信息输出到多个位置。

 

log4j中,使用

log4j.appender.[appender的名称]=[appender类名]

log4j.appender.[appender的名称].[appender的属性名]=[appender的属性值]

来对appender进行配置

 

4Layout

Layout组件负责格式化输出的日志信息,一个Appender只能有一个Layout

log4j中,使用

log4j.appender.[appender的名称].layout=[layout的类名]                

log4j.appender.[appender的名称].layout.[layout的属性名]=[layout的属性名]

来对layout进行配置

 

       log4j采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:

        %m输出代码中指定的消息

        %p输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL

        %r输出自应用启动到输出该log信息耗费的毫秒数

        %c输出所属的类目,通常就是所在类的全名

        %t输出产生该日志事件的线程名

        %n输出一个回车换行符,Windows平台为“\r\n”Unix平台为“\n”

        %d输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,如:%d{yyyyMM dd HH:mm:ss}

        %l输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数

 

通过实例讲解日志处理过程

log4j.properties log4j的配置信息

 

###direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE}%5p %c{1}:%L - %m%n
 
#direct messages to file
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=d:/oa.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE}%5p %c{1}:%L - %m%n
 
#set log levels
log4j.rootLogger=warn,stdout, file
 
#对com.bjsxt目录及其子目录有效,如果不指明,则遵循log4j.rootLogger
log4j.logger.com.bjsxt =debug,stdout,file

 

 

在代码中应用

 

import org.apache.commons.logging.Log;  
import org.apache.commons.logging.LogFactory;  
import org.apache.log4j.Logger;  
  
public class Log4jTest {  
      
    private static Log logger = LogFactory.getLog(Log4jTest.class);  
      
    public static void main(String[] args) {  
          
            logger.debug("发现异常:异常信息是 非法登录,导致User对象为null");  
    }  
}  


 

 

控制台和d:/oa.log中的日志信息:

2013-08-1310:06:23 Log4jTest.main(Log4jTest.java:11)发现异常:异常信息是非法登录,导致User对象为null

 

对于日志的使用,还可以结合AOP(面向切面编程)的思想

通过代理模式进行使用,在我的这篇博客反射机制剖析(三): 谈谈代理模式是如何体现反射的有所讲解。