LOG4J-日志工具包

本文详细介绍了log4j的核心组成部分,包括记录器、输出源、日志级别和布局,以及配置方式和执行顺序。此外,还讲解了自定义布局、NDC和MDC的概念和使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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形式的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值