import { Logger } from '@nestjs/common'; import { NormalizedErrorDto } from '../dto/normalized-error.dto'; export interface RequestLogContext { requestId: string; trackingCode?: string; provider?: string; inquiryType?: string; durationMs?: number; success?: boolean; } /** * Structured console logging for inquiry lifecycle events. * Complements MongoDB persistence in LoggingModule. */ export class RequestLogger { private readonly logger: Logger; constructor(context: string) { this.logger = new Logger(context); } logStart(ctx: RequestLogContext, message: string): void { this.logger.log(this.format(ctx, message)); } logSuccess(ctx: RequestLogContext, message: string): void { this.logger.log(this.format({ ...ctx, success: true }, message)); } logFailure(ctx: RequestLogContext, message: string, error?: unknown): void { const errorDetail = formatErrorDetail(error); const line = errorDetail ? `${this.format({ ...ctx, success: false }, message)} | error=${errorDetail}` : this.format({ ...ctx, success: false }, message); this.logger.error(line, error instanceof Error ? error.stack : undefined); } private format(ctx: RequestLogContext, message: string): string { const parts = [ `requestId=${ctx.requestId}`, ctx.trackingCode ? `trackingCode=${ctx.trackingCode}` : null, ctx.provider ? `provider=${ctx.provider}` : null, ctx.inquiryType ? `inquiryType=${ctx.inquiryType}` : null, ctx.durationMs !== undefined ? `durationMs=${ctx.durationMs}` : null, ctx.success !== undefined ? `success=${ctx.success}` : null, `msg=${message}`, ].filter(Boolean); return parts.join(' | '); } } function formatErrorDetail(error: unknown): string | undefined { if (!(error instanceof Error)) { return error !== undefined ? String(error) : undefined; } const normalized = (error as Error & { normalizedError?: NormalizedErrorDto }).normalizedError; if (normalized?.providerMessage) { const code = normalized.providerCode ? ` (${normalized.providerCode})` : ''; return `${normalized.providerMessage}${code}`; } if (normalized?.message && normalized.message !== error.message) { return normalized.message; } return error.message; }