-
Notifications
You must be signed in to change notification settings - Fork 0
Structured Logging
Source of truth:
docs/logging.md· ADR:ADR-0024
A sink contract, not a logging product: Lugas emits structured, scalar-only entries to a pluggable sink — the entire adaptation surface for Pino, OpenTelemetry-aware loggers, or anything else. No logging dependency enters the package.
import { defineApp } from "lugas";
defineApp({
logging: {
level: "info", // "debug" | "info" | "warn" | "error" (default "info")
access: true, // per-request access entry (default false)
requestIds: true, // UUID per request, x-request-id header, logged (default false)
sink: (entry) => {
// e.g. pino[entry.level](entry.fields, entry.message);
console.log(JSON.stringify(entry));
},
},
routes: { /* ... */ },
});type LugasLogEntry = {
time: string; // ISO-8601 UTC
level: "debug" | "info" | "warn" | "error";
message: string;
fields?: Record<string, string | number | boolean | null>;
};Redaction by construction: the field schema is scalar and closed. Lugas never logs request bodies, query strings, headers, cookies, authorization values, or client IPs — there is no API through which the framework's entries could carry them. (Logging inside your own handlers is your sink, your responsibility.)
With access: true, one info-level entry per completed request:
| Field | Example |
|---|---|
method |
"GET" |
path |
"/users/123" |
route |
"GET /users/:id" — matched pattern, or "-" for unmatched/fallback |
status |
200 |
durationMs |
1.42 |
requestId |
UUID, when requestIds: true
|
Coverage: route() descriptors, native function handlers, 404/fallback responses, held 503s from lifecycle startup failures, and redacted 500s — all with honest end-to-end durations. CORS preflights are not access-logged (handled at the outer boundary before any application wrapper).
- Absent
logging, behavior is byte-identical: no output, no headers. -
requestIdsechoescrypto.randomUUID()as thex-request-idresponse header and correlates it into the access entry. - Invalid configuration fails closed with
LUGAS_LOG_001(allowed keys:level,sink,requestIds,access). - Access logging defaults off — an explicit production policy, not an environment-dependent default.
Pinned by tests/logging/; evidence in docs/reports/issues/M8-003.md.
LugasJS Wiki
Server facilities
- CORS
- Server-Sent Events
- Structured Logging
- OpenAPI and Scalar
- Drizzle
- Service Lifecycle
- Assets and Body Limits
Reference
Repository