Skip to content

FDE-45: Add automatic log-trace correlation for slog#13

Open
prathamesh-sonpatki wants to merge 3 commits intomainfrom
log-trace
Open

FDE-45: Add automatic log-trace correlation for slog#13
prathamesh-sonpatki wants to merge 3 commits intomainfrom
log-trace

Conversation

@prathamesh-sonpatki
Copy link
Member

Summary

  • Adds instrumentation/slog package that wraps any slog.Handler to automatically inject trace_id and span_id from OTel span context into log records
  • Enables log-trace correlation without requiring users to set up an OTel LoggerProvider — logs stay in the existing pipeline (stdout/file)
  • Follows existing instrumentation package conventions (gin, echo, nethttp, etc.)

Key Design Decisions

  • Attribute injection approach over OTel Log Bridge — lightweight, no new OTel providers needed
  • r.Clone() before AddAttrs — prevents data races on the slog.Record's internal slice
  • sc.IsValid() gate — injects even for sampled-out spans (valid IDs still useful for correlation)
  • Options struct — allows custom attribute key names (e.g., dd.trace_id for Datadog)
  • No agent auto-start dependency — handler reads span context directly from ctx, works independently

API Surface

slogagent.NewHandler(inner slog.Handler, opts *Options) *Handler
slogagent.NewJSONHandler(w io.Writer, handlerOpts, opts) *Handler
slogagent.NewTextHandler(w io.Writer, handlerOpts, opts) *Handler
slogagent.SetDefault(w io.Writer, handlerOpts, opts) *slog.Logger

Test Plan

  • No span → no injection (13 tests, all passing)
  • Active span → injects 32-char trace_id + 16-char span_id
  • Sampled-out span → still injects (sc.IsValid() == true)
  • Remote span context → injects correctly
  • Custom keys via Options
  • WithAttrs/WithGroup preserve trace injection
  • Enabled delegates to inner handler
  • Nil inner panics with clear message
  • SetDefault sets global logger
  • User attributes preserved alongside trace attrs
  • golangci-lint clean

Linear: https://linear.app/last9/issue/FDE-45

🤖 Generated with Claude Code

prathamesh-sonpatki and others added 3 commits February 22, 2026 16:41
Add instrumentation/slog package that wraps any slog.Handler to
automatically inject trace_id and span_id from the OTel span context
into every log record. This bridges the log-trace correlation gap
identified in FDE-32.

Key features:
- NewHandler wraps any slog.Handler with trace attribute injection
- NewJSONHandler/NewTextHandler convenience constructors
- SetDefault sets the global slog logger with trace correlation
- Options struct for custom attribute key names
- Injects only when span context is valid (sc.IsValid())
- Correctly handles WithAttrs/WithGroup via record cloning

Linear: FDE-45

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add comprehensive documentation for the new instrumentation/slog
package including quick setup, handler wrapping, custom keys,
how it works, and the context requirement explanation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds three behavioral test cases for the slog handler:
- Concurrent Handle calls validates r.Clone() goroutine safety
- Deeply nested WithAttrs/WithGroup chains ensures trace injection
  survives arbitrary handler wrapping
- Multiple calls with different contexts proves no ID leaking

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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