Canonical Log Lines
Emit one wide, structured log record per request, so each request can be queried as a single event.
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
- Send OpenTelemetry Data - Configure an OpenTelemetry exporter or Collector