Skip to content

CAMEL-24003: Enrich activity data with span decorator attributes#24606

Open
davsclaus wants to merge 1 commit into
mainfrom
feature/CAMEL-24003-activity-span-enrichment
Open

CAMEL-24003: Enrich activity data with span decorator attributes#24606
davsclaus wants to merge 1 commit into
mainfrom
feature/CAMEL-24003-activity-span-enrichment

Conversation

@davsclaus

Copy link
Copy Markdown
Contributor

Summary

When camel-telemetry (via --observe or 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

  • RecordingSpan wraps the real Span and intercepts setTag()/setComponent() calls, building a Map<String, String> alongside the real span. The decorator code is completely unaware of the wrapping.
  • Tracer.beginEventSpan() conditionally wraps the span only when BacklogTracer.isActivityEnabled() returns true and the operation is EVENT_SENT. After the decorator runs, the recorded tags are stored on the exchange via ExchangePropertyKey.ACTIVITY_SPAN_TAGS.
  • Zero overhead in production: the activityEnabled boolean defaults to false. No wrapping, no Map allocation, no exchange property writes unless activity is explicitly enabled.

What the BacklogTracer side picks up (in PR #24598)

The onExchangeSent handler reads ExchangePropertyKey.ACTIVITY_SPAN_TAGS from the exchange and attaches it to each EndpointSend entry. This gives activity data rich details like:

  • Kafka: topic, partition, offset, key
  • SQL: db.system, db.statement
  • HTTP: method, status code
  • General: server.address, server.protocol

Files changed

  • Exchange.java — new ACTIVITY_SPAN_TAGS constant
  • ExchangePropertyKey.java — enum entry + switch case
  • BacklogTracer.javaisActivityEnabled() default method
  • RecordingSpan.java (new) — Span wrapper that records setTag calls
  • Tracer.java — conditional wrapping in beginEventSpan(), activity detection in doInit()

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

  • Verify camel-telemetry module compiles
  • Verify camel-api module compiles
  • Integration test: with --observe and activity enabled, confirm span tags appear on exchange property after ExchangeSentEvent
  • Verify no span wrapping occurs when activity is disabled (production path)

Claude Code on behalf of davsclaus

@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

… camel-telemetry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
@davsclaus davsclaus force-pushed the feature/CAMEL-24003-activity-span-enrichment branch from 684b49d to 7f850b2 Compare July 11, 2026 21:55
@davsclaus davsclaus marked this pull request as ready for review July 11, 2026 21:55

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_TAGS constant with proper @since 4.22 Javadoc ✓
  • ExchangePropertyKey.ACTIVITY_SPAN_TAGS enum entry with switch case ✓
  • BacklogTracer.isActivityEnabled() default method returning false — 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants