无法将值放在MDC中

Ram*_*kla 11 java logging wicket mdc

我试图登录的几个值onBeginRequest()RequestCycle()在检票口.但是这些值未记录在调试文件中.我将值放在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());
}
Run Code Online (Sandbox Code Playgroud)

};

我期待'serverName','sessionId'被记录在调试文件中.

listener在扩展的类中添加了这个WebApplication.

我使用的DEBUG appender是log4j.xml ,如下所示:

<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>
Run Code Online (Sandbox Code Playgroud)

我们在root标签中定义范围:

<root>
   <priority value="INFO" />
   <appender-ref ref="CONSOLE" />
   <appender-ref ref="DEBUG" />
   <appender-ref ref="ERROR" />
</root>
Run Code Online (Sandbox Code Playgroud)

sup*_*rEb 21

通常,如果通过配置在日志记录模式中包含MDC密钥,则MDC值仅输出到日志.由于slf4j只是一个外观,您需要在slf4j下面具有特定于框架的支持和配置才能使用MDC.在这里阅读slf4j的注释.

所以,例如,如果你使用log4j作为slf4j下面的impl,那么你需要log4j config(ConversionPattern),如:

%d %-5p [%c] [%X{serverName} %X{sessionId}] %m%n
Run Code Online (Sandbox Code Playgroud)

%X{serverName} %X{sessionId}从MDC中提取值的相关部分在哪里?

是使用没有sl4j的log4j的一个很好的例子.查看笔记X中的log4j的javadoc转换字符在这里.

请注意,logback的模式语法是相同的.请在此处查看有关回滚的详细信息.

另请注意,MDC(使用底层)的最佳实践ThreadLocal是在上下文不再在范围内时清除上下文(删除放在地图中的值).这通常意味着调用removeclearfinally块中,如:

try {
    //...
    MDC.put("key1", value1);
    MDC.put("key2", value2);
    //...
} finally {
    //this
    MDC.remove("key1");
    MDC.remove("key2");
    //or this
    MDC.clear();
}
Run Code Online (Sandbox Code Playgroud)

如果持有MDC的线程属于池以供以后重用,则这一点尤为重要.您当然不希望无意中记录无效的上下文值,因为这只会引起混淆.

编辑

你的log4j配置看起来有点奇怪,原因如下:

  1. 您在日志级别之后命名您的appender,这可能会导致混淆
  2. RollingFileAppender没有定义文件
  3. 您的root记录器将记录到3个不同的appender,其中一个已命名DEBUG,但它被配置为仅记录INFO级别和更高级别(基于priority标记),因此不会记录调试语句

除非你有单独未显示的配置一些具体类别,我猜想,没有你的LOGGER.debug语句被记录下来,无论你试图使用MDC的.