java – 不能将值放在MDC中

前端之家收集整理的这篇文章主要介绍了java – 不能将值放在MDC中前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在门票中的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的类中添加了这个监听器.

我使用的是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.

猜你在找的Java相关文章