Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法将值放入MDC中_Java_Logging_Wicket_Mdc - Fatal编程技术网

Java 无法将值放入MDC中

Java 无法将值放入MDC中,java,logging,wicket,mdc,Java,Logging,Wicket,Mdc,我试图在wicket中的RequestCycle()的onBeginRequest()中记录一些值。 但是这些值没有记录在调试文件中。我正在将值放入MDC中的RequestCycleListeners() 代码如下: getRequestCycleListeners().add(new AbstractRequestCycleListener() { public void onBeginRequest(RequestCycle cycle) {

我试图在wicket中的
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配置似乎有点奇怪,原因如下:

  • 您正在以日志级别命名appender,这可能会导致混淆
  • 您的
    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();
    }