feat(observability): add structured request logs with request-id middleware

This commit is contained in:
nav
2026-05-12 12:35:23 +00:00
parent 07d8b20f57
commit b7c9e34738
9 changed files with 245 additions and 1 deletions

View File

@@ -0,0 +1,30 @@
import { randomUUID } from 'crypto';
import { NextFunction, Request, Response } from 'express';
type ReqWithId = Request & { requestId?: string };
export function requestContextMiddleware(req: ReqWithId, res: Response, next: NextFunction): void {
const headerId = req.headers['x-request-id'];
const requestId =
(Array.isArray(headerId) ? headerId[0] : headerId) || randomUUID();
req.requestId = requestId;
res.setHeader('x-request-id', requestId);
const startedAt = Date.now();
res.on('finish', () => {
const log = {
level: 'info',
service: 'center',
requestId,
method: req.method,
path: req.originalUrl,
statusCode: res.statusCode,
durationMs: Date.now() - startedAt,
timestamp: new Date().toISOString(),
};
console.log(JSON.stringify(log));
});
next();
}

View File

@@ -3,6 +3,7 @@ import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { requestContextMiddleware } from './common/request-context.middleware';
function requireEnv(name: string): string {
const value = process.env[name];
@@ -28,6 +29,7 @@ async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('api');
app.use(requestContextMiddleware);
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,