@futuristic.digital/logger
v0.1.0
Published
Structured Node.js logging with redaction and OpenTelemetry trace context.
Readme
@futuristic.digital/logger
Structured server logging. Every Node package that logs should go through this logger so production emits JSON lines, secrets are redacted, and request logs can carry an OpenTelemetry trace id.
This package uses node:util and process.env. It is server-only.
What Belongs Here
createLogger/createLoggerForModuleand theLoggertype.getTraceContext()so a request-scoped child logger can attachtraceId/spanId.- Default redaction of common secret keys (
password,token,authorization, …).
What Does Not
- Domain-specific log events or message catalogs. Callers pass a message string plus a context object.
- Browser logging. Client code uses
consoleor nothing.
Keep this package independent of consuming applications.
Usage
Create one module-scoped logger from import.meta.url, then a per-request child with the active trace:
import {
createLoggerForModule,
getTraceContext
} from "@futuristic.digital/logger";
const logger = createLoggerForModule(import.meta.url);
export async function handleRequest() {
const requestLogger = logger.child(getTraceContext());
requestLogger.info("Handled request", { requestId: "request-123" });
}createLoggerForModule names the logger from the file path (extensions stripped) so log lines stay stable across bundlers. child merges extra context; withName replaces the name.
Output
- Development: colored, human-readable lines with
util.inspectcontext. - Production: one JSON object per line (
ts,level,name,msg, plus context). Level defaults todebugin development andinfoin production.
Context values are normalized to JSON (errors become { name, message, stack }, dates to ISO, cycles to "[Circular]") and then redacted. Passing redactKeys replaces the default list entirely — include every key you still need redacted. Do not log raw tokens, cookies, or request bodies that contain them — redaction is a backstop, not a license.
Testing
npm run test -w @futuristic.digital/logger runs Vitest against logger behavior via a custom sink (no console assertions). Prefer that override in unit tests so output stays deterministic.
