structured-logging

Installation
SKILL.md

Structured logging, tracing, and error handling

Usage

Invoke bare (/structured-logging) for the full mechanism. This assumes the controller → service → repository vocabulary from the clean-architecture skill — read that first if you haven't.

What already exists — build on this, don't duplicate it

This repo already has real, working pieces of this. The job here is to close the gaps between them and make the result consistent, not to introduce a new logging stack.

  • common/compiled/node/logger.ts — the transport. A hand-rolled structured JSON logger (error/warn/info/debug), already stamping every entry with timestamp (ISO string), level, message, and service (name@version), filtered by the LOG_LEVEL env var. Set as the global logger — this document changes how it's accessed (injected, not global — see below), not what it is. Also exports loggerMiddleware, which already logs "request received" / "request completed" (with status + duration) for Express routes.
  • common/compiled/node/errors/{AppError,error.middleware,types}.ts — the error hierarchy. AppError (base: statusCode, code, details, isOperational, calls Error.captureStackTrace) plus NotFoundError/ValidationError/UnauthorizedError. errorHandler is the central Express error middleware — already wired into every real app via postRoute() (see apps/sample-api/src/app.ts) — normalizes any thrown value, logs 5xx errors with stack and requestId: req.headers['x-request-id'], and hides internals from the client in production.
  • common/compiled/node/express/requestId.ts — requestIdMiddleware and the canonical REQUEST_ID_HEADER ('x-request-id') constant. Generates one if the caller didn't send it, echoes it on the response, wired into preRoute.ts before loggerMiddleware. This closes what used to be a real gap: error.middleware.ts and db-audit.ts both already read req.headers['x-request-id'] (the latter forwards it into a Postgres session variable for audit triggers — app.session_id), but nothing generated it if the client didn't send one. Always use REQUEST_ID_HEADER, never a variant like x-correlation-id.
  • common/compiled/node/logging/context.ts — createLogger() and the ContextLogger type — the injected-logger mechanism described below. Real, typechecked, unit-tested (common/compiled/node/__test__/logging-context.test.ts), and exercised end-to-end in apps/sample-rest-app-v2.

Do not introduce a new logging library (no pino, no winston) — common/node/logger.ts already does this, and docs/NOTES.md directs using native tooling over heavy libraries.

Log levels

Installs
1
GitHub Stars
461
First Seen
Sep 28, 2026