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

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


The following commit(s) were added to refs/heads/main by this push:
     new 0faa929c6e Add micrometer-observability traceCustomIdOnly 
configuration option
0faa929c6e is described below

commit 0faa929c6e01873f68cf5ff19b631f561c7f1a63
Author: James Netherton <[email protected]>
AuthorDate: Wed Sep 23 21:53:18 2026 +0100

    Add micrometer-observability traceCustomIdOnly configuration option
    
    Fixes #9216.
    
    Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
---
 .../extensions/micrometer-observability.adoc       |  18 ++-
 .../CamelMicrometerObservabilityConfig.java        |  20 +++-
 .../MicrometerObservabilityTracerProducer.java     |   1 +
 .../it/MicrometerObservabilityResource.java        |  14 +++
 .../it/MicrometerObservabilityRoutes.java          |   9 ++
 .../observability/it/SpanExporterResource.java     |   3 +-
 ...icrometerObservabilityTraceCustomIdOnlyIT.java} |  18 +--
 ...crometerObservabilityTraceCustomIdOnlyTest.java | 122 +++++++++++++++++++++
 .../it/TraceCustomIdOnlyTestProfile.java}          |  21 ++--
 9 files changed, 185 insertions(+), 41 deletions(-)

diff --git 
a/docs/modules/ROOT/pages/reference/extensions/micrometer-observability.adoc 
b/docs/modules/ROOT/pages/reference/extensions/micrometer-observability.adoc
index d4743e987f..c693e28989 100644
--- a/docs/modules/ROOT/pages/reference/extensions/micrometer-observability.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/micrometer-observability.adoc
@@ -76,9 +76,9 @@ a| 
[[quarkus-camel-micrometer-observability-exclude-patterns]]`link:#quarkus-cam
 Sets whether to disable tracing for endpoint URIs or Processor ids that match 
the given comma separated patterns.
 The pattern can take the following forms:
 
-1. An exact match on the endpoint URI, e.g., {@code platform-http:/some/path}
-2. A wildcard match, e.g., {@code platform-http:*}
-3. A regular expression matching the endpoint URI, e.g., {@code 
platform-http:/prefix/.*}
+1. An exact match on the endpoint URI, e.g., `platform-http:/some/path`
+2. A wildcard match, e.g., `platform-http:*`
+3. A regular expression matching the endpoint URI, e.g., 
`platform-http:/prefix/.*`
 | `string`
 | 
 
@@ -91,7 +91,7 @@ Multiple patterns can be separated by comma. All processors 
are included by defa
 
 a| 
[[quarkus-camel-micrometer-observability-trace-processors]]`link:#quarkus-camel-micrometer-observability-trace-processors[quarkus.camel.micrometer-observability.trace-processors]`
 
-Sets whether to create new spans for each Camel Processor. Use the {@code 
excludePatterns} property to filter
+Sets whether to create new spans for each Camel Processor. Use the 
`excludePatterns` property to filter
 out specific processors.
 
 When enabled, this generates much more detailed traces but also increases 
overhead.
@@ -101,16 +101,22 @@ When enabled, this generates much more detailed traces 
but also increases overhe
 a| 
[[quarkus-camel-micrometer-observability-disable-core-processors]]`link:#quarkus-camel-micrometer-observability-disable-core-processors[quarkus.camel.micrometer-observability.disable-core-processors]`
 
 Disable tracing of inner core processors (any core DSL processor provided in 
the route, for example
-{@code bean}, {@code log}, ...).
+`bean`, `log`, ...).
 | `boolean`
 | `false`
 
 a| 
[[quarkus-camel-micrometer-observability-trace-headers-inclusion]]`link:#quarkus-camel-micrometer-observability-trace-headers-inclusion[quarkus.camel.micrometer-observability.trace-headers-inclusion]`
 
-If set to {@code true}, adds the generated telemetry {@code CAMEL_TRACE_ID} 
and {@code CAMEL_SPAN_ID}
+If set to `true`, adds the generated telemetry `CAMEL_TRACE_ID` and 
`CAMEL_SPAN_ID`
 Exchange headers.
 | `boolean`
 | `false`
+
+a| 
[[quarkus-camel-micrometer-observability-trace-custom-id-only]]`link:#quarkus-camel-micrometer-observability-trace-custom-id-only[quarkus.camel.micrometer-observability.trace-custom-id-only]`
+
+If set to `true`, only creates trace spans for routes and nodes that have a 
custom id assigned.
+| `boolean`
+| `false`
 |===
 
 [.configuration-legend]
diff --git 
a/extensions/micrometer-observability/runtime/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/CamelMicrometerObservabilityConfig.java
 
