fastcheck/server/src/middleware/elkMiddleware.ts
2026-04-08 13:58:46 -04:00

143 lines
3.7 KiB
TypeScript

import { Request, Response, NextFunction } from 'express';
import ELKService from '../services/elkService';
// Estendi l'interfaccia Request per includere startTime
declare global {
namespace Express {
interface Request {
startTime?: number;
}
}
}
/**
* Middleware per il logging delle richieste HTTP con ELK
* Registra informazioni dettagliate su ogni richiesta HTTP
*/
export const elkLoggingMiddleware = (req: Request, res: Response, next: NextFunction) => {
if (process.env.ELK_ENABLED !== 'true') {
return next();
}
// Registra il tempo di inizio della richiesta
req.startTime = Date.now();
// Estrai informazioni dalla richiesta
const requestInfo = {
method: req.method,
url: req.url,
path: req.path,
query: req.query,
headers: {
'user-agent': req.get('User-Agent'),
'content-type': req.get('Content-Type'),
'authorization': req.get('Authorization') ? '[REDACTED]' : undefined,
'x-forwarded-for': req.get('X-Forwarded-For'),
'x-real-ip': req.get('X-Real-IP')
},
ip: req.ip || req.connection.remoteAddress,
timestamp: new Date().toISOString()
};
// Log della richiesta in arrivo
ELKService.info('Incoming HTTP request', {
type: 'incoming_request',
...requestInfo
});
// Intercetta la risposta per loggare anche quella
const originalSend = res.send;
res.send = function(body: any) {
const responseTime = req.startTime ? Date.now() - req.startTime : 0;
// Log della risposta usando logRequest
ELKService.logRequest({
method: req.method,
url: req.url,
statusCode: res.statusCode,
duration: responseTime,
ip: req.ip,
userAgent: req.get('User-Agent')
});
// Log di errore se status code >= 400
if (res.statusCode >= 400) {
ELKService.error(`HTTP Error ${res.statusCode}`, undefined, {
method: req.method,
url: req.url,
statusCode: res.statusCode,
responseTime,
userAgent: req.get('User-Agent'),
ip: req.ip
});
}
return originalSend.call(this, body);
};
next();
};
/**
* Middleware per il logging degli errori con ELK
* Da utilizzare come error handler globale
*/
export const elkErrorMiddleware = (err: Error, req: Request, res: Response, next: NextFunction) => {
if (process.env.ELK_ENABLED !== 'true') {
return next(err);
}
const responseTime = req.startTime ? Date.now() - req.startTime : 0;
// Log dell'errore con dettagli completi
ELKService.logSystemError(err, 'HTTP Request Error', {
method: req.method,
url: req.url,
path: req.path,
query: req.query,
headers: req.headers,
ip: req.ip,
userAgent: req.get('User-Agent'),
responseTime,
timestamp: new Date().toISOString()
});
// Passa l'errore al prossimo middleware
next(err);
};
/**
* Middleware per il logging delle metriche di performance
*/
export const elkPerformanceMiddleware = (req: Request, res: Response, next: NextFunction) => {
if (process.env.ELK_ENABLED !== 'true') {
return next();
}
const startTime = process.hrtime.bigint();
res.on('finish', () => {
const endTime = process.hrtime.bigint();
const responseTime = Number(endTime - startTime) / 1000000; // Converti in millisecondi
// Log delle metriche di performance
ELKService.info('Performance metrics', {
type: 'performance',
method: req.method,
url: req.url,
statusCode: res.statusCode,
responseTime,
memoryUsage: process.memoryUsage(),
timestamp: new Date().toISOString()
});
});
next();
};
export default {
elkLoggingMiddleware,
elkErrorMiddleware,
elkPerformanceMiddleware
};