| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { AsyncLocalStorage } from "node:async_hooks"; |
| import crypto from "node:crypto"; |
|
|
| const correlationStore = new AsyncLocalStorage(); |
|
|
| |
| |
| |
| |
| function generateCorrelationId() { |
| return crypto.randomUUID(); |
| } |
|
|
| |
| |
| |
| |
| export function getCorrelationId() { |
| return correlationStore.getStore(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| export function runWithCorrelation(correlationId, fn) { |
| const id = correlationId || generateCorrelationId(); |
| return correlationStore.run(id, fn); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function correlationMiddleware(request, next) { |
| const requestId = |
| request.headers.get("x-request-id") || |
| request.headers.get("x-correlation-id") || |
| generateCorrelationId(); |
|
|
| return runWithCorrelation(requestId, async () => { |
| const response = await next(); |
|
|
| |
| if (response && response.headers) { |
| response.headers.set("x-request-id", requestId); |
| } |
|
|
| return response; |
| }); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export function createCorrelatedLogger(baseLogger) { |
| const withCorrelation = (level, ...args) => { |
| const correlationId = getCorrelationId(); |
| if (correlationId) { |
| const meta = typeof args[args.length - 1] === "object" ? args.pop() : {}; |
| meta.correlationId = correlationId; |
| args.push(meta); |
| } |
| baseLogger[level](...args); |
| }; |
|
|
| return { |
| info: (...args) => withCorrelation("info", ...args), |
| warn: (...args) => withCorrelation("warn", ...args), |
| error: (...args) => withCorrelation("error", ...args), |
| debug: (...args) => withCorrelation("debug", ...args), |
| }; |
| } |
|
|