NDC和MDC apache
NDC(Nested Diagnostic Context)和MDC(Mapped Diagnostic Context)是log4j种很是有用的两个类,它们用于存储应用程序的上下文信息(context infomation),从而便于在log中使用这些上下文信息。 app
NDC采用了一个相似栈的机制来push和pop上下文信息,每个线程都独立地储存上下文信息。好比说一个servlet就能够针对每个request建立对应的NDC,储存客户端地址等等信息。 线程
当使用的时候,咱们要尽量确保在进入一个context的时候,把相关的信息使用NDC.push(message);在离开这个context的时候使用NDC.pop()将信息删除。另外因为设计上的一些问题,还须要保证在当前thread结束的时候使用NDC.remove()清除内存,不然会产生内存泄漏的问题。 设计
存储了上下文信息以后,咱们就能够在log的时候将信息输出。在相应的PatternLayout中使用”%x”来输出存储的上下文信息,下面是一个PatternLayout的例子: 日志
%r [%t] %-5p %c{2} %x - %m%n 内存
使用NDC最重要的好处就是,当咱们想输出一些上下文的信息的时候,不须要让logger去寻找这些信息,而只须要在适当的位置进行存储,而后再配置文件中修改PatternLayout。在最新的log4j 1.3版本中增长了一个org.apache.log4j.filters.NDCMatchFilter,用来 开发
根据NDC中存储的信息接受或拒绝一条log信息。 rem
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。 get
至于选择NDC仍是MDC要看须要存储的上下文信息是堆栈式的仍是key/value形式的。 servlet
动态修改日志配置
在开发过程当中,咱们常常会遇到修改log4j配置的状况,在这种状况下,频繁重启应用显然是不可接受的。幸亏log4j提供了自动从新加载配置文件的能力,在配置文件修改后,便会本身从新加载配置。在1.2及之前的版本中DOMConfigurator和PropertyConfigurator都提供了configureAndWatch方法,对指定的配置文件进行监控,而且能够设置检查的间隔时间。