Structured logging with child contexts that outputs JSON in production and pretty-printed text in development.
npm install @prsm/logimportlogfrom'@prsm/log'log.info('server started',{port: 8080})log.warn('slow query',{ms: 1200})log.error(newError('connection refused'))Pretty output (dev):
[14:32:01] INFO server started
port: 8080
[14:32:01] WARN slow query
ms: 1200
[14:32:01] ERROR connection refused
err: connection refused
JSON output (production):
{"level":"info","msg":"server started","port":8080,"ts":1710782521000}Create loggers that carry context through a request, job, or connection.
constconn=log.child({connId: 'abc-123'})conn.info('command received',{cmd: 'submit'})// [14:32:01] INFO command received// connId: abc-123// cmd: submitconstdb=conn.child({db: 'postgres'})db.info('query',{ms: 12})// [14:32:01] INFO query// connId: c1// db: postgres// ms: 12Context accumulates. Every log from a child includes all parent context.
log.configure({level: 'debug',// debug | info | warn | error | nonepretty: false,// true for human-readable, false for JSON})Defaults: level info, pretty when NODE_ENV !== 'production'.
Pass context through queue jobs, realtime commands, workflows.
server.exposeCommand('submit',async(ctx)=>{constl=log.child({connId: ctx.connection.id})l.info('received')awaitqueue.push({ ...ctx.payload,_trace: l.context})})queue.process(async(payload,task)=>{constl=log.child({taskId: task.uuid, ...payload._trace})l.info('processing')// every log line carries connId + taskId})MIT