--- title: Logging description: Structured logging that works everywhere the code runs. type: reference --- # Logging ```ts import { log } from '@kreogen/observability/log'; log.info('Subscription created', { userId, plan }); log.warn('Retrying webhook', { attempt }); log.error('Payment failed', { customerId, reason }); ``` Four levels — `debug`, `info`, `warn`, `error` — each taking a message and an optional object of structured fields. ## Output In development, output is human-readable. In production it is one JSON object per line: ```json {"level":"info","time":"2026-01-01T12:00:00.000Z","message":"Subscription created","userId":"usr_123","plan":"pro"} ``` That shape is deliberate. Containers hand stdout straight to whatever collector the platform runs — Loki, Vector, CloudWatch — so JSON on stdout is already the transport. A logging library with its own transport would add a hop that nothing reads. ## Why there is no logging dependency The logger is dependency-free because `parseError` uses it, and `parseError` runs in server components, route handlers and the browser alike. Anything this module imports is traced into client bundles, so a Node-only logging library would either bloat them or fail outright. If a project needs richer server-side logging, add it in server-only code rather than here. ## What to log Log decisions and outcomes, not control flow. A useful line answers "what happened, to whom, and why" without needing the surrounding code. Never log secrets, tokens, passwords or full request bodies. Structured fields make redaction the default: log an identifier rather than an object. --- For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md) For an index of all available documentation, see [/llms.txt](/llms.txt)