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

Camel日志的覆写或拦截实现方案咨询

为Apache Camel日志统一添加特定Header值的惯用实现方式

在Apache Camel环境中要让每条日志都带上x-correlation-id这类特定Header值,有几种成熟的惯用方案,根据你的场景可以灵活选择:

方案1:利用MDC(映射诊断上下文)全局注入(最推荐)

MDC是日志框架(Logback/Log4j)提供的线程绑定上下文机制,可以把关联ID这类上下文信息绑定到当前线程,所有日志输出都能自动读取并展示——不仅覆盖Camel的log() DSL和Log组件,连你自己写的业务日志也能生效。

实现步骤:

  1. 编写MDC处理器:把Exchange中的Header值放入MDC,并在Exchange完成后清理(避免线程复用导致脏数据)
public class CorrelationIdMdcProcessor implements Processor {
    @Override
    public void process(Exchange exchange) throws Exception {
        // 从Header中获取关联ID,没有则设为UNKNOWN
        String correlationId = exchange.getIn().getHeader("x-correlation-id", "UNKNOWN", String.class);
        MDC.put("x-correlation-id", correlationId);
        
        // 绑定清理逻辑到Exchange生命周期
        exchange.addOnCompletion(new SynchronizationAdapter() {
            @Override
            public void onComplete(Exchange exchange) {
                MDC.remove("x-correlation-id");
            }
        });
    }
}
  1. 全局或局部挂载处理器:

    • 全局生效:给所有路由添加这个处理器
      camelContext.addRoutePolicy(new RoutePolicy() {
          @Override
          public void onStart(Route route) {
              route.getRouteContext().getRoute().getInputs().add(0, new CorrelationIdMdcProcessor());
          }
      });
      
    • 局部生效:在单个路由开头添加
      from("direct:order-service")
          .process(new CorrelationIdMdcProcessor())
          .log("Processing order request")
          .to("jdbc:order-db");
      
  2. 修改日志框架配置:在Logback/Log4j的格式中加入MDC字段,比如Logback的logback.xml:

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %X{x-correlation-id} - %msg%n</pattern>
    </encoder>
</appender>

方案2:自定义LogFormatter扩展Camel Log组件

如果只想针对Camel的log() DSL和Log组件生效,可以自定义LogFormatter,覆盖默认的日志格式逻辑,直接把Header值嵌入日志内容。

实现步骤:

  1. 继承DefaultLogFormatter并扩展:
public class CorrelationIdLogFormatter extends DefaultLogFormatter {
    @Override
    public String format(Exchange exchange, String message) {
        String correlationId = exchange.getIn().getHeader("x-correlation-id", "UNKNOWN", String.class);
        // 在原日志内容前拼接关联ID
        return String.format("[%s] %s", correlationId, super.format(exchange, message));
    }
}
  1. 配置使用自定义Formatter:
    • 单个log DSL使用:
      from("direct:payment-service")
          .log(LoggingLevel.INFO, new CorrelationIdLogFormatter(), "Processing payment")
          .to("activemq:payment-queue");
      
    • 全局默认使用:让所有Log组件调用都用这个Formatter
      LogComponent logComponent = camelContext.getComponent("log", LogComponent.class);
      logComponent.setDefaultFormatter(new CorrelationIdLogFormatter());
      

方案3:使用Intercept策略全局拦截日志端点

通过Camel的interceptSendToEndpoint拦截所有发送到log:*端点的消息,修改日志内容后再转发,适合需要全局修改日志内容的场景。

实现示例:

// 拦截所有log组件的调用
interceptSendToEndpoint("log:*")
    .process(exchange -> {
        String correlationId = exchange.getIn().getHeader("x-correlation-id", "UNKNOWN", String.class);
        // 获取原日志消息并拼接关联ID
        String originalMsg = exchange.getProperty(LogComponent.LOG_MESSAGE, String.class);
        if (originalMsg != null) {
            exchange.setProperty(LogComponent.LOG_MESSAGE, String.format("[%s] %s", correlationId, originalMsg));
        }
    });

注意点:

这个方案需要注意Camel Log组件的消息存储位置(通过LogComponent.LOG_MESSAGE属性获取),如果是带参数的日志(比如.log("Order ID: ${header.orderId}")),需要确保参数解析后再处理。


内容的提问来源于stack exchange,提问作者Darius X.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:00:17