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");
}
}