This is an automated email from the ASF dual-hosted git repository.

pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit b5f0dda145585d617da1b6ac90a922b1573f5087
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Thu Sep 25 14:44:57 2025 +0200

    feat(component): MDC docs
---
 .../main/camel-main-configuration-metadata.json    |  3 +
 .../org/apache/camel/catalog/others/mdc.json       |  2 +-
 components/camel-mdc/pom.xml                       |  2 +-
 .../services/org/apache/camel/other.properties     |  2 +-
 .../camel-mdc/src/generated/resources/mdc.json     |  2 +-
 components/camel-mdc/src/main/docs/mdc.adoc        | 59 ++++++++++++-
 .../camel/mdc/MDCProcessorsInterceptStrategy.java  | 63 ++++++++++----
 .../main/java/org/apache/camel/mdc/MDCService.java |  3 +
 .../java/org/apache/camel/mdc/MDCAsyncTest.java    | 93 ++++++++------------
 ...{MDCAsyncTest.java => MDCAsyncWiretapTest.java} | 22 +++--
 .../org/apache/camel/mdc/MyAsyncComponent.java     | 46 ++++++++++
 .../java/org/apache/camel/mdc/MyAsyncEndpoint.java | 98 ++++++++++++++++++++++
 .../java/org/apache/camel/mdc/MyAsyncProducer.java | 75 +++++++++++++++++
 .../camel-mdc/src/test/resources/log4j2.properties |  4 +-
 .../main/MdcConfigurationPropertiesConfigurer.java | 32 ++++++-
 .../camel-main-configuration-metadata.json         |  3 +
 core/camel-main/src/main/docs/main.adoc            |  5 +-
 .../org/apache/camel/main/BaseMainSupport.java     |  2 +-
 .../camel/main/MdcConfigurationProperties.java     | 51 ++++++++++-
 proposals/mdc.adoc                                 |  8 +-
 .../maven/packaging/PrepareCamelMainMojo.java      |  2 +
 21 files changed, 472 insertions(+), 105 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index 6dbbe63d36a..fae5155bcac 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -217,6 +217,9 @@
     { "name": "camel.management.uploadEnabled", "required": false, 
"description": "Whether to enable file upload via HTTP (not intended for 
production use). This functionality is for development to be able to reload 
Camel routes and code with source changes (if reload is enabled). If enabled 
then you can upload\/delete files via HTTP PUT\/DELETE on context-path: 
\/q\/upload\/{name}. You must also configure the uploadSourceDir option.", 
"sourceType": "org.apache.camel.main.HttpManagementS [...]
     { "name": "camel.management.uploadSourceDir", "required": false, 
"description": "Source directory when upload is enabled.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "secret": false },
     { "name": "camel.management.useGlobalSslContextParameters", "required": 
false, "description": "Whether to use global SSL configuration for securing the 
embedded HTTP server.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"boolean", "javaType": "boolean", "defaultValue": false, "secret": false },
+    { "name": "camel.mdc.customExchangeHeaders", "required": false, 
"description": "Provide the headers you would like to use in the logging. Use 
&#42; value to include all available headers", "sourceType": 
"org.apache.camel.main.MdcConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "secret": false },
+    { "name": "camel.mdc.customExchangeProperties", "required": false, 
"description": "Provide the properties you would like to use in the logging. 
Use &#42; value to include all available properties", "sourceType": 
"org.apache.camel.main.MdcConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "secret": false },
+    { "name": "camel.mdc.enabled", "required": false, "description": "To 
enable MDC service", "sourceType": 
"org.apache.camel.main.MdcConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": false, "secret": false },
     { "name": "camel.metrics.baseEndpointURIExchangeEventNotifier", 
"required": false, "description": "Whether to use static or dynamic values for 
Endpoint Name tags in captured metrics. By default, static values are used. 
When using dynamic tags, then a dynamic to (toD) can compute many different 
endpoint URIs that, can lead to many tags as the URI is dynamic, so use this 
with care if setting this option to false.", "sourceType": 
"org.apache.camel.main.MetricsConfigurationProperties", " [...]
     { "name": "camel.metrics.binders", "required": false, "description": 
"Additional Micrometer binders to include such as jvm-memory, processor, 
jvm-thread, and so forth. Multiple binders can be separated by comma. The 
following binders currently is available from Micrometer: class-loader, 
commons-object-pool2, file-descriptor, hystrix-metrics-binder, jvm-compilation, 
jvm-gc, jvm-heap-pressure, jvm-info, jvm-memory, jvm-thread, log4j2, logback, 
processor, uptime", "sourceType": "org.apa [...]
     { "name": "camel.metrics.clearOnReload", "required": false, "description": 
"Clear the captured metrics data when Camel is reloading routes such as when 
using Camel JBang.", "sourceType": 
"org.apache.camel.main.MetricsConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": true, "secret": false },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/mdc.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/mdc.json
index 073d9a5633d..47ba69df888 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/mdc.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/mdc.json
@@ -3,7 +3,7 @@
     "kind": "other",
     "name": "mdc",
     "title": "Mdc",
-    "description": "Mapped Diagnostic Context component",
+    "description": "Logging MDC (Mapped Diagnostic Context) Service",
     "deprecated": false,
     "firstVersion": "4.15.0",
     "label": "logging",
diff --git a/components/camel-mdc/pom.xml b/components/camel-mdc/pom.xml
index 978c9d6892c..602ee335ab8 100644
--- a/components/camel-mdc/pom.xml
+++ b/components/camel-mdc/pom.xml
@@ -36,7 +36,7 @@
   <artifactId>camel-mdc</artifactId>
   <packaging>jar</packaging>
   <name>Camel :: MDC</name>
-  <description>Mapped Diagnostic Context component</description>
+  <description>Logging MDC (Mapped Diagnostic Context) Service</description>
 
   <dependencies>
     <dependency>
diff --git 
a/components/camel-mdc/src/generated/resources/META-INF/services/org/apache/camel/other.properties
 
b/components/camel-mdc/src/generated/resources/META-INF/services/org/apache/camel/other.properties
index 2f66413827f..7862c26646d 100644
--- 
a/components/camel-mdc/src/generated/resources/META-INF/services/org/apache/camel/other.properties
+++ 
b/components/camel-mdc/src/generated/resources/META-INF/services/org/apache/camel/other.properties
@@ -4,4 +4,4 @@ groupId=org.apache.camel
 artifactId=camel-mdc
 version=4.15.0-SNAPSHOT
 projectName=Camel :: MDC
-projectDescription=Mapped Diagnostic Context component
+projectDescription=Logging MDC (Mapped Diagnostic Context) Service
diff --git a/components/camel-mdc/src/generated/resources/mdc.json 
b/components/camel-mdc/src/generated/resources/mdc.json
index 073d9a5633d..47ba69df888 100644
--- a/components/camel-mdc/src/generated/resources/mdc.json
+++ b/components/camel-mdc/src/generated/resources/mdc.json
@@ -3,7 +3,7 @@
     "kind": "other",
     "name": "mdc",
     "title": "Mdc",
-    "description": "Mapped Diagnostic Context component",
+    "description": "Logging MDC (Mapped Diagnostic Context) Service",
     "deprecated": false,
     "firstVersion": "4.15.0",
     "label": "logging",
diff --git a/components/camel-mdc/src/main/docs/mdc.adoc 
b/components/camel-mdc/src/main/docs/mdc.adoc
index 03ccd90ea33..b61f2af086c 100644
--- a/components/camel-mdc/src/main/docs/mdc.adoc
+++ b/components/camel-mdc/src/main/docs/mdc.adoc
@@ -2,9 +2,66 @@
 :doctitle: Mdc
 :shortname: mdc
 :artifactid: camel-mdc
-:description: Mapped Diagnostic Context component
+:description: Logging MDC (Mapped Diagnostic Context) Service
 :since: 4.15
 :supportlevel: Preview
 :tabs-sync-option:
 
 *Since Camel {since}*
+
+This component is in charge to provide the configuration required to work with 
Mapped Diagnostic Context (MDC), a specification adopted by the major logging 
providers to add diagnostic information in the logging traces. Camel uses the 
API exposed by https://www.slf4j.org/manual.html#mdc[SLF4J logging facade]. The 
concrete implementation will depend on the logging system adopted.
+
+When you enable the MDC Service provided in this component, you will instruct 
your application to automatically store certain Camel Headers into the MDC 
storage. You can additionally provide more headers and properties through the 
component configuration. The MDC is normally sharing the storage per each 
thread. Given the multi threading nature of Camel, the component deals with the 
multithreading setting the information into the context and cleaning them once 
they have been used (general [...]
+
+== Usage
+
+If you want to use the feature, you need to include the `camel-mdc` dependency 
in your `pom.xml` and configure it with the parameters in the 
`application.properties` configuration file (at least set 
`camel.mdc.enabled=true`).
+
+The goal of this component is to avoid to work on low level API in Java. In 
older MDC implementations you had to hack into the code to include MDC such as:
+
+```java
+    org.slf4j.MDC.put("myCustomMDCKey", "myCustomKeyValue");
+```
+
+And later you had to make sure to provide MDC context propagation in async 
components (eg, `wiretap`) in order to make sure to have such context available 
in the new executing async thread. With this new service, the only thing to do 
is to add the value as a Camel Exchange header (or a property), for example:
+
+```java
+    .setHeader("myCustomMDCKey", simple("myCustomKeyValue"))
+```
+include the MDC service and additionally instruct the Camel application to 
treat that header as a MDC trace (via `camel.mdc.customHeaders=myCustomMDCKey` 
or `*` to include all headers). You won't need any longer to worry about 
context propagation as the propagation will be done via Camel Exchange instead.
+
+NOTE: you won't also need any longer to hack the code using Java DSL, as you 
can put headers in any Camel DSL.
+
+Depending on the logging technology used, you can now include the MDC 
parameters you want to trace in your logging configuration. For example, in 
`log4j2` configuration you can include them as shown below:
+
+```
+... [%X{camel.contextId}, %X{camel.routeId}, %X{camel.exchangeId}, 
%X{camel.messageId}, %X{customHead}, %X{customProp}]
+```
+
+During the execution you can verify the output of the log to see the traces 
appended to your logger.
+
+== Default headers
+
+This is the list of default MDC values included in each execution:
+
+* camel.breadcrumbId
+* camel.exchangeId
+* camel.messageId
+* camel.correlationId
+* camel.routeId
+* camel.contextId
+* camel.threadId
+
+If they exists in the Exchange, then, they will be included in the MDC. You 
can use `camel.mdc.customHeaders` and `camel.mdc.customProperties` to include 
any further header and property you need to trace.
+
+== Configuration
+
+The configuration properties for the MDC component are:
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|=======================================================================
+|Option |Default |Description
+|`camel.mdc.enabled`| false | Enable the MDC logging.
+|`camel.mdc.customHeaders` |  | Provide the headers you would like to use in 
the logging. Use `*` value to include all available headers.
+|`camel.mdc.customProperties` |  | Provide the properties you would like to 
use in the logging. Use `*` value to include all available properties.
+|=======================================================================
diff --git 
a/components/camel-mdc/src/main/java/org/apache/camel/mdc/MDCProcessorsInterceptStrategy.java
 
b/components/camel-mdc/src/main/java/org/apache/camel/mdc/MDCProcessorsInterceptStrategy.java
index 3306a40e90d..02c755f8401 100644
--- 
a/components/camel-mdc/src/main/java/org/apache/camel/mdc/MDCProcessorsInterceptStrategy.java
+++ 
b/components/camel-mdc/src/main/java/org/apache/camel/mdc/MDCProcessorsInterceptStrategy.java
@@ -16,12 +16,16 @@
  */
 package org.apache.camel.mdc;
 
+import java.util.concurrent.CompletableFuture;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.AsyncProcessor;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.NamedNode;
 import org.apache.camel.Processor;
 import org.apache.camel.spi.InterceptStrategy;
-import org.apache.camel.support.processor.DelegateAsyncProcessor;
+import org.apache.camel.support.AsyncProcessorConverterHelper;
 
 /**
  * MDCProcessorsInterceptStrategy is used to wrap each processor calls and 
generate the MDC context for each process
@@ -37,28 +41,51 @@ public class MDCProcessorsInterceptStrategy implements 
InterceptStrategy {
 
     @Override
     public Processor wrapProcessorInInterceptors(
-            CamelContext camelContext,
-            NamedNode processorDefinition, Processor target, Processor 
nextTarget)
+            final CamelContext context,
+            final NamedNode definition,
+            final Processor target,
+            final Processor nextTarget)
             throws Exception {
-        return new DelegateAsyncProcessor(new TraceProcessor(target));
-    }
 
-    private class TraceProcessor implements Processor {
-        private final Processor target;
+        final AsyncProcessor asyncProcessor = 
AsyncProcessorConverterHelper.convert(target);
+
+        return new AsyncProcessor() {
+
+            @Override
+            public boolean process(Exchange exchange, AsyncCallback callback) {
+                mdcService.setMDC(exchange);
+                return asyncProcessor.process(exchange, doneSync -> {
+                    mdcService.unsetMDC();
+                    callback.done(doneSync);
+                });
+            }
+
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                mdcService.setMDC(exchange);
+                try {
+                    asyncProcessor.process(exchange);
+                } finally {
+                    mdcService.unsetMDC();
+                }
+            }
 
-        public TraceProcessor(Processor target) {
-            this.target = target;
-        }
+            @Override
+            public CompletableFuture<Exchange> processAsync(Exchange exchange) 
{
+                CompletableFuture<Exchange> future = new CompletableFuture<>();
+                mdcService.setMDC(exchange);
+                asyncProcessor.process(exchange, doneSync -> {
+                    if (exchange.getException() != null) {
+                        future.completeExceptionally(exchange.getException());
+                    } else {
+                        future.complete(exchange);
+                    }
+                    mdcService.unsetMDC();
+                });
 
-        @Override
-        public void process(Exchange exchange) throws Exception {
-            mdcService.setMDC(exchange);
-            try {
-                target.process(exchange);
-            } finally {
-                mdcService.unsetMDC();
+                return future;
             }
-        }
+        };
     }
 
 }
diff --git 
a/components/camel-mdc/src/main/java/org/apache/camel/mdc/MDCService.java 
b/components/camel-mdc/src/main/java/org/apache/camel/mdc/MDCService.java
index 5ac3a429881..47191e79586 100644
--- a/components/camel-mdc/src/main/java/org/apache/camel/mdc/MDCService.java
+++ b/components/camel-mdc/src/main/java/org/apache/camel/mdc/MDCService.java
@@ -39,6 +39,7 @@ public class MDCService extends ServiceSupport implements 
CamelMDCService {
     static String MDC_MESSAGE_ID = "camel.messageId";
     static String MDC_CORRELATION_ID = "camel.correlationId";
     static String MDC_ROUTE_ID = "camel.routeId";
+    static String MDC_CAMEL_THREAD_ID = "camel.threadId";
     static String MDC_CAMEL_CONTEXT_ID = "camel.contextId";
 
     private static final Logger LOG = 
LoggerFactory.getLogger(MDCService.class);
@@ -149,6 +150,8 @@ public class MDCService extends ServiceSupport implements 
CamelMDCService {
         MDC.put(MDC_EXCHANGE_ID, exchange.getExchangeId());
         MDC.put(MDC_MESSAGE_ID, exchange.getMessage().getMessageId());
         MDC.put(MDC_CAMEL_CONTEXT_ID, exchange.getContext().getName());
+        // Useful to make sure aync execution is properly propagating context
+        MDC.put(MDC_CAMEL_THREAD_ID, Thread.currentThread().getName());
         // Backward compatibility: this info may not be longer widely used
         String corrId = 
exchange.getProperty(ExchangePropertyKey.CORRELATION_ID, String.class);
         if (corrId != null) {
diff --git 
a/components/camel-mdc/src/test/java/org/apache/camel/mdc/MDCAsyncTest.java 
b/components/camel-mdc/src/test/java/org/apache/camel/mdc/MDCAsyncTest.java
index 7a5c2284a1d..5b94104bf3f 100644
--- a/components/camel-mdc/src/test/java/org/apache/camel/mdc/MDCAsyncTest.java
+++ b/components/camel-mdc/src/test/java/org/apache/camel/mdc/MDCAsyncTest.java
@@ -16,28 +16,21 @@
  */
 package org.apache.camel.mdc;
 
-import java.io.IOException;
-
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
-import org.apache.camel.RoutesBuilder;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.test.junit5.ExchangeTestSupport;
 import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.slf4j.MDC;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 
 public class MDCAsyncTest extends ExchangeTestSupport {
 
-    private static final Logger LOG = 
LoggerFactory.getLogger(MDCAsyncTest.class);
-
     @Override
     protected CamelContext createCamelContext() throws Exception {
         MDCService mdcSvc = new MDCService();
@@ -50,69 +43,49 @@ public class MDCAsyncTest extends ExchangeTestSupport {
     }
 
     @Test
-    void testRouteSingleRequest() throws IOException, InterruptedException {
-        MockEndpoint mock = getMockEndpoint("mock:end");
-        mock.expectedMessageCount(1);
-        mock.setAssertPeriod(5000);
-        context.createProducerTemplate().sendBody("direct:start", null);
-        mock.assertIsSatisfied(1000);
-        // We should get no MDC after the route has been executed
-        assertEquals(0, MDC.getCopyOfContextMap().size());
+    public void testAsyncEndpoint() throws Exception {
+        getMockEndpoint("mock:before").expectedBodiesReceived("Hello Camel");
+        getMockEndpoint("mock:after").expectedBodiesReceived("Bye Camel");
+        getMockEndpoint("mock:result").expectedBodiesReceived("Bye Camel");
+
+        String reply = template.requestBody("direct:start", "Hello Camel", 
String.class);
+        assertEquals("Bye Camel", reply);
     }
 
     @Override
-    protected RoutesBuilder createRouteBuilder() {
+    protected RouteBuilder createRouteBuilder() {
         return new RouteBuilder() {
             @Override
             public void configure() {
-                from("direct:start")
-                        .setBody()
-                        .simple("start")
-                        .log("start: ${exchangeId}")
-                        .to("direct:a")
-                        .wireTap("direct:b");
+                context.addComponent("async", new MyAsyncComponent());
 
-                from("direct:a")
+                from("direct:start").to("mock:before").to("log:before")
                         .setProperty("prop1", simple("Property1"))
                         .setHeader("head", simple("Header1"))
-                        .process(exchange -> {
-                            LOG.info("Direct:a process");
-                            assertNotNull(MDC.get(MDCService.MDC_MESSAGE_ID));
-                            assertNotNull(MDC.get(MDCService.MDC_EXCHANGE_ID));
-                            assertNotNull(MDC.get(MDCService.MDC_ROUTE_ID));
-                            
assertNotNull(MDC.get(MDCService.MDC_CAMEL_CONTEXT_ID));
-                            assertEquals("Header1", MDC.get("head"));
-                            assertEquals("Property1", MDC.get("prop1"));
-                            assertNull(MDC.get("prop2"));
-                            // We store the exchange of this execution in a 
property
-                            // as we will use this property to evaluate the 
exchange in the direct:b execution
-                            exchange.setProperty("directa-exchange", 
exchange.getExchangeId());
-                        })
-                        .setBody()
-                        .simple("Direct a")
-                        .log("directa: ${exchangeId}");
+                        .process(new Processor() {
+                            public void process(Exchange exchange) {
+                                assertEquals("Header1", MDC.get("head"));
+                                assertEquals("Property1", MDC.get("prop1"));
+                                assertNull(MDC.get("prop2"));
+                                // We store the threadId of this execution in 
a property
+                                // as we will use it to assert the thread is 
different in the direct:b execution
+                                exchange.setProperty("thread-a", 
MDC.get(MDCService.MDC_CAMEL_THREAD_ID));
+                            }
+                        }).recipientList(constant("direct:foo"));
 
-                from("direct:b")
+                from("direct:foo").to("async:bye:camel")
                         .setProperty("prop2", simple("Property2"))
                         .setHeader("head", simple("Header2"))
-                        .process(exchange -> {
-                            LOG.info("Direct:b process");
-                            assertNotNull(MDC.get(MDCService.MDC_MESSAGE_ID));
-                            assertNotNull(MDC.get(MDCService.MDC_EXCHANGE_ID));
-                            assertNotNull(MDC.get(MDCService.MDC_ROUTE_ID));
-                            
assertNotNull(MDC.get(MDCService.MDC_CAMEL_CONTEXT_ID));
-                            assertEquals("Header2", MDC.get("head"));
-                            // NOTE: properties are shared
-                            assertEquals("Property1", MDC.get("prop1"));
-                            assertEquals("Property2", MDC.get("prop2"));
-                            // We use as support storage the same properties
-                            
assertNotEquals(exchange.getProperty("directa-exchange"), 
MDC.get(MDCService.MDC_EXCHANGE_ID));
-                        })
-                        .delay(2000)
-                        .setBody()
-                        .simple("Direct b")
-                        .log("directb: ${exchangeId}")
-                        .to("mock:end");
+                        .process(new Processor() {
+                            public void process(Exchange exchange) {
+                                // Make sure this execution is spanned in a 
different thread
+                                // but still the context (in this case the 
properties) is propagated
+                                
assertNotEquals(exchange.getProperty("thread-a"), 
MDC.get(MDCService.MDC_CAMEL_THREAD_ID));
+                                assertEquals("Header2", MDC.get("head"));
+                                assertEquals("Property1", MDC.get("prop1"));
+                                assertEquals("Property2", MDC.get("prop2"));
+                            }
+                        }).to("log:after").to("mock:after").to("mock:result");
             }
         };
     }
diff --git 
a/components/camel-mdc/src/test/java/org/apache/camel/mdc/MDCAsyncTest.java 
b/components/camel-mdc/src/test/java/org/apache/camel/mdc/MDCAsyncWiretapTest.java
similarity index 85%
copy from 
components/camel-mdc/src/test/java/org/apache/camel/mdc/MDCAsyncTest.java
copy to 
components/camel-mdc/src/test/java/org/apache/camel/mdc/MDCAsyncWiretapTest.java
index 7a5c2284a1d..f549a830dd9 100644
--- a/components/camel-mdc/src/test/java/org/apache/camel/mdc/MDCAsyncTest.java
+++ 
b/components/camel-mdc/src/test/java/org/apache/camel/mdc/MDCAsyncWiretapTest.java
@@ -34,9 +34,9 @@ import static 
org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 
-public class MDCAsyncTest extends ExchangeTestSupport {
+public class MDCAsyncWiretapTest extends ExchangeTestSupport {
 
-    private static final Logger LOG = 
LoggerFactory.getLogger(MDCAsyncTest.class);
+    private static final Logger LOG = 
LoggerFactory.getLogger(MDCAsyncWiretapTest.class);
 
     @Override
     protected CamelContext createCamelContext() throws Exception {
@@ -70,6 +70,7 @@ public class MDCAsyncTest extends ExchangeTestSupport {
                         .simple("start")
                         .log("start: ${exchangeId}")
                         .to("direct:a")
+                        // MUST be any async component
                         .wireTap("direct:b");
 
                 from("direct:a")
@@ -81,12 +82,13 @@ public class MDCAsyncTest extends ExchangeTestSupport {
                             assertNotNull(MDC.get(MDCService.MDC_EXCHANGE_ID));
                             assertNotNull(MDC.get(MDCService.MDC_ROUTE_ID));
                             
assertNotNull(MDC.get(MDCService.MDC_CAMEL_CONTEXT_ID));
+                            
assertNotNull(MDC.get(MDCService.MDC_CAMEL_THREAD_ID));
                             assertEquals("Header1", MDC.get("head"));
                             assertEquals("Property1", MDC.get("prop1"));
                             assertNull(MDC.get("prop2"));
-                            // We store the exchange of this execution in a 
property
-                            // as we will use this property to evaluate the 
exchange in the direct:b execution
-                            exchange.setProperty("directa-exchange", 
exchange.getExchangeId());
+                            // We store the threadId of this execution in a 
property
+                            // as we will use it to assert the thread is 
different in the direct:b execution
+                            exchange.setProperty("thread-a", 
MDC.get(MDCService.MDC_CAMEL_THREAD_ID));
                         })
                         .setBody()
                         .simple("Direct a")
@@ -97,16 +99,12 @@ public class MDCAsyncTest extends ExchangeTestSupport {
                         .setHeader("head", simple("Header2"))
                         .process(exchange -> {
                             LOG.info("Direct:b process");
-                            assertNotNull(MDC.get(MDCService.MDC_MESSAGE_ID));
-                            assertNotNull(MDC.get(MDCService.MDC_EXCHANGE_ID));
-                            assertNotNull(MDC.get(MDCService.MDC_ROUTE_ID));
-                            
assertNotNull(MDC.get(MDCService.MDC_CAMEL_CONTEXT_ID));
+                            // Make sure this execution is spanned in a 
different thread
+                            // but still the context (in this case the 
properties) is propagated
+                            assertNotEquals(exchange.getProperty("thread-a"), 
MDC.get(MDCService.MDC_CAMEL_THREAD_ID));
                             assertEquals("Header2", MDC.get("head"));
-                            // NOTE: properties are shared
                             assertEquals("Property1", MDC.get("prop1"));
                             assertEquals("Property2", MDC.get("prop2"));
-                            // We use as support storage the same properties
-                            
assertNotEquals(exchange.getProperty("directa-exchange"), 
MDC.get(MDCService.MDC_EXCHANGE_ID));
                         })
                         .delay(2000)
                         .setBody()
diff --git 
a/components/camel-mdc/src/test/java/org/apache/camel/mdc/MyAsyncComponent.java 
b/components/camel-mdc/src/test/java/org/apache/camel/mdc/MyAsyncComponent.java
new file mode 100644
index 00000000000..141a3041a0c
--- /dev/null
+++ 
b/components/camel-mdc/src/test/java/org/apache/camel/mdc/MyAsyncComponent.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.mdc;
+
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.support.DefaultComponent;
+import org.apache.camel.util.StringHelper;
+
+public class MyAsyncComponent extends DefaultComponent {
+
+    @Override
+    protected Endpoint createEndpoint(String uri, String remaining, 
Map<String, Object> parameters) throws Exception {
+        MyAsyncEndpoint answer = new MyAsyncEndpoint(uri, this);
+        answer.setReply(prepareReply(remaining));
+        setProperties(answer, parameters);
+        return answer;
+    }
+
+    private String prepareReply(String value) {
+        // to make URIs valid we make the conventions of using ':' for ' ' and
+        // capitalize words
+        String[] words = value.split(":");
+        StringBuilder result = new StringBuilder();
+        for (String word : words) {
+            result.append(result.isEmpty() ? "" : " ");
+            result.append(StringHelper.capitalize(word));
+        }
+        return result.toString();
+    }
+}
diff --git 
a/components/camel-mdc/src/test/java/org/apache/camel/mdc/MyAsyncEndpoint.java 
b/components/camel-mdc/src/test/java/org/apache/camel/mdc/MyAsyncEndpoint.java
new file mode 100644
index 00000000000..71f0474e112
--- /dev/null
+++ 
b/components/camel-mdc/src/test/java/org/apache/camel/mdc/MyAsyncEndpoint.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.mdc;
+
+import org.apache.camel.Component;
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.support.DefaultEndpoint;
+import org.apache.camel.support.SynchronousDelegateProducer;
+
+public class MyAsyncEndpoint extends DefaultEndpoint {
+
+    private boolean append;
+    private String reply;
+    private long delay = 25;
+    private int failFirstAttempts;
+    private boolean synchronous;
+
+    public MyAsyncEndpoint(String endpointUri, Component component) {
+        super(endpointUri, component);
+    }
+
+    @Override
+    public Producer createProducer() {
+        Producer answer = new MyAsyncProducer(this);
+        if (isSynchronous()) {
+            // force it to be synchronously
+            return new SynchronousDelegateProducer(answer);
+        } else {
+            return answer;
+        }
+    }
+
+    @Override
+    public Consumer createConsumer(Processor processor) {
+        throw new UnsupportedOperationException("Consumer not supported");
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return true;
+    }
+
+    public boolean isSynchronous() {
+        return synchronous;
+    }
+
+    public void setSynchronous(boolean synchronous) {
+        this.synchronous = synchronous;
+    }
+
+    public String getReply() {
+        return reply;
+    }
+
+    public void setReply(String reply) {
+        this.reply = reply;
+    }
+
+    public long getDelay() {
+        return delay;
+    }
+
+    public void setDelay(long delay) {
+        this.delay = delay;
+    }
+
+    public int getFailFirstAttempts() {
+        return failFirstAttempts;
+    }
+
+    public void setFailFirstAttempts(int failFirstAttempts) {
+        this.failFirstAttempts = failFirstAttempts;
+    }
+
+    public boolean isAppend() {
+        return append;
+    }
+
+    public void setAppend(boolean append) {
+        this.append = append;
+    }
+}
diff --git 
a/components/camel-mdc/src/test/java/org/apache/camel/mdc/MyAsyncProducer.java 
b/components/camel-mdc/src/test/java/org/apache/camel/mdc/MyAsyncProducer.java
new file mode 100644
index 00000000000..4e99a798a4c
--- /dev/null
+++ 
b/components/camel-mdc/src/test/java/org/apache/camel/mdc/MyAsyncProducer.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.mdc;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.CamelExchangeException;
+import org.apache.camel.Exchange;
+import org.apache.camel.support.DefaultAsyncProducer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MyAsyncProducer extends DefaultAsyncProducer {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(MyAsyncProducer.class);
+    private final ExecutorService executor;
+    private final AtomicInteger counter = new AtomicInteger();
+
+    public MyAsyncProducer(MyAsyncEndpoint endpoint) {
+        super(endpoint);
+        this.executor = 
endpoint.getCamelContext().getExecutorServiceManager().newDefaultThreadPool(this,
 "MyProducer");
+    }
+
+    @Override
+    public MyAsyncEndpoint getEndpoint() {
+        return (MyAsyncEndpoint) super.getEndpoint();
+    }
+
+    @Override
+    public boolean process(final Exchange exchange, final AsyncCallback 
callback) {
+        executor.submit(new Callable<Object>() {
+            public Object call() throws Exception {
+                LOG.info("Simulating a task which takes {} millis to reply", 
getEndpoint().getDelay());
+                Thread.sleep(getEndpoint().getDelay());
+
+                int count = counter.incrementAndGet();
+                if (getEndpoint().getFailFirstAttempts() >= count) {
+                    LOG.info("Simulating a failure at attempt {}", count);
+                    exchange.setException(new 
CamelExchangeException("Simulated error at attempt " + count, exchange));
+                } else {
+                    String reply = getEndpoint().getReply();
+                    reply = getEndpoint().isAppend() ? 
exchange.getIn().getBody() + " " + reply : reply;
+                    exchange.getMessage().setBody(reply);
+                    LOG.info("Setting reply {}", reply);
+                }
+
+                LOG.info("Callback done(false)");
+                callback.done(false);
+                return null;
+            }
+        });
+
+        // indicate from this point forward its being routed asynchronously
+        LOG.info("Task submitted, now tell Camel routing engine to that this 
Exchange is being continued asynchronously");
+        return false;
+    }
+
+}
diff --git a/components/camel-mdc/src/test/resources/log4j2.properties 
b/components/camel-mdc/src/test/resources/log4j2.properties
index 590933e3e26..731b4840a10 100644
--- a/components/camel-mdc/src/test/resources/log4j2.properties
+++ b/components/camel-mdc/src/test/resources/log4j2.properties
@@ -17,14 +17,14 @@
 appender.console.type = Console
 appender.console.name = console
 appender.console.layout.type = PatternLayout
-appender.console.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m 
[%X{camel.contextId}, %X{camel.routeId}, %X{camel.exchangeId}, 
%X{camel.messageId}, %X{head1}, %X{prop1}, %X{head2}, %X{prop2}]%n
+appender.console.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m 
[%X{camel.threadId}, %X{camel.contextId}, %X{camel.routeId}, 
%X{camel.exchangeId}, %X{camel.messageId}, %X{head1}, %X{prop1}, %X{head2}, 
%X{prop2}]%n
 
 appender.file.type = File
 appender.file.name = file
 appender.file.fileName = target/camel-mdc-test.log
 appender.file.append = true
 appender.file.layout.type = PatternLayout
-appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m 
[%X{camel.contextId}, %X{camel.routeId}, %X{camel.exchangeId}, 
%X{camel.messageId}, %X{head1}, %X{prop1}, %X{head2}, %X{prop2}]%n
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m 
[%X{camel.threadId}, %X{camel.contextId}, %X{camel.routeId}, 
%X{camel.exchangeId}, %X{camel.messageId}, %X{head1}, %X{prop1}, %X{head2}, 
%X{prop2}]%n
 
 rootLogger.level = INFO
 rootLogger.appenderRef.file.ref = file
diff --git 
a/core/camel-main/src/generated/java/org/apache/camel/main/MdcConfigurationPropertiesConfigurer.java
 
b/core/camel-main/src/generated/java/org/apache/camel/main/MdcConfigurationPropertiesConfigurer.java
index 9707c284526..abc3e624f75 100644
--- 
a/core/camel-main/src/generated/java/org/apache/camel/main/MdcConfigurationPropertiesConfigurer.java
+++ 
b/core/camel-main/src/generated/java/org/apache/camel/main/MdcConfigurationPropertiesConfigurer.java
@@ -22,12 +22,23 @@ public class MdcConfigurationPropertiesConfigurer extends 
org.apache.camel.suppo
     private static final Map<String, Object> ALL_OPTIONS;
     static {
         Map<String, Object> map = new CaseInsensitiveMap();
+        map.put("CustomExchangeHeaders", java.lang.String.class);
+        map.put("CustomExchangeProperties", java.lang.String.class);
+        map.put("Enabled", boolean.class);
         ALL_OPTIONS = map;
     }
 
     @Override
     public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
-        return false;
+        org.apache.camel.main.MdcConfigurationProperties target = 
(org.apache.camel.main.MdcConfigurationProperties) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "customexchangeheaders":
+        case "customExchangeHeaders": 
target.setCustomExchangeHeaders(property(camelContext, java.lang.String.class, 
value)); return true;
+        case "customexchangeproperties":
+        case "customExchangeProperties": 
target.setCustomExchangeProperties(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "enabled": target.setEnabled(property(camelContext, 
boolean.class, value)); return true;
+        default: return false;
+        }
     }
 
     @Override
@@ -37,12 +48,27 @@ public class MdcConfigurationPropertiesConfigurer extends 
org.apache.camel.suppo
 
     @Override
     public Class<?> getOptionType(String name, boolean ignoreCase) {
-        return null;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "customexchangeheaders":
+        case "customExchangeHeaders": return java.lang.String.class;
+        case "customexchangeproperties":
+        case "customExchangeProperties": return java.lang.String.class;
+        case "enabled": return boolean.class;
+        default: return null;
+        }
     }
 
     @Override
     public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
-        return null;
+        org.apache.camel.main.MdcConfigurationProperties target = 
(org.apache.camel.main.MdcConfigurationProperties) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "customexchangeheaders":
+        case "customExchangeHeaders": return target.getCustomExchangeHeaders();
+        case "customexchangeproperties":
+        case "customExchangeProperties": return 
target.getCustomExchangeProperties();
+        case "enabled": return target.isEnabled();
+        default: return null;
+        }
     }
 }
 
diff --git 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index 6dbbe63d36a..fae5155bcac 100644
--- 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -217,6 +217,9 @@
     { "name": "camel.management.uploadEnabled", "required": false, 
"description": "Whether to enable file upload via HTTP (not intended for 
production use). This functionality is for development to be able to reload 
Camel routes and code with source changes (if reload is enabled). If enabled 
then you can upload\/delete files via HTTP PUT\/DELETE on context-path: 
\/q\/upload\/{name}. You must also configure the uploadSourceDir option.", 
"sourceType": "org.apache.camel.main.HttpManagementS [...]
     { "name": "camel.management.uploadSourceDir", "required": false, 
"description": "Source directory when upload is enabled.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "secret": false },
     { "name": "camel.management.useGlobalSslContextParameters", "required": 
false, "description": "Whether to use global SSL configuration for securing the 
embedded HTTP server.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"boolean", "javaType": "boolean", "defaultValue": false, "secret": false },
+    { "name": "camel.mdc.customExchangeHeaders", "required": false, 
"description": "Provide the headers you would like to use in the logging. Use 
&#42; value to include all available headers", "sourceType": 
"org.apache.camel.main.MdcConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "secret": false },
+    { "name": "camel.mdc.customExchangeProperties", "required": false, 
"description": "Provide the properties you would like to use in the logging. 
Use &#42; value to include all available properties", "sourceType": 
"org.apache.camel.main.MdcConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "secret": false },
+    { "name": "camel.mdc.enabled", "required": false, "description": "To 
enable MDC service", "sourceType": 
"org.apache.camel.main.MdcConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": false, "secret": false },
     { "name": "camel.metrics.baseEndpointURIExchangeEventNotifier", 
"required": false, "description": "Whether to use static or dynamic values for 
Endpoint Name tags in captured metrics. By default, static values are used. 
When using dynamic tags, then a dynamic to (toD) can compute many different 
endpoint URIs that, can lead to many tags as the URI is dynamic, so use this 
with care if setting this option to false.", "sourceType": 
"org.apache.camel.main.MetricsConfigurationProperties", " [...]
     { "name": "camel.metrics.binders", "required": false, "description": 
"Additional Micrometer binders to include such as jvm-memory, processor, 
jvm-thread, and so forth. Multiple binders can be separated by comma. The 
following binders currently is available from Micrometer: class-loader, 
commons-object-pool2, file-descriptor, hystrix-metrics-binder, jvm-compilation, 
jvm-gc, jvm-heap-pressure, jvm-info, jvm-memory, jvm-thread, log4j2, logback, 
processor, uptime", "sourceType": "org.apa [...]
     { "name": "camel.metrics.clearOnReload", "required": false, "description": 
"Clear the captured metrics data when Camel is reloading routes such as when 
using Camel JBang.", "sourceType": 
"org.apache.camel.main.MetricsConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": true, "secret": false },
diff --git a/core/camel-main/src/main/docs/main.adoc 
b/core/camel-main/src/main/docs/main.adoc
index 78a79e8b33a..c922a5d7d95 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -563,11 +563,14 @@ The camel.telemetryDev supports 4 options, which are 
listed below.
 
 
 === Camel MDC configurations
-The camel.mdc supports 0 options, which are listed below.
+The camel.mdc supports 3 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
+| *camel.mdc.customExchange{zwsp}Headers* | Provide the headers you would like 
to use in the logging. Use &#42; value to include all available headers |  | 
String
+| *camel.mdc.customExchange{zwsp}Properties* | Provide the properties you 
would like to use in the logging. Use &#42; value to include all available 
properties |  | String
+| *camel.mdc.enabled* | To enable MDC service | false | boolean
 |===
 
 
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java 
b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index 84e69be5b48..b7857dd07d9 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -2790,7 +2790,7 @@ public abstract class BaseMainSupport extends BaseService 
{
             answer = 
camelContext.getCamelContextExtension().getBootstrapFactoryFinder()
                     .newInstance("mdc-service", CamelMDCService.class)
                     .orElseThrow(() -> new IllegalArgumentException(
-                            "Cannot find OpenTelemetryTracer2 on classpath. 
Add camel-opentelemetry2 to classpath."));
+                            "Cannot find CamelMDCService on classpath. Add 
camel-mdc to classpath."));
         }
         return answer;
     }
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/MdcConfigurationProperties.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/MdcConfigurationProperties.java
index 4d678032669..1d570b320fb 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/MdcConfigurationProperties.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/MdcConfigurationProperties.java
@@ -28,6 +28,8 @@ public class MdcConfigurationProperties implements 
BootstrapCloseable {
     private MainConfigurationProperties parent;
 
     private boolean enabled;
+    private String customExchangeHeaders;
+    private String customExchangeProperties;
 
     public MdcConfigurationProperties(MainConfigurationProperties parent) {
         this.parent = parent;
@@ -47,11 +49,58 @@ public class MdcConfigurationProperties implements 
BootstrapCloseable {
     }
 
     /**
-     * To enable Mdc
+     * To enable MDC service
+     */
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public String getCustomExchangeHeaders() {
+        return customExchangeHeaders;
+    }
+
+    /**
+     * Provide the headers you would like to use in the logging. Use `&#42;` 
value to include all available headers
+     */
+    public void setCustomExchangeHeaders(String customExchangeHeaders) {
+        this.customExchangeHeaders = customExchangeHeaders;
+    }
+
+    public String getCustomExchangeProperties() {
+        return customExchangeProperties;
+    }
+
+    /**
+     * Provide the properties you would like to use in the logging. Use 
`&#42;` value to include all available
+     * properties
+     */
+    public void setCustomExchangeProperties(String customExchangeProperties) {
+        this.customExchangeProperties = customExchangeProperties;
+    }
+
+    /**
+     * To enable MDC service
      */
     public MdcConfigurationProperties withEnabled(boolean enabled) {
         this.enabled = enabled;
         return this;
     }
 
+    /**
+     * Provide the headers you would like to use in the logging. Use `&#42;` 
value to include all available headers
+     */
+    public MdcConfigurationProperties withCustomExchangeHeaders(String 
customExchangeHeaders) {
+        this.customExchangeHeaders = customExchangeHeaders;
+        return this;
+    }
+
+    /**
+     * Provide the properties you would like to use in the logging. Use 
`&#42;` value to include all available
+     * properties
+     */
+    public MdcConfigurationProperties withCustomExchangeProperties(String 
customExchangeProperties) {
+        this.customExchangeProperties = customExchangeProperties;
+        return this;
+    }
+
 }
diff --git a/proposals/mdc.adoc b/proposals/mdc.adoc
index a65c8fd6655..4fb883afbe9 100644
--- a/proposals/mdc.adoc
+++ b/proposals/mdc.adoc
@@ -5,8 +5,8 @@ authors:
 reviewers: ["@davsclaus"]
 approvers: ["@davsclaus"]
 creation-date: 2025-03-07
-last-updated: 2025-03-21
-status: implementable
+last-updated: 2025-09-25
+status: implemented
 see-also: []
 replaces: []
 superseded-by: []
@@ -93,3 +93,7 @@ If the above is proven to work effectively, then, in any 
future major version we
 == Development
 
 This design proposals should not introduce any breaking compatibility changes. 
The old and new MDC mechanism can coexist, although it will be recommendable to 
deprecate the old one once the new one proves to work correctly.
+
+=== `camel-mdc` component (2025-09-25)
+
+Developed a component which cover the design specifications. See component 
documentation for more details.
\ No newline at end of file
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java
index 324dd3d4176..39bff690a96 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCamelMainMojo.java
@@ -233,6 +233,8 @@ public class PrepareCamelMainMojo extends 
AbstractGeneratorMojo {
                     prefix = "camel.opentelemetry.";
                 } else if (file.getName().contains("TelemetryDev")) {
                     prefix = "camel.telemetryDev.";
+                } else if 
(file.getName().contains("MdcConfigurationProperties")) {
+                    prefix = "camel.mdc.";
                 } else if (file.getName().contains("Metrics")) {
                     prefix = "camel.metrics.";
                 } else if (file.getName().contains("HttpServer")) {

Reply via email to