Java 无法将值放入MDC中
我试图在wicket中的Java 无法将值放入MDC中,java,logging,wicket,mdc,Java,Logging,Wicket,Mdc,我试图在wicket中的RequestCycle()的onBeginRequest()中记录一些值。 但是这些值没有记录在调试文件中。我正在将值放入MDC中的RequestCycleListeners() 代码如下: getRequestCycleListeners().add(new AbstractRequestCycleListener() { public void onBeginRequest(RequestCycle cycle) {
RequestCycle()
的onBeginRequest()
中记录一些值。
但是这些值没有记录在调试文件中。我正在将值放入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
的类中添加了这个listener
我使用的是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的注释 例如,如果您使用log4j作为slf4j下的impl,那么您需要log4j配置(ConversionPattern),如: 其中,
%X{serverName}%X{sessionId}
是从MDC提取值的相关部分
这是一个使用log4j而不使用sl4j的很好的例子。请参阅log4j javadoc中关于X
转换字符的注释
注意,logback的模式语法是相同的。请参阅详细信息以了解回登录
还请注意,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
未定义文件root
记录器将记录到3个不同的附加器,其中一个名为DEBUG
,但它被配置为仅记录INFO
级别及更高级别(基于优先级
标记),因此不会记录调试语句除非您单独配置了一些未显示的特定类别,否则我猜无论您是否尝试使用MDC,
LOGGER.debug
语句都不会被记录。请注意,如果您使用的是AsyncAppender,从线程中清除MDC不会保护您,因为日志事件和MDC处理发生在AsyncAppender的线程中。另见
不幸的是,在下线log4j-1.x的最新版本v1.2.17中,AsyncAppender的Dispatcher线程在停止时也不会清除MDC
由于AsyncAppender/Dispatcher相当简单,因此通过放置
finally
{
MDC.clear();
}
在org.apache.log4j.AsyncAppender.Dispatcher.run()方法的try块中
当然,也可以通过在ServletContainer中执行时不使用AsyncAppender来解决这个问题。@Buurman:这是一种日志机制。您可以在这里看到更多,您在slf4j下面使用的是什么日志框架?log4j,logback,java.util.logging,commons logging?@superEb:现在就看log4j@RamDuttShukla请将您的
log4j
配置和一些应用程序中的示例日志添加到问题中,好吗?这可能会有帮助。谢谢。@Jonathan:添加了log4j.xml配置。仅在superEb的答案中添加了logback手册中关于如何使用MDC的内容。我尝试了与您在答案中建议的方法相同的方法,参考veera sundar的博客,但问题在某种程度上有所不同。我接受这个答案,因为解释非常有用。虽然它没有正确的答案,但它帮助我得到答案。@RamDuttShukla-我注意到你没有接受我的答案。请参阅我对编辑部分所做的补充。它可能会帮助您解决日志记录问题。是的,不记录日志的原因是标签。你是对的。现在我将再次接受答案,谢谢。
finally
{
MDC.clear();
}