liveBook · Manning

Correlation id

As explained in Go by Example

A trace ID is an identifier that correlates processing and log records belonging to the same request or distributed operation.

A trace ID is a request-scoped identifier that links log records produced while handling the same HTTP request. It turns scattered failures, paths, and status records into a correlated trail, so troubleshooting does not depend on guessing which entries belong together. section 9.5

In Go, carry the ID in context.Context. Generate it at the HTTP boundary, attach it with context.WithValue, and pass the resulting request context downstream. Context values form a parent chain: adding an ID returns a new Context while retaining values from its parent. section 9.5.1 section 9.5.2

Figure 9.5 Injecting and propagating trace IDs through Request.Context
A diagram of a computer code

Description automatically generated with medium confidence

The request flow shows middleware injecting one ID into Request.Context and making it available to every downstream handler that receives that request. section 9.5

Keep the trace-ID package small and defensive:

  • Use package-local, unexported key types for Context storage. The same key must be used to retrieve the value, and an unexported type prevents collisions with keys from other packages. section 9.5.1
  • Return the ID together with a success boolean after asserting the value to string, because Context.Value returns any. section 9.5.1
  • Add an ID only when the incoming request lacks one, so earlier middleware can supply it without being overwritten. section 9.5.2
  • Treat the value as peripheral metadata, not as a control-flow dependency; Context values are type-unsafe and misuse can create subtle bugs. section 9.5.2

Logging code should not need to extract and attach the ID at every call site. Wrap an existing slog.Handler with a handler that reads the ID from the logging Context, clones the slog.Record, adds a trace_id attribute when present, and delegates rendering to the wrapped handler. section 9.5.3 section 9.5.4

Listing 9.12 LogHandler (link/kit/traceid/slog.go)
package traceid

import (
    "context"
    "log/slog"
)

// LogKey is the key used to store the trace ID in the log record.
const LogKey = "trace_id"

// LogHandler adds trace IDs from [context.Context] to [slog.Record].
type LogHandler struct {
    slog.Handler #1
    LogKey string // LogKey for the trace ID (Default: [LogKey])
}

// NewLogHandler returns a new [LogHandler].
func NewLogHandler(next slog.Handler) *LogHandler {
    return &LogHandler{
        Handler: next, #2
        LogKey:  LogKey,
    }
}

// Handle may add a [slog.Attr] to a [slog.Record].
func (h *LogHandler) Handle( #3
    ctx context.Context, r slog.Record,
) error {
    if id, ok := FromContext(ctx); ok { #4
        r = r.Clone() #5
        r.AddAttrs(slog.String(h.LogKey, id)) #6
    }
    return h.Handler.Handle(ctx, r) #7
}

The handler implementation demonstrates composition: embed the next slog.Handler, enrich only records whose Context contains an ID, then delegate handling. section 9.5.4

HTTP server integration

Wrap the logger's handler with LogHandler, pass that logger through application handlers, then wrap the server handler with trace-ID middleware. A request such as GET /health can then produce a log entry containing its path, method, and trace_id automatically. section 9.5.6 section 9.5.6

How Go by Example covers it

How deep it goes
Explains generation, Context storage, middleware propagation, and slog.Handler record enrichment, while deferring robust UUID generation.
Examples
Demonstrates a traceid package, HTTP middleware, LogHandler wrapper, and /health request logs carrying trace_id.
What it assumes
Introduces Context value storage and retrieval while using HTTP handlers, middleware, and type assertions.
What you can do after
Apply it via net/http middleware and log/slog handlers to emit correlated request logs automatically.
How it connects
Connects Context, HTTP middleware, slog.Handler, slog.Record, type assertions, and interface embedding.

Also explained in

Compare how 5 books explain correlation id →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go by Example. The section links point to the parts of the book it draws on.