import type { Request, Response, NextFunction } from 'express'; import { runWithTrace, newTraceId, traceIdFromTraceparent } from './trace-context'; import { logJson } from './logger'; /** * Express middleware (P9 observability). Derives a trace id per request (inbound * x-trace-id → traceparent → generated), echoes it as `x-trace-id` on the response, * runs the whole request inside the trace context, and logs a structured line when * the response finishes (method, path, status, ms). Wired via app.use() in main.ts. */ export function traceMiddleware(req: Request, res: Response, next: NextFunction): void { const headerTrace = (req.headers['x-trace-id'] as string | undefined)?.trim(); const traceId = headerTrace || traceIdFromTraceparent(req.headers['traceparent'] as string | undefined) || newTraceId(); res.setHeader('x-trace-id', traceId); const startedAt = Date.now(); runWithTrace(traceId, () => { res.on('finish', () => { logJson('info', 'http.request', { method: req.method, path: (req.originalUrl || req.url || '').split('?')[0], status: res.statusCode, ms: Date.now() - startedAt, }); }); next(); }); }