CAMEL-24003: Enrich activity data with span decorator attributes#24606
CAMEL-24003: Enrich activity data with span decorator attributes#24606davsclaus wants to merge 1 commit into
Conversation
|
🌟 Thank you for your contribution to the Apache Camel project! 🌟 🐫 Apache Camel Committers, please review the following items:
|
… camel-telemetry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
684b49d to
7f850b2
Compare
gnodet
left a comment
There was a problem hiding this comment.
Claude Code review on behalf of @gnodet
Review: CAMEL-24003 — Enrich activity data with span decorator attributes
Clean, well-designed decorator pattern for capturing span attributes without running decorator logic twice.
RecordingSpan: Elegant wrapper — intercepts setTag()/setComponent() into a LinkedHashMap while delegating everything to the real span. Package-private visibility is correct (internal detail). Map.copyOf() for getRecordedTags() ensures immutability. Only records non-null values.
Tracer.beginEventSpan(): Wrapping is gated on two conditions — activityEnabled && op == EVENT_SENT — so there's zero overhead in production (no wrapping, no map allocation, no exchange property writes). After the decorator runs, recorded tags are stored via ExchangePropertyKey.ACTIVITY_SPAN_TAGS for the BacklogTracer consumer side (in PR #24598) to pick up.
API additions:
Exchange.ACTIVITY_SPAN_TAGSconstant with proper@since 4.22Javadoc ✓ExchangePropertyKey.ACTIVITY_SPAN_TAGSenum entry with switch case ✓BacklogTracer.isActivityEnabled()default method returningfalse— feature is inert until the implementation overrides it (clean separation with #24598) ✓
Design note: activityEnabled is captured once in doInit(), so dynamic toggling of activity tracking after context startup won't be reflected. This is fine for the intended use case (activity is configured at startup), and avoids volatile/synchronization overhead on the hot path.
LGTM — zero-overhead enrichment path with clean separation between the telemetry and consumer sides.
Summary
When
camel-telemetry(via--observeor explicit dependency) is active alongside BacklogTracer activity tracking, this PR enriches activity endpoint-send entries with component-specific span decorator attributes — without running decorator logic twice.Design
RecordingSpanwraps the realSpanand interceptssetTag()/setComponent()calls, building aMap<String, String>alongside the real span. The decorator code is completely unaware of the wrapping.Tracer.beginEventSpan()conditionally wraps the span only whenBacklogTracer.isActivityEnabled()returnstrueand the operation isEVENT_SENT. After the decorator runs, the recorded tags are stored on the exchange viaExchangePropertyKey.ACTIVITY_SPAN_TAGS.activityEnabledboolean defaults tofalse. No wrapping, no Map allocation, no exchange property writes unless activity is explicitly enabled.What the BacklogTracer side picks up (in PR #24598)
The
onExchangeSenthandler readsExchangePropertyKey.ACTIVITY_SPAN_TAGSfrom the exchange and attaches it to eachEndpointSendentry. This gives activity data rich details like:Files changed
Exchange.java— newACTIVITY_SPAN_TAGSconstantExchangePropertyKey.java— enum entry + switch caseBacklogTracer.java—isActivityEnabled()default methodRecordingSpan.java(new) — Span wrapper that records setTag callsTracer.java— conditional wrapping inbeginEventSpan(), activity detection indoInit()Dependency
This PR provides the telemetry side of the enrichment. The consumer side (BacklogTracer reading the exchange property) will be added in PR #24598.
Test plan
camel-telemetrymodule compilescamel-apimodule compiles--observeand activity enabled, confirm span tags appear on exchange property afterExchangeSentEventClaude Code on behalf of davsclaus