feat(freight-api): enrich canonical request log line

Emit the request line as raw JSON on stdout (level/time/logger as fields)
instead of through Nest's console logger, whose prefix made it unparsable.

Collect data points via logCtx at the flow chokepoints: BaseRepository
writes (status changes, creates, deletes), invoice transitions, payment
intent lifecycle + outbound payment-service calls, booking/contract entry
state, review-note reasons, signatures and OTP verify outcomes.
This commit is contained in:
Nathnael
2026-08-12 09:31:31 +00:00
parent 879f0b890d
commit bd9f7f354a
11 changed files with 295 additions and 14 deletions

View File

@@ -59,7 +59,6 @@ const userId = (req: LoggedRequest): string | undefined => {
@Injectable()
export class RequestLogMiddleware implements NestMiddleware {
private readonly logger = new Logger("HTTP");
private readonly canonical = new Logger("request");
use(req: LoggedRequest, res: LoggedResponse, next: () => void): void {
const start = Date.now();
@@ -90,6 +89,12 @@ export class RequestLogMiddleware implements NestMiddleware {
const line = {
...ctx,
// Fields the Nest console prefix used to carry. They are IN the JSON
// now because this line is written raw (see below) — a log shipper
// needs level and time as parsable fields, not as console decoration.
time: new Date().toISOString(),
level: status >= 500 ? "error" : status >= 400 ? "warn" : "info",
logger: "request",
type: "http_request",
requestId,
method: req.method,
@@ -113,6 +118,9 @@ export class RequestLogMiddleware implements NestMiddleware {
json = JSON.stringify(line);
} catch {
json = JSON.stringify({
time: line.time,
level: line.level,
logger: "request",
type: "http_request",
requestId,
method: req.method,
@@ -123,9 +131,11 @@ export class RequestLogMiddleware implements NestMiddleware {
});
}
if (status >= 500) this.canonical.error(json);
else if (status >= 400) this.canonical.warn(json);
else this.canonical.log(json);
// Written raw, NOT through Nest's Logger: the console logger wraps every
// message in "[Nest] pid - date LEVEL [ctx] …", which makes the line
// un-parsable as JSON. Same destination the Nest logger writes to
// (stdout, stderr for errors) — only the decoration is dropped.
(status >= 500 ? process.stderr : process.stdout).write(`${json}\n`);
};
res.on("finish", emit);