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 04fece586e1baeecba6dfd98ab7182ed40768df8 Author: Pasquale Congiusti <[email protected]> AuthorDate: Tue Sep 23 16:05:11 2025 +0200 feat(components): Camel MDC --- bom/camel-bom/pom.xml | 5 ++ catalog/camel-allcomponents/pom.xml | 5 ++ .../main/camel-main-configuration-metadata.json | 1 + .../org/apache/camel/catalog/others.properties | 1 + .../org/apache/camel/catalog/others/mdc.json | 15 ++++ components/camel-mdc/pom.xml | 63 +++++++++++++++ .../META-INF/services/org/apache/camel/mdc-service | 2 + .../services/org/apache/camel/other.properties | 7 ++ .../camel-mdc/src/generated/resources/mdc.json | 15 ++++ components/camel-mdc/src/main/docs/mdc.adoc | 10 +++ .../main/java/org/apache/camel/mdc/MDCService.java | 89 ++++++++++++++++++++++ .../camel-mdc/src/test/resources/log4j2.properties | 30 ++++++++ components/pom.xml | 1 + .../java/org/apache/camel/spi/CamelMDCService.java | 27 +++++++ .../java/org/apache/camel/spi/LogListener.java | 12 +++ .../org/apache/camel/processor/LogProcessor.java | 20 +++++ .../main/MdcConfigurationPropertiesConfigurer.java | 48 ++++++++++++ .../camel-main-configuration-metadata.json | 1 + ...rg.apache.camel.main.MdcConfigurationProperties | 2 + core/camel-main/src/main/docs/main.adoc | 9 +++ .../org/apache/camel/main/BaseMainSupport.java | 56 +++++++++++++- .../camel/main/MainConfigurationProperties.java | 12 +++ .../camel/main/MdcConfigurationProperties.java | 57 ++++++++++++++ .../camel/support/processor/CamelLogProcessor.java | 22 ++++++ .../modules/others/examples/json/mdc.json | 1 + docs/components/modules/others/nav.adoc | 1 + docs/components/modules/others/pages/mdc.adoc | 1 + parent/pom.xml | 5 ++ .../maven/packaging/PrepareCamelMainMojo.java | 3 + 29 files changed, 520 insertions(+), 1 deletion(-) diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml index 7e3bf987964..fa912d0b1b2 100644 --- a/bom/camel-bom/pom.xml +++ b/bom/camel-bom/pom.xml @@ -1477,6 +1477,11 @@ <artifactId>camel-master</artifactId> <version>4.15.0-SNAPSHOT</version> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-mdc</artifactId> + <version>4.15.0-SNAPSHOT</version> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-metrics</artifactId> diff --git a/catalog/camel-allcomponents/pom.xml b/catalog/camel-allcomponents/pom.xml index dbe1e7a85fd..2b96ba6ae96 100644 --- a/catalog/camel-allcomponents/pom.xml +++ b/catalog/camel-allcomponents/pom.xml @@ -1286,6 +1286,11 @@ <artifactId>camel-master</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-mdc</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-metrics</artifactId> 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 bb1e632f40c..6dbbe63d36a 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 @@ -21,6 +21,7 @@ { "name": "camel.opentelemetry", "description": "Camel OpenTelemetry configurations", "sourceType": "org.apache.camel.main.OtelConfigurationProperties" }, { "name": "camel.opentelemetry2", "description": "Camel OpenTelemetry 2 configurations", "sourceType": "org.apache.camel.main.Otel2ConfigurationProperties" }, { "name": "camel.telemetryDev", "description": "Camel Telemetry Dev configurations", "sourceType": "org.apache.camel.main.TelemetryDevConfigurationProperties" }, + { "name": "camel.mdc", "description": "Camel MDC configurations", "sourceType": "org.apache.camel.main.MdcConfigurationProperties" }, { "name": "camel.metrics", "description": "Camel Micrometer Metrics configurations", "sourceType": "org.apache.camel.main.MetricsConfigurationProperties" }, { "name": "camel.faulttolerance", "description": "Fault Tolerance EIP Circuit Breaker configurations", "sourceType": "org.apache.camel.main.FaultToleranceConfigurationProperties" }, { "name": "camel.resilience4j", "description": "Resilience4j EIP Circuit Breaker configurations", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties index 39b1e80ca2e..bbd73f057a6 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties @@ -26,6 +26,7 @@ lra mail-microsoft-oauth main management +mdc micrometer-observability micrometer-prometheus microprofile-config 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 new file mode 100644 index 00000000000..073d9a5633d --- /dev/null +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/mdc.json @@ -0,0 +1,15 @@ +{ + "other": { + "kind": "other", + "name": "mdc", + "title": "Mdc", + "description": "Mapped Diagnostic Context component", + "deprecated": false, + "firstVersion": "4.15.0", + "label": "logging", + "supportLevel": "Preview", + "groupId": "org.apache.camel", + "artifactId": "camel-mdc", + "version": "4.15.0-SNAPSHOT" + } +} diff --git a/components/camel-mdc/pom.xml b/components/camel-mdc/pom.xml new file mode 100644 index 00000000000..978c9d6892c --- /dev/null +++ b/components/camel-mdc/pom.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.camel</groupId> + <artifactId>components</artifactId> + <version>4.15.0-SNAPSHOT</version> + </parent> + + <properties> + <firstVersion>4.15.0</firstVersion> + <label>logging</label> + <supportLevel>Preview</supportLevel> + </properties> + + <artifactId>camel-mdc</artifactId> + <packaging>jar</packaging> + <name>Camel :: MDC</name> + <description>Mapped Diagnostic Context component</description> + + <dependencies> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-support</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test-spring-junit5</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>${mockito-version}</version> + <scope>test</scope> + </dependency> + + </dependencies> +</project> diff --git a/components/camel-mdc/src/generated/resources/META-INF/services/org/apache/camel/mdc-service b/components/camel-mdc/src/generated/resources/META-INF/services/org/apache/camel/mdc-service new file mode 100644 index 00000000000..cdc20a7cf74 --- /dev/null +++ b/components/camel-mdc/src/generated/resources/META-INF/services/org/apache/camel/mdc-service @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.mdc.MDCService 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 new file mode 100644 index 00000000000..2f66413827f --- /dev/null +++ b/components/camel-mdc/src/generated/resources/META-INF/services/org/apache/camel/other.properties @@ -0,0 +1,7 @@ +# Generated by camel build tools - do NOT edit this file! +name=mdc +groupId=org.apache.camel +artifactId=camel-mdc +version=4.15.0-SNAPSHOT +projectName=Camel :: MDC +projectDescription=Mapped Diagnostic Context component diff --git a/components/camel-mdc/src/generated/resources/mdc.json b/components/camel-mdc/src/generated/resources/mdc.json new file mode 100644 index 00000000000..073d9a5633d --- /dev/null +++ b/components/camel-mdc/src/generated/resources/mdc.json @@ -0,0 +1,15 @@ +{ + "other": { + "kind": "other", + "name": "mdc", + "title": "Mdc", + "description": "Mapped Diagnostic Context component", + "deprecated": false, + "firstVersion": "4.15.0", + "label": "logging", + "supportLevel": "Preview", + "groupId": "org.apache.camel", + "artifactId": "camel-mdc", + "version": "4.15.0-SNAPSHOT" + } +} diff --git a/components/camel-mdc/src/main/docs/mdc.adoc b/components/camel-mdc/src/main/docs/mdc.adoc new file mode 100644 index 00000000000..03ccd90ea33 --- /dev/null +++ b/components/camel-mdc/src/main/docs/mdc.adoc @@ -0,0 +1,10 @@ += Mdc Component +:doctitle: Mdc +:shortname: mdc +:artifactid: camel-mdc +:description: Mapped Diagnostic Context component +:since: 4.15 +:supportlevel: Preview +:tabs-sync-option: + +*Since Camel {since}* 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 new file mode 100644 index 00000000000..098230b11a0 --- /dev/null +++ b/components/camel-mdc/src/main/java/org/apache/camel/mdc/MDCService.java @@ -0,0 +1,89 @@ +/* + * 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.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.spi.CamelLogger; +import org.apache.camel.spi.CamelMDCService; +import org.apache.camel.spi.LogListener; +import org.apache.camel.spi.annotations.JdkService; +import org.apache.camel.support.service.ServiceSupport; +import org.apache.camel.util.ObjectHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +@JdkService("mdc-service") +public class MDCService extends ServiceSupport implements CamelMDCService { + + private static final Logger LOG = LoggerFactory.getLogger(MDCService.class); + + private CamelContext camelContext; + + @Override + public CamelContext getCamelContext() { + return camelContext; + } + + @Override + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + /** + * Registers this {@link MDCService} on the {@link CamelContext} if not already registered. + */ + public void init(CamelContext camelContext) { + if (!camelContext.hasService(this)) { + try { + // start this service eager so we init before Camel is starting up + camelContext.addService(this, true, true); + } catch (Exception e) { + throw RuntimeCamelException.wrapRuntimeCamelException(e); + } + } + } + + @Override + public void doInit() { + ObjectHelper.notNull(camelContext, "CamelContext", this); + camelContext.getCamelContextExtension().addLogListener(new TracingLogListener()); + } + + private final class TracingLogListener implements LogListener { + + @Override + public String onLog(Exchange exchange, CamelLogger camelLogger, String message) { + try { + // MDC setting here + MDC.put("exchangeID", exchange.getExchangeId()); + } catch (Exception t) { + // This exception is ignored + LOG.warn("MDC: failed to store MDC data. This exception is ignored.", t); + } + return message; + } + + @Override + public void afterLog(Exchange exchange, CamelLogger camelLogger, String message) { + MDC.clear(); + } + } + +} diff --git a/components/camel-mdc/src/test/resources/log4j2.properties b/components/camel-mdc/src/test/resources/log4j2.properties new file mode 100644 index 00000000000..c9d7df800c7 --- /dev/null +++ b/components/camel-mdc/src/test/resources/log4j2.properties @@ -0,0 +1,30 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- +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%n + +appender.file.type = File +appender.file.name = file +appender.file.fileName = target/camel-telemetry-test.log +appender.file.append = true +appender.file.layout.type = PatternLayout +appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n + +rootLogger.level = INFO +rootLogger.appenderRef.file.ref = file diff --git a/components/pom.xml b/components/pom.xml index 1b87350f836..b4b07ebb810 100644 --- a/components/pom.xml +++ b/components/pom.xml @@ -215,6 +215,7 @@ <module>camel-mail</module> <module>camel-mail-microsoft-oauth</module> <module>camel-mapstruct</module> + <module>camel-mdc</module> <module>camel-metrics</module> <module>camel-micrometer</module> <module>camel-micrometer-observability</module> diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/CamelMDCService.java b/core/camel-api/src/main/java/org/apache/camel/spi/CamelMDCService.java new file mode 100644 index 00000000000..25252052788 --- /dev/null +++ b/core/camel-api/src/main/java/org/apache/camel/spi/CamelMDCService.java @@ -0,0 +1,27 @@ +/* + * 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.spi; + +import org.apache.camel.CamelContextAware; +import org.apache.camel.Service; + +/** + * A Camel MDC service is a factory for Mapped Diagnostic Context service. + */ +public interface CamelMDCService extends Service, CamelContextAware { + +} diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/LogListener.java b/core/camel-api/src/main/java/org/apache/camel/spi/LogListener.java index 04a741265fa..ab726f2cbb2 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/LogListener.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/LogListener.java @@ -38,4 +38,16 @@ public interface LogListener { */ String onLog(Exchange exchange, CamelLogger camelLogger, String message); + /** + * Invoked right after Log component or Log EIP logs. The method can be used for cleaning up any transient + * information used during onLog execution. + * + * @param exchange camel exchange + * @param camelLogger {@link CamelLogger} + * @param message log message + */ + default void afterLog(Exchange exchange, CamelLogger camelLogger, String message) { + // NO-OP + } + } diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/LogProcessor.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/LogProcessor.java index 0491209964e..5babd94ca6a 100644 --- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/LogProcessor.java +++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/LogProcessor.java @@ -78,6 +78,9 @@ public class LogProcessor extends BaseProcessorSupport implements Traceable, IdA msg = fireListeners(exchange, msg); } logger.doLog(msg); + if (listeners != null && !listeners.isEmpty()) { + closeListeners(exchange, msg); + } } catch (Exception e) { exchange.setException(e); } @@ -105,6 +108,23 @@ public class LogProcessor extends BaseProcessorSupport implements Traceable, IdA return message; } + private void closeListeners(Exchange exchange, String message) { + for (LogListener listener : listeners) { + if (listener == null) { + continue; + } + try { + listener.afterLog(exchange, logger, message); + } catch (Exception t) { + LOG.warn("Ignoring an exception: {} thrown by: {} caused by: {}", t.getClass().getName(), + listener.getClass().getName(), t.getMessage()); + if (LOG.isDebugEnabled()) { + LOG.debug("", t); + } + } + } + } + @Override public String toString() { return id; 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 new file mode 100644 index 00000000000..9707c284526 --- /dev/null +++ b/core/camel-main/src/generated/java/org/apache/camel/main/MdcConfigurationPropertiesConfigurer.java @@ -0,0 +1,48 @@ +/* Generated by camel build tools - do NOT edit this file! */ +package org.apache.camel.main; + +import javax.annotation.processing.Generated; +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.spi.ExtendedPropertyConfigurerGetter; +import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.spi.ConfigurerStrategy; +import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.util.CaseInsensitiveMap; +import org.apache.camel.main.MdcConfigurationProperties; + +/** + * Generated by camel build tools - do NOT edit this file! + */ +@Generated("org.apache.camel.maven.packaging.GenerateConfigurerMojo") +@SuppressWarnings("unchecked") +public class MdcConfigurationPropertiesConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, ExtendedPropertyConfigurerGetter { + + private static final Map<String, Object> ALL_OPTIONS; + static { + Map<String, Object> map = new CaseInsensitiveMap(); + ALL_OPTIONS = map; + } + + @Override + public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { + return false; + } + + @Override + public Map<String, Object> getAllOptions(Object target) { + return ALL_OPTIONS; + } + + @Override + public Class<?> getOptionType(String name, boolean ignoreCase) { + return null; + } + + @Override + public Object getOptionValue(Object obj, String name, boolean ignoreCase) { + 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 bb1e632f40c..6dbbe63d36a 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 @@ -21,6 +21,7 @@ { "name": "camel.opentelemetry", "description": "Camel OpenTelemetry configurations", "sourceType": "org.apache.camel.main.OtelConfigurationProperties" }, { "name": "camel.opentelemetry2", "description": "Camel OpenTelemetry 2 configurations", "sourceType": "org.apache.camel.main.Otel2ConfigurationProperties" }, { "name": "camel.telemetryDev", "description": "Camel Telemetry Dev configurations", "sourceType": "org.apache.camel.main.TelemetryDevConfigurationProperties" }, + { "name": "camel.mdc", "description": "Camel MDC configurations", "sourceType": "org.apache.camel.main.MdcConfigurationProperties" }, { "name": "camel.metrics", "description": "Camel Micrometer Metrics configurations", "sourceType": "org.apache.camel.main.MetricsConfigurationProperties" }, { "name": "camel.faulttolerance", "description": "Fault Tolerance EIP Circuit Breaker configurations", "sourceType": "org.apache.camel.main.FaultToleranceConfigurationProperties" }, { "name": "camel.resilience4j", "description": "Resilience4j EIP Circuit Breaker configurations", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties" }, diff --git a/core/camel-main/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.main.MdcConfigurationProperties b/core/camel-main/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.main.MdcConfigurationProperties new file mode 100644 index 00000000000..a95186bdc04 --- /dev/null +++ b/core/camel-main/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.main.MdcConfigurationProperties @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.main.MdcConfigurationPropertiesConfigurer diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc index 8dac7ccd593..78a79e8b33a 100644 --- a/core/camel-main/src/main/docs/main.adoc +++ b/core/camel-main/src/main/docs/main.adoc @@ -562,6 +562,15 @@ The camel.telemetryDev supports 4 options, which are listed below. |=== +=== Camel MDC configurations +The camel.mdc supports 0 options, which are listed below. + +[width="100%",cols="2,5,^1,2",options="header"] +|=== +| Name | Description | Default | Type +|=== + + === Camel Micrometer Metrics configurations The camel.metrics supports 14 options, which are listed below. 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 2662a60413b..84e69be5b48 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 @@ -67,6 +67,7 @@ import org.apache.camel.spi.AutowiredLifecycleStrategy; import org.apache.camel.spi.BacklogTracer; import org.apache.camel.spi.CamelBeanPostProcessor; import org.apache.camel.spi.CamelEvent; +import org.apache.camel.spi.CamelMDCService; import org.apache.camel.spi.CamelMetricsService; import org.apache.camel.spi.CamelTracingService; import org.apache.camel.spi.CompileStrategy; @@ -136,7 +137,7 @@ public abstract class BaseMainSupport extends BaseService { "camel.context.", "camel.resilience4j.", "camel.faulttolerance.", "camel.rest.", "camel.vault.", "camel.threadpool.", "camel.health.", "camel.lra.", "camel.opentelemetry2.", "camel.opentelemetry.", - "camel.telemetryDev.", "camel.management.", "camel.metrics.", "camel.routeTemplate", + "camel.telemetryDev.", "camel.management.", "camel.mdc.", "camel.metrics.", "camel.routeTemplate", "camel.devConsole.", "camel.variable.", "camel.beans.", "camel.globalOptions.", "camel.server.", "camel.ssl.", "camel.debug.", "camel.trace.", "camel.routeController." }; @@ -1283,6 +1284,7 @@ public abstract class BaseMainSupport extends BaseService { OrderedLocationProperties lraProperties = new OrderedLocationProperties(); OrderedLocationProperties otelProperties = new OrderedLocationProperties(); OrderedLocationProperties otel2Properties = new OrderedLocationProperties(); + OrderedLocationProperties mdcProperties = new OrderedLocationProperties(); OrderedLocationProperties telemetryDevProperties = new OrderedLocationProperties(); OrderedLocationProperties metricsProperties = new OrderedLocationProperties(); OrderedLocationProperties routeTemplateProperties = new OrderedLocationProperties(); @@ -1359,6 +1361,12 @@ public abstract class BaseMainSupport extends BaseService { String option = key.substring(19); validateOptionAndValue(key, option, value); telemetryDevProperties.put(loc, optionKey(option), value); + } else if (startsWithIgnoreCase(key, "camel.mdc.")) { + // grab the value + String value = prop.getProperty(key); + String option = key.substring(10); + validateOptionAndValue(key, option, value); + mdcProperties.put(loc, optionKey(option), value); } else if (startsWithIgnoreCase(key, "camel.metrics.")) { // grab the value String value = prop.getProperty(key); @@ -1525,6 +1533,11 @@ public abstract class BaseMainSupport extends BaseService { setMetricsProperties(camelContext, metricsProperties, mainConfigurationProperties.isAutoConfigurationFailFast(), autoConfiguredProperties); } + if (!mdcProperties.isEmpty() || mainConfigurationProperties.hasMdcConfiguration()) { + LOG.debug("Auto-configuring MDC from loaded properties: {}", mdcProperties.size()); + setMdcProperties(camelContext, mdcProperties, mainConfigurationProperties.isAutoConfigurationFailFast(), + autoConfiguredProperties); + } if (!devConsoleProperties.isEmpty()) { LOG.debug("Auto-configuring Dev Console from loaded properties: {}", devConsoleProperties.size()); setDevConsoleProperties(camelContext, devConsoleProperties, @@ -1656,6 +1669,11 @@ public abstract class BaseMainSupport extends BaseService { LOG.warn("Property not auto-configured: camel.management.{}={}", k, v); }); } + if (!mdcProperties.isEmpty()) { + mdcProperties.forEach((k, v) -> { + LOG.warn("Property not auto-configured: camel.mdc.{}={}", k, v); + }); + } // and call after all properties are set DefaultConfigurationConfigurer.afterPropertiesSet(camelContext); @@ -1851,6 +1869,28 @@ public abstract class BaseMainSupport extends BaseService { } } + private void setMdcProperties( + CamelContext camelContext, OrderedLocationProperties mdcProperties, + boolean failIfNotSet, OrderedLocationProperties autoConfiguredProperties) + throws Exception { + + String loc = mdcProperties.getLocation("enabled"); + Object obj = mdcProperties.remove("enabled"); + if (ObjectHelper.isNotEmpty(obj)) { + autoConfiguredProperties.put(loc, "camel.mdc.enabled", obj.toString()); + } + boolean enabled = obj != null ? CamelContextHelper.parseBoolean(camelContext, obj.toString()) : true; + if (enabled) { + CamelMDCService mdc = resolveMDCService(camelContext); + setPropertiesOnTarget(camelContext, mdc, mdcProperties, "camel.mdc.", failIfNotSet, true, + autoConfiguredProperties); + if (camelContext.hasService(CamelMDCService.class) == null) { + // add as service so tracing can be active + camelContext.addService(mdc, true, true); + } + } + } + private void setTelemetryDevProperties( CamelContext camelContext, OrderedLocationProperties telemetryDevProperties, boolean failIfNotSet, OrderedLocationProperties autoConfiguredProperties) @@ -2741,6 +2781,20 @@ public abstract class BaseMainSupport extends BaseService { return answer; } + private static CamelMDCService resolveMDCService(CamelContext camelContext) throws Exception { + CamelMDCService answer = camelContext.hasService(CamelMDCService.class); + if (answer == null) { + answer = camelContext.getRegistry().findSingleByType(CamelMDCService.class); + } + if (answer == null) { + answer = camelContext.getCamelContextExtension().getBootstrapFactoryFinder() + .newInstance("mdc-service", CamelMDCService.class) + .orElseThrow(() -> new IllegalArgumentException( + "Cannot find OpenTelemetryTracer2 on classpath. Add camel-opentelemetry2 to classpath.")); + } + return answer; + } + private static MainHttpServerFactory resolveMainHttpServerFactory(CamelContext camelContext) { // lookup in service registry first MainHttpServerFactory answer = camelContext.getRegistry().findSingleByType(MainHttpServerFactory.class); diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MainConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/MainConfigurationProperties.java index 1048cd15014..c95aab73387 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/MainConfigurationProperties.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/MainConfigurationProperties.java @@ -61,6 +61,7 @@ public class MainConfigurationProperties extends DefaultConfigurationProperties< private LraConfigurationProperties lraConfigurationProperties; private OtelConfigurationProperties otelConfigurationProperties; private Otel2ConfigurationProperties otel2ConfigurationProperties; + private MdcConfigurationProperties mdcConfigurationProperties; private TelemetryDevConfigurationProperties telemetryDevConfigurationProperties; private MetricsConfigurationProperties metricsConfigurationProperties; private ThreadPoolConfigurationProperties threadPoolProperties; @@ -97,6 +98,10 @@ public class MainConfigurationProperties extends DefaultConfigurationProperties< telemetryDevConfigurationProperties.close(); telemetryDevConfigurationProperties = null; } + if (mdcConfigurationProperties != null) { + mdcConfigurationProperties.close(); + mdcConfigurationProperties = null; + } if (metricsConfigurationProperties != null) { metricsConfigurationProperties.close(); metricsConfigurationProperties = null; @@ -237,6 +242,13 @@ public class MainConfigurationProperties extends DefaultConfigurationProperties< return telemetryDevConfigurationProperties != null; } + /** + * Whether there has been any MDC configuration specified + */ + public boolean hasMdcConfiguration() { + return mdcConfigurationProperties != null; + } + /** * To configure Micrometer metrics. */ 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 new file mode 100644 index 00000000000..4d678032669 --- /dev/null +++ b/core/camel-main/src/main/java/org/apache/camel/main/MdcConfigurationProperties.java @@ -0,0 +1,57 @@ +/* + * 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.main; + +import org.apache.camel.spi.BootstrapCloseable; +import org.apache.camel.spi.Configurer; + +/** + * Global configuration for MDC + */ +@Configurer(extended = true) +public class MdcConfigurationProperties implements BootstrapCloseable { + + private MainConfigurationProperties parent; + + private boolean enabled; + + public MdcConfigurationProperties(MainConfigurationProperties parent) { + this.parent = parent; + } + + public MainConfigurationProperties end() { + return parent; + } + + @Override + public void close() { + parent = null; + } + + public boolean isEnabled() { + return enabled; + } + + /** + * To enable Mdc + */ + public MdcConfigurationProperties withEnabled(boolean enabled) { + this.enabled = enabled; + return this; + } + +} diff --git a/core/camel-support/src/main/java/org/apache/camel/support/processor/CamelLogProcessor.java b/core/camel-support/src/main/java/org/apache/camel/support/processor/CamelLogProcessor.java index d6c9ec0192d..6162ab3247b 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/processor/CamelLogProcessor.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/processor/CamelLogProcessor.java @@ -102,6 +102,7 @@ public class CamelLogProcessor extends AsyncProcessorSupport implements IdAware, } output = fireListeners(exchange, output); logger.log(output); + closeListeners(exchange, output); } callback.done(true); return true; @@ -115,6 +116,7 @@ public class CamelLogProcessor extends AsyncProcessorSupport implements IdAware, } output = fireListeners(exchange, output); logger.log(output, exception); + closeListeners(exchange, output); } } @@ -126,6 +128,7 @@ public class CamelLogProcessor extends AsyncProcessorSupport implements IdAware, } output = fireListeners(exchange, output); logger.log(output); + closeListeners(exchange, output); } } @@ -150,6 +153,25 @@ public class CamelLogProcessor extends AsyncProcessorSupport implements IdAware, return message; } + private void closeListeners(Exchange exchange, String message) { + if (listeners == null || listeners.isEmpty()) { + return; + } + for (LogListener listener : listeners) { + if (listener == null) { + continue; + } + try { + listener.afterLog(exchange, logger, message); + } catch (Exception t) { + LOG.warn("Ignoring an exception thrown by {}: {}", listener.getClass().getName(), t.getMessage()); + if (LOG.isDebugEnabled()) { + LOG.debug("", t); + } + } + } + } + public CamelLogger getLogger() { return logger; } diff --git a/docs/components/modules/others/examples/json/mdc.json b/docs/components/modules/others/examples/json/mdc.json new file mode 120000 index 00000000000..0d57f5bed57 --- /dev/null +++ b/docs/components/modules/others/examples/json/mdc.json @@ -0,0 +1 @@ +../../../../../../components/camel-mdc/src/generated/resources/mdc.json \ No newline at end of file diff --git a/docs/components/modules/others/nav.adoc b/docs/components/modules/others/nav.adoc index 02b181394d9..16495e4d3ac 100644 --- a/docs/components/modules/others/nav.adoc +++ b/docs/components/modules/others/nav.adoc @@ -28,6 +28,7 @@ ** xref:lra.adoc[LRA] ** xref:mail-microsoft-oauth.adoc[Mail Microsoft Oauth] ** xref:main.adoc[Main] +** xref:mdc.adoc[Mdc] ** xref:observation.adoc[Micrometer Observability] ** xref:micrometer-observability.adoc[Micrometer Observability 2] ** xref:micrometer-prometheus.adoc[Micrometer Prometheus] diff --git a/docs/components/modules/others/pages/mdc.adoc b/docs/components/modules/others/pages/mdc.adoc new file mode 120000 index 00000000000..eec3ea2ffd3 --- /dev/null +++ b/docs/components/modules/others/pages/mdc.adoc @@ -0,0 +1 @@ +../../../../../components/camel-mdc/src/main/docs/mdc.adoc \ No newline at end of file diff --git a/parent/pom.xml b/parent/pom.xml index 2442a93df2a..2a14a54308d 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -1937,6 +1937,11 @@ <artifactId>camel-master</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-mdc</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-metrics</artifactId> 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 e919a83c765..324dd3d4176 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 @@ -443,6 +443,9 @@ public class PrepareCamelMainMojo extends AbstractGeneratorMojo { model.getGroups().add(new MainGroupModel( "camel.telemetryDev", "Camel Telemetry Dev configurations", "org.apache.camel.main.TelemetryDevConfigurationProperties")); + model.getGroups().add(new MainGroupModel( + "camel.mdc", "Camel MDC configurations", + "org.apache.camel.main.MdcConfigurationProperties")); model.getGroups().add(new MainGroupModel( "camel.metrics", "Camel Micrometer Metrics configurations", "org.apache.camel.main.MetricsConfigurationProperties"));
