首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

LOG4J-日记工具包

2012-10-08 
LOG4J-日志工具包log4j有记录器(loggers)、输出源(appenders)、级别(levels)、布局(layouts)4个部分组成。1,记

LOG4J-日志工具包

log4j有记录器(loggers)、输出源(appenders)、级别(levels)、布局(layouts)4个部分组成。

1,记录器

?? ?调用log4j的logger.getLogger()方法将会得到一个logger的实例。如果一个应用中能够包含了上千个类,那么几乎需要上千个logger实例。

如何对这上千个logger实例进行方便地配置,就是一个很重要的问题。log4j采用了一种树状的继承层次关系,它们有一个共同的根,位于最上层。?

2,输出源

?? ?输出源可以是控制台、文本文件、xml文件、socket、windows事件日志、Eamil,这些相关的处理类是ConsoleAppender、FileAppender、SocketAppender、

NtEventLogAppender、SMTPAppender。我们常用的输出源是文本文件。?

3,级别

?? ?log4j内置5种日志级别为: DEBUG(调试) < INFO(信息) < WARN(警告) < ERROR(错误) < FATAL(致命错误)?

4,布局

?? ?log4j采用了类似C语言中的printf()函数的打印格式对日志信息进行格式化,打印参数如下:

?? ?%m ?输出代码中指定的信息

?? ?%p ?输出日志级别,即DEBUG、INFO等

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

?? ?%c ?输出所属的类目,通常是所在类的全名,如果加上{<层数>}表示列出从最内层算起的指定层数的名字空间。

?? ?%C ?输出所属的类目,通常是所在类的简名

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

?? ?%n ?输出换行符

?? ?%d ?输出日志时间,默认格式是ISO8601,也可自定义,如:%d{yyyy MM dd HH:mm:ss,SSS} ,输出为:2011 10 18 22:10:28,921?

?? ?%L ?输出日志事件在代码中的行号

?? ?%i ?输出日志事件的类目名、线程名、行号

?? ?%F ?输出文件名

?? ?%x ?按NDC(Nested Diagnostic Context,线程堆栈)顺序输出日志

?? ?%X ?按MDC(Mapped Diagnostic Context,线程映射表)输出日志。

?

5,配置

?? ?log4j.properties

?? ?log4j.appender.normallog=org.apache.log4j.DailyRollingFileAppender #可定义单个文件最大值,在每日零点自动归档

?? ?log4j.appender.normallog.layout=org.apache.log4j.PatternLayout

?? ?log4j.appender.normallog.layout.ConversionPattern=%d %5p [%t](%F:%L)-%m%n

?? ?log4j.appender.normallog.File=mylog.log

?? ?log4j.appender.normallog.DatePattern='.'yyyy-MM-dd?

?? ?log4j.rootlogger=info,normallog

?? ?log4j是利用类装载器(ClassLoader)查找配置文件的,提高了系统的可移植性。

?

?6,执行顺序

?? ?loger.info() -> Log4JLogger.info() ->Category.log(),forcedLog,callAppenders ->AppenderAttachableImpl.appendLoopOnAppenders() ->

?? ?ConsoleAppender.doAppend()->AppenderSkeleton.doAppend()->WriterAppender.append(),subAppend -> PatternLayout.format()

?? ?注: PatternLayout实例化时,构建PatternParser,并执行parse方法。

?? ? ? ?PatternLayout.format时,执行PatternConverter的format方法和convert方法。

?

?7,自定义layout

?? ?a,定义PatternLayout类,继承PatternLayout类,重写createPatternParser方法和构造函数,如:org.jboss.logging.layout.PatternLayout

?? ?b,定义PatternParser类,继承PatternParser,重写finalizeConverter方法和构造函数,如:org.jboss.logging.layout.PatternParserEx

?? ?c,定义PatternConverter类,继承PatternConverter,重写convert方法和构造函数,如:org.jboss.logging.layout.ThreadNDCConverter

//返回当前调用线程的ID

@Override

protected String convert(LoggingEvent event) {

return String.valueOf(Thread.currentThread().getId());

}

?

8,NDC和MDC

?? ? ?NDC(Nested Diagnostic Context)和MDC(Mapped Diagnostic Context)是log4j种非常有用的两个类,它们用于存储应用程序的上下文信息(context infomation),从而便于在log中使用这些上下文信息。?

?? ? ?NDC采用了一个类似栈的机制来push和pop上下文信息,每一个线程都独立地储存上下文信息。比如一个servlet就可以针对每一个request创建对应的NDC,储存客户端地址等等信息。当使用的时候,我们要尽可能确保在进入一个context的时候,把相关的信息使用NDC.push(message);在离开这个context的时候使用NDC.pop()将信息删除。另外由于设计上的一些问题,还需要保证在当前thread结束的时候使用NDC.remove()清除内存,否则会产生内存泄漏的问题。在最新的log4j 1.3版本中增加了一个org.apache.log4j.filters.NDCMatchFilter,用来根据NDC中存储的信息接受或拒绝一条log信息。?

?? ? ?MDC和NDC非常相似,所不同的是MDC内部使用了类似map的机制来存储信息,上下文信息也是每个线程独立地储存,所不同的是信息都是以它们的key值存储在”map”中。相对应的方法,MDC.put(key, value); MDC.remove(key); MDC.get(key); 在配置PatternLayout的时候使用:%x{key}来输出对应的value。同样地,MDC也有一个org.apache.log4j.filters.MDCMatchFilter。MDC是线程独立的,但是一个子线程会自动获得一个父线程MDC的copy。至于选择NDC还是MDC要看需要存储的上下文信息是堆栈式的还是key/value形式的。

?

热点排行