Skip to content

Quick Start

import {
ConsoleTransport,
createNamedLogger,
PrettyFormatter,
Severity,
} from "@jamx/logger";
const logger = createNamedLogger({
name: "worker",
minSeverity: Severity.Info,
transport: new ConsoleTransport(new PrettyFormatter()),
});
logger.info("Job started");
logger.warn("Job retry scheduled", { attempt: 2 });

message is always a string. Put structured data in meta.

import {
ConsoleTransport,
createLogger,
JsonFormatter,
Severity,
} from "@jamx/logger";
const logger = createLogger({
minSeverity: Severity.Debug,
meta: { service: "payments" },
transport: new ConsoleTransport(new JsonFormatter()),
});
logger.log(Severity.Info, "charge succeeded", {
chargeId: "ch_42",
amount: 5000,
currency: "USD",
});

To write JSON logs to Node’s diagnostic stream while keeping the transport itself runtime-neutral, use WriterTransport:

import { JsonFormatter, WriterTransport } from "@jamx/logger";
const transport = new WriterTransport(
new JsonFormatter(),
(output) => process.stderr.write(`${output}\n`),
);

Use createChildLogger when a workflow needs extra inherited metadata.

import { createChildLogger } from "@jamx/logger";
const requestLogger = createChildLogger(logger, {
requestId: "req_42",
});
requestLogger.info("Request completed", { durationMs: 18 });

If the configured transport buffers or asynchronously delivers records, close it before the process exits:

logger.info("Worker shutting down");
await logger.transport.close?.();

Synchronous transports do not need to implement lifecycle methods. See Transports And Formatters for the full contract.