加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 不能将值放在MDC中

发布时间:2020-12-15 00:58:42 所属栏目:Java 来源:网络整理
导读:我试图在门票中的RequestCycle()的onBeginRequest()中记录几个值. 但是这些值没有被记录在调试文件中.我将值放在MDC中的RequestCycleListeners()中. 以下是代码: getRequestCycleListeners().add(new AbstractRequestCycleListener(){ public void onBeginR
我试图在门票中的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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读