我试图在门票中的RequestCycle()的onBeginRequest()中记录几个值.
但是这些值没有被记录在调试文件中.我将值放在MDC中的RequestCycleListeners()中.
但是这些值没有被记录在调试文件中.我将值放在MDC中的RequestCycleListeners()中.
以下是代码:
getRequestCycleListeners().add(new AbstractRequestCycleListener() { public void onBeginRequest(RequestCycle cycle) { if( cycle.getRequest().getContainerRequest() instanceof HttpServletRequest ) { HttpServletRequest containerRequest = (HttpServletRequest)cycle.getRequest().getContainerRequest(); MDC.put("serverName",containerRequest.getServerName()); MDC.put("sessionId",containerRequest.getSession().getId()); LOGGER.debug("logging from RequestCycleListeners() !!!"); WebClientInfo webClientInfo = new WebClientInfo(RequestCycle.get()); System.out.println(webClientInfo.getUserAgent()); System.out.println("webClientInfo.getProperties().getBrowserVersionMajor() " +containerRequest.getRemoteAddr()); }
};
我期待’serverName’,’sessionId’被记录在调试文件中.
我已经在扩展WebApplication的类中添加了这个监听器.
我使用的是log4j.xml,DEBUG appender如下所示:
<appender name="DEBUG" class="org.apache.log4j.rolling.RollingFileAppender"> <param name="Append" value="true"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%d{ISO8601} %t %5p] %m -- %X{serverName} -- %X{sessionId} -- %X{portNumber}%n"/> </layout> <filter class="org.apache.log4j.varia.LevelRangeFilter"> <param name="LevelMin" value="DEBUG"/> <param name="LevelMax" value="WARN"/> </filter> </appender>
我们正在根标记中定义范围:
<root> <priority value="INFO" /> <appender-ref ref="CONSOLE" /> <appender-ref ref="DEBUG" /> <appender-ref ref="ERROR" /> </root>
解决方法
通常,如果您通过配置在记录模式中包含MDC密钥,则MDC值仅输出到日志.由于slf4j只是一个立面,您需要在slf4j下面使用框架特定的支持和配置来使用MDC.阅读slf4j关于
here的注释.
所以,例如,如果您使用log4j作为slf4j下的impl,那么您将需要log4j config(ConversionPattern),如:
%d %-5p [%c] [%X{serverName} %X{sessionId}] %m%n
其中%X {serverName}%X {sessionId}是从MDC中提取值的相关部分.
Here是一个非常好的例子,使用没有sl4j的log4j.请参阅log4j javadoc here中X转换字符的注释.
请注意,logback的模式语法是相同的.请参阅logback here的详细信息.
另请注意,MDC(使用ThreadLocal的引擎)的最佳做法是在上下文不再在范围内时清除上下文(删除您在地图中放置的值).这通常意味着在finally块中调用remove或clear,如:
try { //... MDC.put("key1",value1); MDC.put("key2",value2); //... } finally { //this MDC.remove("key1"); MDC.remove("key2"); //or this MDC.clear(); }
如果保存MDC的线程属于一个池以供以后重用,这一点尤为重要.您当然不想无意地记录无效的上下文值,因为这将导致混乱.
编辑
您的log4j配置似乎有点奇怪,原因如下:
>您正在命名您的追加者日志级别,这可能会导致混乱
>您的RollingFileAppender没有定义一个文件
>您的根记录器将记录到3个不同的追加器,其中一个被称为DEBUG,但是它被配置为仅记录INFO级别和更高级别(基于优先级标签),因此不会记录调试语句
除非您具有单独配置的未显示的特定类别,否则我猜测您的LOGGER.debug语句都不会被记录,无论您尝试使用MDC.