feat: add OTel spans to NATS request operations#25
Conversation
- Add package-level tracer and natsHeaderCarrier for trace context propagation via NATS message headers - Wrap Request() with a nats.request client span using semconv/v1.39.0 constants for all standard attributes (messaging.system, messaging.operation.type=send, destination, body size) - Define messaging.message.reply.body.size as a package-level const for the reply payload size (no semconv standard attribute exists yet) - Set span status codes.Ok on success; RecordError + codes.Error on all failure paths - Respect ctx deadline: use shorter of timeout and ctx.Deadline(); short-circuit with context.DeadlineExceeded if deadline already past - Add TestMessagingRepository_Request_CreatesSpan to verify span creation and attributes via in-memory exporter; save/restore global TracerProvider in cleanup to avoid nil-provider panics 🤖 Generated with [Claude Code](https://claude.com/claude-code) Issue: LFXV2-1743 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Trevor Bramwell <tbramwell@linuxfoundation.org>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughThis PR integrates OpenTelemetry tracing into NATS messaging by promoting the otel/trace dependency to direct, instrumenting the messaging repository's Request method with span creation and context propagation, and validating span attributes through unit tests. ChangesOpenTelemetry tracing for NATS messaging
🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
This PR instruments the NATS request/reply path in the messaging repository with OpenTelemetry client spans and injects W3C trace context into NATS message headers to enable cross-service trace propagation (e.g., into fga-sync).
Changes:
- Added an OTel client span around NATS request operations, including standard messaging semantic convention attributes and reply body size.
- Injected the current trace context into outbound NATS message headers via a
TextMapCarrieradapter. - Added a unit test using an in-memory trace exporter to verify span creation/attributes; updated
go.modto makeotel/tracea direct dependency.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| internal/infrastructure/messaging/messaging_repository.go | Adds OTel span instrumentation, context-propagation injection, and ctx deadline/timeout handling for NATS requests. |
| internal/infrastructure/messaging/messaging_repository_test.go | Adds a unit test verifying that Request creates a nats.request span with expected attributes. |
| go.mod | Promotes go.opentelemetry.io/otel/trace from indirect to direct dependency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Address review comment from copilot-pull-request-reviewer[bot]: - messaging_repository.go: flatten ctx-deadline/timeout guard so that a caller-supplied timeout <= 0 is also caught. Previously, the nested `remaining < timeout` condition was false when timeout was negative and remaining was positive, silently passing an invalid duration to RequestMsg. Now: always clamp to ctx deadline when shorter, then a single `timeout <= 0` guard short-circuits with context.DeadlineExceeded before reaching NATS. Resolves 1 review thread. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Issue: LFXV2-1743 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Trevor Bramwell <tbramwell@linuxfoundation.org>
Review Feedback AddressedCommit: f6b2f82 Changes Made
Threads Resolved1 of 1 unresolved threads addressed. |
Address review comment from copilot-pull-request-reviewer[bot]: - messaging_repository.go: use constants.ErrMsgNATSRequestFailed as the span status description instead of err.Error(). Raw NATS error strings are high-cardinality (contain server addresses, ports, etc.) and can leak internal connection details into traces. RecordError(err) already captures the full error detail; the status description should be a stable, low-cardinality string. Resolves 1 review thread. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Issue: LFXV2-1743 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Trevor Bramwell <tbramwell@linuxfoundation.org>
Review Feedback AddressedCommit: 3eb55c0 Changes Made
Threads Resolved1 of 1 unresolved threads addressed in this iteration. |
Summary
RequestMsgcalls so NATS request-reply operations are visible in Datadog APM tracessemconv/v1.39.0constants for all standard messaging attributes; defines a localconstformessaging.message.reply.body.size(no semconv equivalent yet)ctxdeadline — uses the shorter of the explicit timeout andctx.Deadline(); short-circuits withcontext.DeadlineExceededif the deadline is already pastTestMessagingRepository_Request_CreatesSpanto verify span creation and attributes via in-memory exporterChanges
internal/infrastructure/messaging/messaging_repository.go— span instrumentation,natsHeaderCarrier, ctx-deadline timeout handlinginternal/infrastructure/messaging/messaging_repository_test.go— span creation test with provider save/restorego.mod— promoteotel/tracefrom indirect to direct dependencyIssue: LFXV2-1743
🤖 Generated with Claude Code