b/extensions/micrometer-observability/runtime/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/CamelMicrometerObservabilityConfig.java
index 68fb554ab5..e4b15d3514 100644
--- 
a/extensions/micrometer-observability/runtime/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/CamelMicrometerObservabilityConfig.java
+++ 
b/extensions/micrometer-observability/runtime/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/CamelMicrometerObservabilityConfig.java
@@ -30,9 +30,9 @@ public interface CamelMicrometerObservabilityConfig {
      * Sets whether to disable tracing for endpoint URIs or Processor ids that 
match the given comma separated patterns.
      * The pattern can take the following forms:
      *
-     * 1. An exact match on the endpoint URI, e.g., {@code 
platform-http:/some/path}
-     * 2. A wildcard match, e.g., {@code platform-http:*}
-     * 3. A regular expression matching the endpoint URI, e.g., {@code 
platform-http:/prefix/.*}
+     * 1. An exact match on the endpoint URI, e.g., `platform-http:/some/path`
+     * 2. A wildcard match, e.g., `platform-http:*`
+     * 3. A regular expression matching the endpoint URI, e.g., 
`platform-http:/prefix/.*`
      *
      * @asciidoclet
      */
@@ -47,7 +47,7 @@ public interface CamelMicrometerObservabilityConfig {
     Optional<String> includePatterns();
 
     /**
-     * Sets whether to create new spans for each Camel Processor. Use the 
{@code excludePatterns} property to filter
+     * Sets whether to create new spans for each Camel Processor. Use the 
`excludePatterns` property to filter
      * out specific processors.
      *
      * When enabled, this generates much more detailed traces but also 
increases overhead.
@@ -59,7 +59,7 @@ public interface CamelMicrometerObservabilityConfig {
 
     /**
      * Disable tracing of inner core processors (any core DSL processor 
provided in the route, for example
-     * {@code bean}, {@code log}, ...).
+     * `bean`, `log`, ...).
      *
      * @asciidoclet
      */
@@ -67,11 +67,19 @@ public interface CamelMicrometerObservabilityConfig {
     boolean disableCoreProcessors();
 
     /**
-     * If set to {@code true}, adds the generated telemetry {@code 
CAMEL_TRACE_ID} and {@code CAMEL_SPAN_ID}
+     * If set to `true`, adds the generated telemetry `CAMEL_TRACE_ID` and 
`CAMEL_SPAN_ID`
      * Exchange headers.
      *
      * @asciidoclet
      */
     @WithDefault("false")
     boolean traceHeadersInclusion();
+
+    /**
+     * If set to `true`, only creates trace spans for routes and nodes that 
have a custom id assigned.
+     *
+     * @asciidoclet
+     */
+    @WithDefault("false")
+    boolean traceCustomIdOnly();
 }
diff --git 
a/extensions/micrometer-observability/runtime/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/MicrometerObservabilityTracerProducer.java
 
b/extensions/micrometer-observability/runtime/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/MicrometerObservabilityTracerProducer.java
index 20c635af10..b017148e0b 100644
--- 
a/extensions/micrometer-observability/runtime/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/MicrometerObservabilityTracerProducer.java
+++ 
b/extensions/micrometer-observability/runtime/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/MicrometerObservabilityTracerProducer.java
@@ -74,6 +74,7 @@ public class MicrometerObservabilityTracerProducer {
         tracer.setTraceProcessors(config.traceProcessors());
         tracer.setDisableCoreProcessors(config.disableCoreProcessors());
         tracer.setTraceHeadersInclusion(config.traceHeadersInclusion());
+        tracer.setTraceCustomIdOnly(config.traceCustomIdOnly());
 
         tracer.init(camelContext);
         return tracer;
diff --git 
a/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityResource.java
 
b/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityResource.java
index 92df917fae..9f1e2af08b 100644
--- 
a/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityResource.java
+++ 
b/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityResource.java
@@ -51,6 +51,20 @@ public class MicrometerObservabilityResource {
         return producerTemplate.requestBody("direct:excluded", "test", 
String.class);
     }
 
+    @Path("/trace-custom-id")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String traceCustomId() {
+        return producerTemplate.requestBody("direct:customId", "test", 
String.class);
+    }
+
+    @Path("/trace-no-custom-id")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String traceNoCustomId() {
+        return producerTemplate.requestBody("direct:noCustomId", "test", 
String.class);
+    }
+
     @Path("/trace-upstream")
     @GET
     @Produces(MediaType.TEXT_PLAIN)
diff --git 
a/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityRoutes.java
 
b/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityRoutes.java
index bdcbbc0e52..36204ee552 100644
--- 
a/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityRoutes.java
+++ 
b/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityRoutes.java
@@ -32,5 +32,14 @@ public class MicrometerObservabilityRoutes extends 
RouteBuilder {
         from("direct:excluded")
                 .routeId("excluded-route")
                 .setBody(constant("excluded-response"));
+
+        // Route and node both have a custom id assigned, so both are traced 
when trace-custom-id-only is enabled
+        from("direct:customId")
+                .routeId("custom-id-route")
+                
.setBody(constant("custom-id-response")).id("custom-id-set-body");
+
+        // No custom route id, so nothing is traced when trace-custom-id-only 
is enabled
+        from("direct:noCustomId")
+                .setBody(constant("no-custom-id-response"));
     }
 }
diff --git 
a/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/SpanExporterResource.java
 
b/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/SpanExporterResource.java
index 1564963455..6bd697a006 100644
--- 
a/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/SpanExporterResource.java
+++ 
b/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/SpanExporterResource.java
@@ -73,7 +73,7 @@ public class SpanExporterResource {
 
     /**
      * Returns the live configuration values of the {@link 
MicrometerObservabilityTracer} registered
-     * in the Camel registry. Used by {@code testConfigPropertiesAreWired} to 
verify that all five
+     * in the Camel registry. Used by {@code testConfigPropertiesAreWired} to 
verify that all
      * {@code quarkus.camel.micrometer-observability.*} properties are 
correctly passed through
      * {@code CamelMicrometerObservabilityConfig} → {@code 
MicrometerObservabilityTracerProducer}
      * → the tracer instance.
@@ -91,6 +91,7 @@ public class SpanExporterResource {
             builder.add("traceProcessors", tracer.isTraceProcessors());
             builder.add("disableCoreProcessors", 
tracer.isDisableCoreProcessors());
             builder.add("traceHeadersInclusion", 
tracer.isTraceHeadersInclusion());
+            builder.add("traceCustomIdOnly", tracer.isTraceCustomIdOnly());
         }
         return builder.build();
     }
diff --git 
a/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityRoutes.java
 
b/integration-tests/micrometer-observability/src/test/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityTraceCustomIdOnlyIT.java
similarity index 58%
copy from 
integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityRoutes.java
copy to 
integration-tests/micrometer-observability/src/test/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityTraceCustomIdOnlyIT.java
index bdcbbc0e52..a9588b70b8 100644
--- 
a/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityRoutes.java
+++ 
b/integration-tests/micrometer-observability/src/test/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityTraceCustomIdOnlyIT.java
@@ -16,21 +16,9 @@
  */
 package org.apache.camel.quarkus.component.micrometer.observability.it;
 
-import jakarta.enterprise.context.ApplicationScoped;
-import org.apache.camel.builder.RouteBuilder;
+import io.quarkus.test.junit.QuarkusIntegrationTest;
 
-@ApplicationScoped
-public class MicrometerObservabilityRoutes extends RouteBuilder {
+@QuarkusIntegrationTest
+class MicrometerObservabilityTraceCustomIdOnlyIT extends 
MicrometerObservabilityTraceCustomIdOnlyTest {
 
-    @Override
-    public void configure() throws Exception {
-        from("direct:traced")
-                .routeId("traced-route")
-                .setBody(constant("traced-response"));
-
-        // This route is excluded from tracing via 
quarkus.camel.micrometer-observability.exclude-patterns
-        from("direct:excluded")
-                .routeId("excluded-route")
-                .setBody(constant("excluded-response"));
-    }
 }
diff --git 
a/integration-tests/micrometer-observability/src/test/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityTraceCustomIdOnlyTest.java
 
b/integration-tests/micrometer-observability/src/test/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityTraceCustomIdOnlyTest.java
new file mode 100644
index 0000000000..e9892c118c
--- /dev/null
+++ 
b/integration-tests/micrometer-observability/src/test/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityTraceCustomIdOnlyTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.quarkus.component.micrometer.observability.it;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.TestProfile;
+import io.restassured.RestAssured;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+
+import static org.awaitility.Awaitility.await;
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@TestProfile(TraceCustomIdOnlyTestProfile.class)
+@QuarkusTest
+class MicrometerObservabilityTraceCustomIdOnlyTest {
+
+    @AfterEach
+    public void afterEach() {
+        RestAssured.post("/micrometer-observability/exporter/spans/reset")
+                .then()
+                .statusCode(204);
+    }
+
+    @Test
+    void traceCustomIdOnlyIsWired() {
+        RestAssured.get("/micrometer-observability/exporter/tracer-config")
+                .then()
+                .statusCode(200)
+                .body("traceCustomIdOnly", equalTo(true));
+    }
+
+    @Test
+    void customIdRouteAndNodeAreTraced() {
+        RestAssured.get("/micrometer-observability/trace-custom-id")
+                .then()
+                .statusCode(200)
+                .body(equalTo("custom-id-response"));
+
+        await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
+            List<Map<String, String>> spans = getSpans();
+            assertTrue(spans.stream().anyMatch(span -> 
"custom-id-route".equals(span.get("camel.route.id"))),
+                    "Expected a route span for custom-id-route, got: " + 
spans);
+            assertTrue(spans.stream().anyMatch(span -> 
"custom-id-set-body-setBody".equals(span.get("name"))),
+                    "Expected a processor span for custom-id-set-body, got: " 
+ spans);
+        });
+    }
+
+    @Test
+    void nonCustomIdNodeIsNotTraced() {
+        RestAssured.get("/micrometer-observability/trace")
+                .then()
+                .statusCode(200)
+                .body(equalTo("traced-response"));
+
+        // The route has a custom id so it is traced, but its setBody node 
does not, so no processor span is created
+        await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
+            List<Map<String, String>> spans = getSpans();
+            assertTrue(spans.stream().anyMatch(span -> 
"traced-route".equals(span.get("camel.route.id"))),
+                    "Expected a route span for traced-route, got: " + spans);
+        });
+        List<Map<String, String>> spans = getSpans();
+        assertTrue(spans.stream().noneMatch(span -> 
"EVENT_PROCESS".equals(span.get("op"))),
+                "Expected no processor spans, got: " + spans);
+    }
+
+    @Test
+    void nonCustomIdRouteIsNotTraced() {
+        RestAssured.get("/micrometer-observability/trace-no-custom-id")
+                .then()
+                .statusCode(200)
+                .body(equalTo("no-custom-id-response"));
+
+        // Invoke a traced route afterwards so that once its spans are 
exported, any spans for direct:noCustomId would be too
+        RestAssured.get("/micrometer-observability/trace-custom-id")
+                .then()
+                .statusCode(200);
+
+        await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
+            List<Map<String, String>> spans = getSpans();
+            assertTrue(spans.stream().anyMatch(span -> 
"custom-id-route".equals(span.get("camel.route.id"))),
+                    "Expected a route span for custom-id-route, got: " + 
spans);
+        });
+
+        // The route has no custom id, so no Camel spans are created for it
+        List<Map<String, String>> spans = getSpans();
+        assertTrue(spans.stream().noneMatch(span -> 
"direct://noCustomId".equals(span.get("camel.uri"))),
+                "Expected no spans for direct:noCustomId, got: " + spans);
+        assertTrue(spans.stream()
+                .filter(span -> "EVENT_PROCESS".equals(span.get("op")))
+                .allMatch(span -> 
"custom-id-set-body-setBody".equals(span.get("name"))),
+                "Expected no processor spans for direct:noCustomId, got: " + 
spans);
+    }
+
+    private static List<Map<String, String>> getSpans() {
+        return RestAssured.get("/micrometer-observability/exporter/spans")
+                .then()
+                .statusCode(200)
+                .extract()
+                .jsonPath()
+                .getList("$");
+    }
+}
diff --git 
a/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityRoutes.java
 
