log4j输出ip地址等附加信息

jing31 发布于 2010/11/22 11:18
阅读 3K+
收藏 3

默认的log4j输出语法中并没有当前线程IP地址等相关信息,如果log需要记录怎么办?

答案是借助于log4j的“NDC(嵌套诊断环境)”来处理。

NDC是什么?举例来说,如果一个Servlet接到并发请求时,为每一个客户端创建一个新的线程,然后分配一个用于保存该请求上下文的NDC堆栈。该上下文可能是发出请求的主机名、IP地址或其它任何可以用于标识该请求的信息。这样,由于不同的客户端处理线程具有不同的NDC堆栈,即使这个Servlet同时生成多个线程处理不同的请求,这些日志信息仍然可以区分出来,就好像Log4J为每一个线程都单独生成了一个Logger实例一样。在Log4J中是通过org.apache.log4j.NDC实现这种机制的。

NDC代码声明:

 

public class NDC {
    // 返回诊断堆栈的内容
    public static String get();
    // 从堆栈的顶端删除一个元素
    public static String pop();
    //在堆栈顶端加入一个元素
    public static void push(String message);
    //察看这个堆栈最顶层的元素,但不删除它
    public static String peek()
    // 删除这个线程的堆栈内容
    public static void remove();
}

 

 

使用NDC的方法也很简单,步骤如下:

 1. 在进入一个环境时调用NDC.push(String),然后创建一个NDC;

 2. 所做的日志操作输出中包括了NDC的信息;

 3. 离开该环境时调用NDC.pop方法;

 4. 当从一个线程中退出时调用NDC.remove方法,以便释放资源。

在log4j的配置文件中的输入样式中,用%x对NDC内容进行输出。

例如:

 

NDC.push(CommonTools.getIpAddr());
Logger.getLogger().info(“go into the method”);
NDC.pop();
NDC.remove();

 

配置文件:

log4j.appender.stdout.layout.ConversionPattern=[%d{yyyy-MM-dd HH🇲🇲ssS}] [%x] : %m%n  

输出:[2010-11-22 09:32:3193] [127.0.0.1] : go into the method

 

另外,还有一种MDC 和 NDC 相似,也可以减少多线程的系统为每个客户单独记录日志的系统开销。它同样是为每个线程建立一个独立的存储空间,开发人员可以根据需要把信息存入其中。不同的是 MDC 使用 Map 的机制来存储信息,信息以 key/value 对的形式存储在 Map 中。

MDC代码声明:
public class MDC {
    // 清空map所有的条目。
    public static void clear();
    // 根据key值返回相应的对象
    public static object get(String key);
    //返回所有的key值.
    public static Enumeration getKeys();
    //把key值和关联的对象,插入map中
    public static void put(String key, Object val),
    //删除key对应的对象
    public static  remove(String key)
}
MDC 和 NDC 的使用方法也类似,区别只是在 Log4J配置文件中,在通过 PatternLayout 的 ConversionPattern 来配置日志的格式的时候,需要使用 %X{key} 来输出相应的用户标志信息对象。

加载中
返回顶部
顶部