Add comprehensive logging infrastructure with configuration and middleware
- Implemented centralized logging utility using Winston with daily log rotation - Added logging middleware for request and error tracking - Extended .env.example with logging configuration options - Updated app configuration to support flexible logging settings - Replaced console.log with structured logging in main application entry point - Created logging middleware to capture request details and response times
This commit is contained in:
106
src/middleware/logging.middleware.ts
Normal file
106
src/middleware/logging.middleware.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Logging Middleware
|
||||
*
|
||||
* This middleware provides request logging functionality.
|
||||
* It logs incoming requests and their responses.
|
||||
*
|
||||
* @module logging-middleware
|
||||
*/
|
||||
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { logger } from '../utils/logger.js';
|
||||
import { APP_CONFIG } from '../config/app.config.js';
|
||||
|
||||
/**
|
||||
* Interface for extended request object with timing information
|
||||
*/
|
||||
interface TimedRequest extends Request {
|
||||
startTime?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the response time in milliseconds
|
||||
* @param startTime - Start time in milliseconds
|
||||
* @returns Response time in milliseconds
|
||||
*/
|
||||
const getResponseTime = (startTime: number): number => {
|
||||
const NS_PER_SEC = 1e9; // nanoseconds per second
|
||||
const NS_TO_MS = 1e6; // nanoseconds to milliseconds
|
||||
const diff = process.hrtime();
|
||||
return (diff[0] * NS_PER_SEC + diff[1]) / NS_TO_MS - startTime;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get client IP address from request
|
||||
* @param req - Express request object
|
||||
* @returns Client IP address
|
||||
*/
|
||||
const getClientIp = (req: Request): string => {
|
||||
return (
|
||||
(req.headers['x-forwarded-for'] as string)?.split(',')[0] ||
|
||||
req.socket.remoteAddress ||
|
||||
'unknown'
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Format log message for request
|
||||
* @param req - Express request object
|
||||
* @returns Formatted log message
|
||||
*/
|
||||
const formatRequestLog = (req: TimedRequest): string => {
|
||||
return `${req.method} ${req.originalUrl} - IP: ${getClientIp(req)}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Format log message for response
|
||||
* @param req - Express request object
|
||||
* @param res - Express response object
|
||||
* @param time - Response time in milliseconds
|
||||
* @returns Formatted log message
|
||||
*/
|
||||
const formatResponseLog = (req: TimedRequest, res: Response, time: number): string => {
|
||||
return `${req.method} ${req.originalUrl} - ${res.statusCode} - ${time.toFixed(2)}ms`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Request logging middleware
|
||||
* Logs information about incoming requests and their responses
|
||||
*/
|
||||
export const requestLogger = (req: TimedRequest, res: Response, next: NextFunction): void => {
|
||||
if (!APP_CONFIG.LOGGING.LOG_REQUESTS) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// Record start time
|
||||
req.startTime = Date.now();
|
||||
|
||||
// Log request
|
||||
logger.http(formatRequestLog(req));
|
||||
|
||||
// Log response
|
||||
res.on('finish', () => {
|
||||
const responseTime = Date.now() - (req.startTime || 0);
|
||||
const logLevel = res.statusCode >= 400 ? 'warn' : 'http';
|
||||
logger[logLevel](formatResponseLog(req, res, responseTime));
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
/**
|
||||
* Error logging middleware
|
||||
* Logs errors that occur during request processing
|
||||
*/
|
||||
export const errorLogger = (err: Error, req: Request, res: Response, next: NextFunction): void => {
|
||||
logger.error(`Error processing ${req.method} ${req.originalUrl}: ${err.message}`, {
|
||||
error: err.stack,
|
||||
method: req.method,
|
||||
url: req.originalUrl,
|
||||
body: req.body,
|
||||
query: req.query,
|
||||
ip: getClientIp(req)
|
||||
});
|
||||
next(err);
|
||||
};
|
||||
Reference in New Issue
Block a user