You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Logstash/Gelf未存储全部MDC内容问题排查与解决咨询

问题分析与解决方案

核心问题1:日志生成时机与MDC字段设置时机不匹配

你的额外字段(结果、耗时等)是在ictx.proceed()执行完成后的finally块中才放入MDC的,但SoapLogHandler的日志是在ictx.proceed()内部输出的——此时这些字段还未被添加到MDC中,自然不会出现在日志里。

核心问题2:Logger配置范围覆盖不全

当前JsonLog handler仅绑定到org.somepackgs.SoapLogHandler这个Logger,拦截器GeneralInterceptor的日志没有关联该handler,所以拦截器的日志不会写入JSON文件;而如果只配置拦截器的Logger,SOAP日志又会丢失。


具体解决方案

1. 调整日志输出时机,确保MDC字段已存在

把需要包含完整MDC字段的日志输出逻辑移到拦截器的finally块中,此时所有业务结果、耗时等字段都已设置完成,日志会自动包含这些内容。如果需要保留SoapLogHandler的原有日志,可以在拦截器中补充一条汇总日志。

示例调整后的拦截器代码:

@AroundInvoke
public Object run(InvocationContext ictx) throws Exception {
    String requestId = UUID.randomUUID().toString();
    MDC.put("requestId", requestId);
    long startTime = System.currentTimeMillis();
    Object obj = null;
    String resultStatus = "SUCCESS";

    try{
        // 业务校验与执行
        obj = ictx.proceed();
    } catch (Exception ex) {
        resultStatus = "FAILED";
        throw ex; // 不要吞掉异常,保证业务异常流程正常执行
    } finally {
        // 计算耗时并写入MDC
        long elapsedTime = System.currentTimeMillis() - startTime;
        MDC.put("resultStatus", resultStatus);
        MDC.put("elapsedTimeMs", String.valueOf(elapsedTime));

        // 输出包含完整MDC字段的日志(可选择用SoapLogHandler或拦截器自己的Logger)
        LoggerFactory.getLogger(SoapLogHandler.class).info("Request processed - requestId: {}", requestId);
        // LoggerFactory.getLogger(GeneralInterceptor.class).info("Request completed");

        MDC.clear(); // 必须清理MDC,避免线程池复用导致的字段污染
    }
    return obj;
}

2. 配置Logger覆盖所有需要的日志来源

要同时记录SOAP日志和拦截器日志,需要让两个Logger都关联JsonLog handler,修改standalone.xml的日志配置:

<profile>
  <subsystem xmlns="urn:jboss:domain:logging:3.0">
    <!-- 保留原有的JsonLog handler和JsonFormatter配置 -->
    <periodic-rotating-file-handler name="JsonLog" autoflush="true">
      <!-- ... 原有配置 ... -->
    </periodic-rotating-file-handler>
    <!-- ... 其他handler ... -->

    <!-- 给SoapLogHandler添加JsonLog handler -->
    <logger category="org.somepackgs.SoapLogHandler" use-parent-handlers="true">
      <level name="INFO"/>
      <handlers>
        <handler name="JsonLog"/>
      </handlers>
    </logger>

    <!-- 给GeneralInterceptor添加JsonLog handler -->
    <logger category="org.somepackgs.GeneralInterceptor" use-parent-handlers="true">
      <level name="INFO"/>
      <handlers>
        <handler name="JsonLog"/>
      </handlers>
    </logger>

    <!-- 保留原有的JsonFormatter配置 -->
    <formatter name="JsonFormatter">
      <!-- ... 原有配置 ... -->
    </formatter>
  </subsystem>
</profile>

如果希望所有应用日志都写入JSON文件,可以简化配置,把JsonLog handler添加到ROOT logger:

<root-logger>
  <level name="INFO"/>
  <handlers>
    <handler name="JsonLog"/>
    <!-- 保留原有控制台/文件handler,避免丢失其他日志渠道 -->
    <handler name="CONSOLE"/>
    <handler name="FILE"/>
  </handlers>
</root-logger>

3. 确认JsonFormatter配置有效性

你的JsonFormatter已经开启了includeFullMdc="true"和mdcProfiling="true",这部分配置是正确的——只要日志生成时MDC中有对应的字段,就会自动被包含到JSON日志中。


内容的提问来源于stack exchange,提问作者Morteza Asadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:46:18