日志主要用于记录程序运行的情况,以便于程序在部署之后的排错调试等等!也有利于将这些信息进行持久化,否则信息便会丢失。很多时候,系统出现的异常都是碰巧的,很难再现的,所以需要实时监控,记录运行日志信息。
介绍下日志工具:logging,log4j,commons-logging。
logging是java自带的,在JDK中java.util.logging.*包是日志记录API。
Log4j比JDK Logging更加成熟,是日志记录标准。
commons-logging,是一个接口抽象,底层的实现可以自动替换:
如果当前存在log4j,则使用log4j来实现
否则,使用JDKlogging来实现
否则,使用其自身的简单实现
通常使用Commons-log接口,使用log4j实现
一个日志工具,至少应该包括以下几个组成部分:
1、Logger
Logger按照布局中指定的格式把日志信息写入一个或多个输出源,Log4j 允许开发人员定义多个Logger,每个Logger拥有自己的名字,Logger之间通过名字来表明隶属关系。
2、Level
它还有一个重要的属性——日志级别。不管何种日志记录工具,大概包含如下几种日志级别,优先级由低到高:DEBUG,INFO,WARN,ERROR,FATAL。
在程序中打印日志信息时,优先级别低于配置文件中指定的级别时,将不做任何处理;比如配置文件中指定优先级别是WARN,当程序中有代码logger.info(message),则对message不会进行处理(输出到控制台或者文件)
在log4j中,使用
log4j.rootLogger=[级别],[使用哪个appender]
log4.logger.[logger的名称]=[级别],[使用哪个appender]
来对logger进行配置。如果某个logger没有进行配置,那么就会使用rootLogger的配置信息。
3、Appender
一个Appender表示一个输出的目的地。Appendr可以是控制台、文本文件、XML文件或Socket。一个Logger可以拥有多个Appender ,即可以将种信息输出到多个位置。
在log4j中,使用
log4j.appender.[appender的名称]=[appender类名]
log4j.appender.[appender的名称].[appender的属性名]=[appender的属性值]
来对appender进行配置
4、Layout
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平台为“ ”,Unix平台为“ ”
%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(面向切面编程)的思想
通过代理模式进行使用,在我的这篇博客反射机制剖析(三): 谈谈代理模式是如何体现反射的有所讲解。