b/integration-tests/micrometer-observability/src/test/java/org/apache/camel/quarkus/component/micrometer/observability/it/TraceCustomIdOnlyTestProfile.java
similarity index 60%
copy from 
integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityRoutes.java
copy to 
integration-tests/micrometer-observability/src/test/java/org/apache/camel/quarkus/component/micrometer/observability/it/TraceCustomIdOnlyTestProfile.java
index bdcbbc0e52..7ef3976832 100644
--- 
a/integration-tests/micrometer-observability/src/main/java/org/apache/camel/quarkus/component/micrometer/observability/it/MicrometerObservabilityRoutes.java
+++ 
b/integration-tests/micrometer-observability/src/test/java/org/apache/camel/quarkus/component/micrometer/observability/it/TraceCustomIdOnlyTestProfile.java
@@ -16,21 +16,16 @@
  */
 package org.apache.camel.quarkus.component.micrometer.observability.it;
 
-import jakarta.enterprise.context.ApplicationScoped;
-import org.apache.camel.builder.RouteBuilder;
+import java.util.Map;
 
-@ApplicationScoped
-public class MicrometerObservabilityRoutes extends RouteBuilder {
+import io.quarkus.test.junit.QuarkusTestProfile;
 
+public class TraceCustomIdOnlyTestProfile implements QuarkusTestProfile {
     @Override
-    public void configure() throws Exception {
-        from("direct:traced")
-                .routeId("traced-route")
-                .setBody(constant("traced-response"));
-
-        // This route is excluded from tracing via 
quarkus.camel.micrometer-observability.exclude-patterns
-        from("direct:excluded")
-                .routeId("excluded-route")
-                .setBody(constant("excluded-response"));
+    public Map<String, String> getConfigOverrides() {
+        return Map.of(
+                "quarkus.camel.micrometer-observability.trace-custom-id-only", 
"true",
+                "quarkus.camel.micrometer-observability.include-patterns", "",
+                
"quarkus.camel.micrometer-observability.disable-core-processors", "false");
     }
 }

Reply via email to