我遇到了 MDC 中缺少标头的问题,并且早期 cmets 中提供的解决方案不起作用。这是我的情况的一个有效解决方案:除了默认标头之外的所有标头都在线程之间丢失(MDC 是线程本地的)。由于 Camel MDCUnitOfWork 默认的有缺陷的实现,在另一个线程中传递给 MDC 的唯一标头是默认的 Camel 标头。
您必须将 MDCLogging 设置为 true 并实现您自己的 UnitOfWork,就像在之前的 cmets 中显示的那样:
camelContext.setUseMDCLogging(true);
camelContext.setUnitOfWorkFactory(CustomUnitOfWork::new);
CustomUnitOfWork 的实现要复杂得多,因为我们需要重写很多默认的 MDCUnitOfWork 行为(确保导入 org.slf4j.MDC):
class CustomUnitOfWork extends MDCUnitOfWork {
static final String CUSTOM_FIELD_NAME = "customField";
private String customField;
CustomUnitOfWork(Exchange exchange) {
super(exchange);
customField = (String) exchange.getIn().getHeader("customFieldPath123");
MDC.put(CUSTOM_FIELD_NAME, customField);
}
@Override
public UnitOfWork newInstance(Exchange exchange) {
return new CustomUnitOfWork(exchange);
}
@Override
public void clear() {
super.clear();
if (customField != null) {
MDC.put(CUSTOM_FIELD_NAME, customField);
} else {
MDC.remove(CUSTOM_FIELD_NAME);
}
}
@Override
public void stop() throws Exception {
super.stop();
clear();
}
@Override
public AsyncCallback beforeProcess(Processor processor, Exchange exchange, AsyncCallback callback) {
return new CustomMDCCallback(callback);
}
private class CustomMDCCallback implements AsyncCallback {
private final AsyncCallback delegate;
private final String breadcrumbId;
private final String exchangeId;
private final String messageId;
private final String correlationId;
private final String routeId;
private final String camelContextId;
private final String customField;
private CustomMDCCallback(AsyncCallback delegate) {
this.delegate = delegate;
this.exchangeId = MDC.get(MDC_EXCHANGE_ID);
this.messageId = MDC.get(MDC_MESSAGE_ID);
this.breadcrumbId = MDC.get(MDC_BREADCRUMB_ID);
this.correlationId = MDC.get(MDC_CORRELATION_ID);
this.camelContextId = MDC.get(MDC_CAMEL_CONTEXT_ID);
this.routeId = MDC.get(MDC_ROUTE_ID);
this.customField = MDC.get(CUSTOM_FIELD_NAME);
}
@Override
public void done(boolean doneSync) {
try {
if (!doneSync) {
checkAndPut(breadcrumbId, MDC_BREADCRUMB_ID);
checkAndPut(exchangeId, MDC_EXCHANGE_ID);
checkAndPut(messageId, MDC_MESSAGE_ID);
checkAndPut(correlationId, MDC_CORRELATION_ID);
checkAndPut(camelContextId, MDC_CAMEL_CONTEXT_ID);
checkAndPut(customField, CUSTOM_FIELD_NAME);
}
checkAndPut(routeId, MDC_ROUTE_ID);
} finally {
delegate.done(doneSync);
}
}
private void checkAndPut(String value, String fieldName) {
if (value != null) {
MDC.put(fieldName, value);
}
}
}
}
如果您查看 Camel MDCUnitOfWork 类,您会发现代码非常相似。