[
https://issues.apache.org/jira/browse/CAMEL-23712?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen updated CAMEL-23712:
--------------------------------
Description:
h3. Motivation
When {{traceProcessors}} is enabled, every core EIP (log, setHeader, setBody,
convertBodyTo, etc.) generates a span. For large routes this creates massive
span explosion in tools like Grafana/Jaeger — the same problem reported in
CAMEL-23564.
The existing filters are either too coarse or leak across concerns:
* {{disableCoreProcessors=true}} kills ALL core EIP spans (too coarse)
* {{excludePatterns}} / {{includePatterns}} are shared between endpoint event
filtering and processor filtering — patterns like {{log*}} match both processor
names ({{log1-log}}) and endpoint URIs ({{log://info}})
h3. Proposal
Add a {{traceCustomIdOnly}} option (boolean, default false) that only creates
spans for processors/endpoints where the route author explicitly assigned a
custom {{.id()}}.
This mirrors the existing JMX precedent
{{ManagementAgent.onlyRegisterProcessorWithCustomId}} which uses
{{OptionalIdentifiedDefinition.hasCustomIdAssigned()}} to distinguish explicit
IDs from auto-generated ones ({{log1}}, {{setHeader2}}).
The idea is that route authors assign IDs to steps that have business meaning:
{code:java}
from("kafka:orders")
.setHeader("foo", constant("bar")) // no id → not traced
.log("processing") // no id → not traced
.bean("taxCalculator").id("calculateTax") // custom id → TRACED
.to("kafka:processed").id("sendToKafka") // custom id → TRACED
.to("direct:audit"); // no id → not traced
{code}
This avoids the need for type-based filtering — intent-based filtering is
simpler and more powerful.
h3. API changes
Add {{hasCustomIdAssigned()}} to both {{NamedNode}} and {{NamedRoute}}
interfaces in {{core/camel-api}} so the interceptors and route policies can
check without casting to model classes:
{code:java}
// NamedNode.java
default boolean hasCustomIdAssigned() {
return false;
}
// NamedRoute.java
default boolean hasCustomIdAssigned() {
return false;
}
{code}
{{OptionalIdentifiedDefinition}} (which implements {{NamedNode}}) and
{{RouteDefinition}} (which implements {{NamedRoute}}) already have this method
at the implementation level — the interface addition just makes it accessible
through the API without casting.
h3. Configuration via application.properties
The {{OpenTelemetryTracer}} class is annotated with {{@Configurer}}, so adding
a {{setTraceCustomIdOnly(boolean)}} setter to the {{Tracer}} base class will
automatically generate the property configurer during the build. This means it
will be available as:
{code:properties}
# application.properties
camel.opentelemetry2.enabled = true
camel.opentelemetry2.traceCustomIdOnly = true
{code}
No additional wiring needed — the existing auto-configuration mechanism handles
it.
h3. Documentation
Update {{components/camel-opentelemetry2/src/main/docs/opentelemetry2.adoc}}:
* Add {{traceCustomIdOnly}} to the configuration options table
* Add a new section explaining the concept: assign business-meaningful IDs to
the steps you want traced, enable {{traceCustomIdOnly}}, and only those steps
produce spans
* Include examples in both Java DSL and YAML DSL showing how to assign IDs and
the resulting span output
h3. Implementation scope
1. Add {{hasCustomIdAssigned()}} default method to {{NamedNode}} and
{{NamedRoute}} interfaces (camel-api)
2. Add {{traceCustomIdOnly}} boolean field + getter/setter to {{Tracer}} base
class (camel-telemetry)
3. Wire into {{TraceProcessorsInterceptStrategy.shouldTrace()}} — skip
processors without custom IDs
4. Wire into {{TracingEventNotifier}} / {{TracingRoutePolicy}} — skip endpoint
events for routes/endpoints without custom IDs (allows treating Camel as a
higher-level black box, skipping internal {{direct:}} / {{seda:}} wiring)
5. Property auto-configured via {{@Configurer}} as
{{camel.opentelemetry2.traceCustomIdOnly}}
6. Update opentelemetry2.adoc documentation with option, concept explanation,
and examples
7. Add tests
h3. Related
* CAMEL-23564 — baggage not visible without traceProcessors (span explosion
workaround)
* CAMEL-23709 — reduced span verbosity for endpoint-sending processors
* JMX precedent: {{JmxManagementLifecycleStrategy}} line 979 uses
{{onlyRegisterProcessorWithCustomId}}
was:
h3. Motivation
When {{traceProcessors}} is enabled, every core EIP (log, setHeader, setBody,
convertBodyTo, etc.) generates a span. For large routes this creates massive
span explosion in tools like Grafana/Jaeger — the same problem reported in
CAMEL-23564.
The existing filters are either too coarse or leak across concerns:
* {{disableCoreProcessors=true}} kills ALL core EIP spans (too coarse)
* {{excludePatterns}} / {{includePatterns}} are shared between endpoint event
filtering and processor filtering — patterns like {{log*}} match both processor
names ({{log1-log}}) and endpoint URIs ({{log://info}})
h3. Proposal
Add a {{traceCustomIdOnly}} option (boolean, default false) that only creates
spans for processors/endpoints where the route author explicitly assigned a
custom {{.id()}}.
This mirrors the existing JMX precedent
{{ManagementAgent.onlyRegisterProcessorWithCustomId}} which uses
{{OptionalIdentifiedDefinition.hasCustomIdAssigned()}} to distinguish explicit
IDs from auto-generated ones ({{log1}}, {{setHeader2}}).
The idea is that route authors assign IDs to steps that have business meaning:
{code:java}
from("kafka:orders")
.setHeader("foo", constant("bar")) // no id → not traced
.log("processing") // no id → not traced
.bean("taxCalculator").id("calculateTax") // custom id → TRACED
.to("kafka:processed").id("sendToKafka") // custom id → TRACED
.to("direct:audit"); // no id → not traced
{code}
This avoids the need for type-based filtering — intent-based filtering is
simpler and more powerful.
h3. API changes
Add {{hasCustomIdAssigned()}} to the {{NamedNode}} and {{NamedRoute}}
interfaces in {{core/camel-api}} so the interceptors can check without casting
to model classes:
{code:java}
// NamedNode.java
default boolean hasCustomIdAssigned() {
return false;
}
// NamedRoute.java
default boolean hasCustomIdAssigned() {
return false;
}
{code}
{{OptionalIdentifiedDefinition}} (which implements {{NamedNode}}) already has
this method — the interface addition just makes it accessible through the API.
h3. Implementation scope
1. Add {{hasCustomIdAssigned()}} to {{NamedNode}} and {{NamedRoute}} interfaces
2. Add {{traceCustomIdOnly}} boolean to {{Tracer}} base class (camel-telemetry)
3. Wire it into {{TraceProcessorsInterceptStrategy.shouldTrace()}} — skip
processors without custom IDs
4. Optionally wire it into {{TracingEventNotifier}} / {{TracingRoutePolicy}} —
skip endpoint events for routes/endpoints without custom IDs (allows treating
Camel as a higher-level black box, skipping internal {{direct:}} / {{seda:}}
wiring)
5. Expose as {{camel.opentelemetry2.traceCustomIdOnly}} configuration property
6. Document in the opentelemetry2 component docs
h3. Related
* CAMEL-23564 — baggage not visible without traceProcessors (span explosion
workaround)
* CAMEL-23709 — reduced span verbosity for endpoint-sending processors
* JMX precedent: {{JmxManagementLifecycleStrategy}} line 979 uses
{{onlyRegisterProcessorWithCustomId}}
> camel-telemetry - Add traceCustomIdOnly option to only trace
> processors/endpoints with custom IDs
> -------------------------------------------------------------------------------------------------
>
> Key: CAMEL-23712
> URL: https://issues.apache.org/jira/browse/CAMEL-23712
> Project: Camel
> Issue Type: New Feature
> Components: camel-opentelemetry
> Reporter: Claus Ibsen
> Priority: Major
> Labels: opentelemetry, telemetry
>
> h3. Motivation
> When {{traceProcessors}} is enabled, every core EIP (log, setHeader, setBody,
> convertBodyTo, etc.) generates a span. For large routes this creates massive
> span explosion in tools like Grafana/Jaeger — the same problem reported in
> CAMEL-23564.
> The existing filters are either too coarse or leak across concerns:
> * {{disableCoreProcessors=true}} kills ALL core EIP spans (too coarse)
> * {{excludePatterns}} / {{includePatterns}} are shared between endpoint event
> filtering and processor filtering — patterns like {{log*}} match both
> processor names ({{log1-log}}) and endpoint URIs ({{log://info}})
> h3. Proposal
> Add a {{traceCustomIdOnly}} option (boolean, default false) that only creates
> spans for processors/endpoints where the route author explicitly assigned a
> custom {{.id()}}.
> This mirrors the existing JMX precedent
> {{ManagementAgent.onlyRegisterProcessorWithCustomId}} which uses
> {{OptionalIdentifiedDefinition.hasCustomIdAssigned()}} to distinguish
> explicit IDs from auto-generated ones ({{log1}}, {{setHeader2}}).
> The idea is that route authors assign IDs to steps that have business meaning:
> {code:java}
> from("kafka:orders")
> .setHeader("foo", constant("bar")) // no id → not traced
> .log("processing") // no id → not traced
> .bean("taxCalculator").id("calculateTax") // custom id → TRACED
> .to("kafka:processed").id("sendToKafka") // custom id → TRACED
> .to("direct:audit"); // no id → not traced
> {code}
> This avoids the need for type-based filtering — intent-based filtering is
> simpler and more powerful.
> h3. API changes
> Add {{hasCustomIdAssigned()}} to both {{NamedNode}} and {{NamedRoute}}
> interfaces in {{core/camel-api}} so the interceptors and route policies can
> check without casting to model classes:
> {code:java}
> // NamedNode.java
> default boolean hasCustomIdAssigned() {
> return false;
> }
> // NamedRoute.java
> default boolean hasCustomIdAssigned() {
> return false;
> }
> {code}
> {{OptionalIdentifiedDefinition}} (which implements {{NamedNode}}) and
> {{RouteDefinition}} (which implements {{NamedRoute}}) already have this
> method at the implementation level — the interface addition just makes it
> accessible through the API without casting.
> h3. Configuration via application.properties
> The {{OpenTelemetryTracer}} class is annotated with {{@Configurer}}, so
> adding a {{setTraceCustomIdOnly(boolean)}} setter to the {{Tracer}} base
> class will automatically generate the property configurer during the build.
> This means it will be available as:
> {code:properties}
> # application.properties
> camel.opentelemetry2.enabled = true
> camel.opentelemetry2.traceCustomIdOnly = true
> {code}
> No additional wiring needed — the existing auto-configuration mechanism
> handles it.
> h3. Documentation
> Update {{components/camel-opentelemetry2/src/main/docs/opentelemetry2.adoc}}:
> * Add {{traceCustomIdOnly}} to the configuration options table
> * Add a new section explaining the concept: assign business-meaningful IDs to
> the steps you want traced, enable {{traceCustomIdOnly}}, and only those steps
> produce spans
> * Include examples in both Java DSL and YAML DSL showing how to assign IDs
> and the resulting span output
> h3. Implementation scope
> 1. Add {{hasCustomIdAssigned()}} default method to {{NamedNode}} and
> {{NamedRoute}} interfaces (camel-api)
> 2. Add {{traceCustomIdOnly}} boolean field + getter/setter to {{Tracer}} base
> class (camel-telemetry)
> 3. Wire into {{TraceProcessorsInterceptStrategy.shouldTrace()}} — skip
> processors without custom IDs
> 4. Wire into {{TracingEventNotifier}} / {{TracingRoutePolicy}} — skip
> endpoint events for routes/endpoints without custom IDs (allows treating
> Camel as a higher-level black box, skipping internal {{direct:}} / {{seda:}}
> wiring)
> 5. Property auto-configured via {{@Configurer}} as
> {{camel.opentelemetry2.traceCustomIdOnly}}
> 6. Update opentelemetry2.adoc documentation with option, concept explanation,
> and examples
> 7. Add tests
> h3. Related
> * CAMEL-23564 — baggage not visible without traceProcessors (span explosion
> workaround)
> * CAMEL-23709 — reduced span verbosity for endpoint-sending processors
> * JMX precedent: {{JmxManagementLifecycleStrategy}} line 979 uses
> {{onlyRegisterProcessorWithCustomId}}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)