我正在尝试在wicket中的onBeginRequest()RequestCycle()中记录一些值。
但是这些值未记录在调试文件中。我将值放在RequestCycleListeners()的MDC中。

以下是代码:

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”。

我在扩展listener的类中添加了这个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标签中定义作用域:
<root>
   <priority value="INFO" />
   <appender-ref ref="CONSOLE" />
   <appender-ref ref="DEBUG" />
   <appender-ref ref="ERROR" />
</root>

最佳答案

通常,只有在通过配置将MDC key 包括在日志记录模式中时,MDC值才会输出到日志。由于slf4j只是一个外观,因此您需要在slf4j下具有特定于框架的支持和配置才能使用MDC。阅读关于here的slf4j的注释。

因此,举例来说,如果您将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 here的详细信息。

还要注意,MDC的最佳实践(在后台使用ThreadLocal)是在上下文不在范围内时清除上下文(删除在 map 中输入的值)。这通常意味着在remove块中调用clearfinally,例如:
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级别和更高级别(基于priority标记),因此调试语句不会被记录

  • 除非您有一些未单独配置的特定类别,这些类别没有显示,否则我想您的LOGGER.debug语句都不会被记录,无论您尝试使用MDC如何。

    10-08 05:21