Skip to content

Go logger: correlate lines with the active OTel span (th-de3805)#171

Open
brentrager wants to merge 1 commit into
mainfrom
fix/go-otel-span-correlation
Open

Go logger: correlate lines with the active OTel span (th-de3805)#171
brentrager wants to merge 1 commit into
mainfrom
fix/go-otel-span-correlation

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

Problem

Every Go log line's traceId was a fabricated uuid (equal to correlationId), set in resetGlobalContext/setCorrelationID. A line could never be joined to the trace that actually produced it.

Solution

  • New *Context log methodsTraceContext/DebugContext/InfoContext/WarnContext/ErrorContext/FatalContext. Each reads the active span from the passed context.Context (trace.SpanContextFromContext) and stamps its real W3C traceId + spanId onto the line. With no active span, the prior uuid behavior is untouched (correlationId stays the fabricated uuid; no spanId).
  • SetSlogHandler(h) — every line is mirrored to an installed slog.Handler carrying the call's ctx, so the @smooai/observability otelslog bridge turns a logger line into an OTLP log record correlated to the active span (→ /v1/logs). The application wires the handler in; the logger depends only on go.opentelemetry.io/otel/trace (API), never on @smooai/observability — no dependency cycle.

All log methods now route through one logWith core; the caller-frame skip was bumped by one to keep caller.* pointing at the same site as before.

Deps

go.opentelemetry.io/otel/trace v1.44.0 (API only; otel v1.44.0 indirect). otel v1.44.0 requires go 1.25.0, matching the sibling observability Go module.

Tests

go test ./...62 passed (4 new). Correlation verified by round-trip, not just compiled:

  • TestInfoContextUsesActiveSpanIDs — active span in ctx → emitted JSON traceId/spanId equal the span's ids, correlationId stays the uuid.
  • TestInfoWithoutSpanFallsBack — no span → traceId == fabricated uuid, no spanId.
  • TestSlogForwardCarriesSpanContext — reads the span back out of the forwarded ctx, proving the bridge would correlate.
  • TestSlogForwardNoHandlerIsNoOp.

go vet clean, gofmt clean.

🤖 Generated with Claude Code

Every log line's traceId was a fabricated uuid (== correlationId), so a
line could never be joined to the trace that produced it. New *Context
log methods (InfoContext/ErrorContext/…) read the active span from the
passed context and stamp its real W3C trace_id + span_id onto the line;
with no active span the prior uuid behavior is untouched.

Also adds SetSlogHandler: each line is mirrored to an installed
slog.Handler carrying the call's context, so the @smooai/observability
otelslog bridge turns a logger line into an OTLP log record correlated to
the active span (→ /v1/logs). The application wires the handler in;
logger depends only on go.opentelemetry.io/otel/trace (API), never on
@smooai/observability, so there is no dependency cycle.

Deps: go.opentelemetry.io/otel/trace v1.44.0 (API only). otel v1.44.0
requires go 1.25.0, matching the sibling observability Go module.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S2bM94GAnVjYSSv1x7HKRB
@changeset-bot

changeset-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 270bf7e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant