Search docs
Jump to a page or section

Canonical Log Lines

Emit one wide, structured log record per request, so each request can be queried as a single event.

Open in Claude

Emit one structured log record per request (or job, or loop) per service, at the end of the request, instead of many log lines along the way.

  • Put everything on it: user and tenant IDs, plan, feature flags, cart size, cache hits, the outcome, and the error type and message. High-cardinality fields are fine.
  • Put environment context on the OpenTelemetry resource, such as service.version, deployment.environment.name, and the commit, not on each record.
  • Send it through the OpenTelemetry Logs API or a logging bridge while the request's span is active, so the record carries its trace and span IDs.
  • Use one logger, configured at startup and used everywhere. Two levels are enough: info and error.
  • Don't log unstructured strings, and use the same field names across services.

Adapted from Stripe's Canonical Log Lines and Boris Tane's logging-best-practices (MIT).

Next steps