最近使用log4j库,由于需要输出xml格式的日志文件,有关输出MDC和NDC内容,折腾了整整一天,最后还是切换使用log4j2.x才能够成功。网上搜索了很久都没能找到原因,国内外搜了上百篇,借鉴一些帖子,然后推断出了原因。现整理如下,作为备忘录。
1、下载log4j-1.2.17.jar,可以到网站http://mvnrepository.com/搜索,这个网站的jar包很全。
2、使用eclpise创建一个工程,把log4j-1.2.17.jar加上。
3、编写Log类,代码如下:
import org.apache.log4j.Logger;import org.apache.log4j.MDC;import org.apache.log4j.NDC;import org.apache.log4j.PropertyConfigurator;import org.apache.log4j.xml.DOMConfigurator;public class Log {public static void main(String[] args) {Logger log = Logger.getRootLogger();DOMConfigurator.configureAndWatch("log4j.xml");log.debug("Sample debug message");log.info("Sample info message");log.error("Sample error message");log.fatal("Sample fatal message");}}
配置文件,输出格式xml文件,因此需要需要使用org.apache.log4j.xml.XMLLayout。如下:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration debug="false" xmlns:log4j='http://jakarta.apache.org/log4j/'><appender name="FILE" class="org.apache.log4j.RollingFileAppender"><param name="threshold" value="debug" /><param name="file" value="log4jlog.xml" /><param name="maxBackupIndex" value="5" /><param name="append" value="true" /><layout class="org.apache.log4j.xml.XMLLayout"></layout></appender><root><level value="DEBUG" /><appender-ref ref="FILE" /></root></log4j:configuration>
运行输出:
<log4j:event logger="root" timestamp="1468679895876" level="DEBUG" thread="main"><log4j:message><![CDATA[Sample debug message]]></log4j:message></log4j:event><log4j:event logger="root" timestamp="1468679895877" level="INFO" thread="main"><log4j:message><![CDATA[Sample info message]]></log4j:message></log4j:event><log4j:event logger="root" timestamp="1468679895878" level="ERROR" thread="main"><log4j:message><![CDATA[Sample error message]]></log4j:message></log4j:event><log4j:event logger="root" timestamp="1468679895878" level="FATAL" thread="main"><log4j:message><![CDATA[Sample fatal message]]></log4j:message></log4j:event>
4、在多线程环境中,有需要需要打印线程信息,就需要使用MDC或NDC(网上有概念介绍),网上实例都是PatternLayout介绍的,没有针对XMLLayout。代码如下:
import org.apache.log4j.Logger;import org.apache.log4j.MDC;import org.apache.log4j.NDC;import org.apache.log4j.PropertyConfigurator;import org.apache.log4j.xml.DOMConfigurator;public class Log {public static void main(String[] args) {Logger log = Logger.getRootLogger();MDC.put("key", "value");MDC.put("key2", "value2");NDC.push("haha");DOMConfigurator.configureAndWatch("og4j.xml");log.debug("Sample debug message");log.info("Sample info message");log.error("Sample error message");log.fatal("Sample fatal message");NDC.clear();MDC.clear();}}
<log4j:event logger="root" timestamp="1468680531531" level="DEBUG" thread="main"><log4j:message><![CDATA[Sample debug message]]></log4j:message><log4j:NDC><![CDATA[haha]]></log4j:NDC></log4j:event><log4j:event logger="root" timestamp="1468680531532" level="INFO" thread="main"><log4j:message><![CDATA[Sample info message]]></log4j:message><log4j:NDC><![CDATA[haha]]></log4j:NDC></log4j:event><log4j:event logger="root" timestamp="1468680531532" level="ERROR" thread="main"><log4j:message><![CDATA[Sample error message]]></log4j:message><log4j:NDC><![CDATA[haha]]></log4j:NDC></log4j:event><log4j:event logger="root" timestamp="1468680531532" level="FATAL" thread="main"><log4j:message><![CDATA[Sample fatal message]]></log4j:message><log4j:NDC><![CDATA[haha]]></log4j:NDC></log4j:event>
从输出来看,MDC的内容没有输出,原因是选项开关没打开,这个还是通过看源代码猜到的原因,配置参数为Properties,把这个值设为true(LocationInfo选项是当前函数信息,这个挺有用的)。log4j.jar版本很多,犯了一个基本错误,开始用了老版本jar始终不能解决问题,居然以为log4j-1.2.9比log4j-1.2.17新。等我弄好了log4j2再回头long4j1的时候,才发现版本弄错了,浪费了一整天的时间。
修改的xml配置文件如下:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration debug="false" xmlns:log4j='http://jakarta.apache.org/log4j/'><appender name="FILE" class="org.apache.log4j.RollingFileAppender"><param name="threshold" value="debug" /><param name="file" value="log4jlog.xml" /><param name="maxBackupIndex" value="5" /><param name="append" value="true" /><layout class="org.apache.log4j.xml.XMLLayout"><param name="LocationInfo" value="true" /><param name="Properties" value="true" /></layout></appender><root><level value="DEBUG" /><appender-ref ref="FILE" /></root></log4j:configuration>
重新运行,输出对了,MDC这个关键字并没有输出,使用log4cxx是有的,原因是新版本好像改掉了。但现在还有个问题,如果需要输出MDC,就只有扩展appender了。
<log4j:event logger="root" timestamp="1468680646638" level="DEBUG" thread="main"><log4j:message><![CDATA[Sample debug message]]></log4j:message><log4j:NDC><![CDATA[haha]]></log4j:NDC><log4j:locationInfo class="testlog4j.Log" method="main" file="Log.java" line="22"/><log4j:properties><log4j:data name="key" value="value"/><log4j:data name="key2" value="value2"/></log4j:properties></log4j:event><log4j:event logger="root" timestamp="1468680646641" level="INFO" thread="main"><log4j:message><![CDATA[Sample info message]]></log4j:message><log4j:NDC><![CDATA[haha]]></log4j:NDC><log4j:locationInfo class="testlog4j.Log" method="main" file="Log.java" line="23"/><log4j:properties><log4j:data name="key" value="value"/><log4j:data name="key2" value="value2"/></log4j:properties></log4j:event><log4j:event logger="root" timestamp="1468680646641" level="ERROR" thread="main"><log4j:message><![CDATA[Sample error message]]></log4j:message><log4j:NDC><![CDATA[haha]]></log4j:NDC><log4j:locationInfo class="testlog4j.Log" method="main" file="Log.java" line="24"/><log4j:properties><log4j:data name="key" value="value"/><log4j:data name="key2" value="value2"/></log4j:properties></log4j:event><log4j:event logger="root" timestamp="1468680646641" level="FATAL" thread="main"><log4j:message><![CDATA[Sample fatal message]]></log4j:message><log4j:NDC><![CDATA[haha]]></log4j:NDC><log4j:locationInfo class="testlog4j.Log" method="main" file="Log.java" line="25"/><log4j:properties><log4j:data name="key" value="value"/><log4j:data name="key2" value="value2"/></log4j:properties></log4j:event>
结论:java不熟悉,麻烦的不是java,而是第三方库的使用,总感觉通过xml配置麻烦,不如直接用api来得直观。可能是用c++用惯了,总是想从基本原理看起,快速搭建环境。log4j的配置,也可以通过properties文件实现。上述的配置文件也可以写成:
# Define the root logger with file appenderlog4j.rootLogger = DEBUG, XML# Define the file appenderlog4j.appender.XML=org.apache.log4j.FileAppenderlog4j.appender.XML.File=log4jlog.xml# Define the xml layout for file appenderlog4j.appender.XML.layout=org.apache.log4j.xml.XMLLayoutlog4j.appender.XML.layout.LocationInfo=truelog4j.appender.XML.layout.Properties=truelog4j.appender.XML.Threshold=DEBUG
使用下面的代码进行读取配置文件,配置文件的路径可以依据你的工程指定,可以使用绝对路径:
PropertyConfigurator.configure("log4j.properties");
本文介绍如何使用 Log4j 库输出 XML 格式的日志文件,并详细记录了配置过程中遇到的问题及解决方法,包括如何正确配置 MDC 和 NDC 的内容。
1297

被折叠的 条评论
为什么被折叠?



