A practical, opinionated guide to writing structured logs that are queryable, filterable, and consistent. Covers naming log events with a domain.action pattern using snake_case, using flat dot-notation attribute keys instead of nested objects, keeping attribute values as primitives, and enforcing these conventions with a custom ESLint plugin. Also discusses using logging library context scopes for shared attributes, avoiding timing data in logs (use spans instead), and leveraging AI agents to audit log schemas beyond what linters can catch.
Table of contents
The shape of a structured logEnforce log patterns with ESLintUse stable event namesUse scoped attribute keysKeep event attributes inlineUse primitive attribute valuesKeeping consistent with a linterA good log answers the next question4K Impressions