Source: middleware/logging.js

const { createLogger, transports, format } = require('winston');

// Function to cereate a Winston logger instance
const logger = createLogger({
    level: 'info',
    // Defines log format with timestamp and simple format
    format: format.combine(
        format.timestamp(),
        format.simple()
    ),
    // Specifies transports for logging, in this case, it will be Console transport
    transports: [
        new transports.Console()
    ]
});


/**
 * Middleware function to log information about incoming requests and responses.
 * @param {object} req - The request object.
 * @param {object} res - The response object.
 * @param {function} next - The next middleware function in the stack.
 */
function requestLogger(req, res, next) {
    const timestamp = new Date().toISOString();
    const { method, url, ip } = req;

    // Log the incoming request
    const requestLogMessage = `[${timestamp}] ${method} ${url} - IP: ${ip}`;
    logger.info(requestLogMessage);

    // Store reference to original response.send function
    const originalSend = res.send;

    // Override response.send to log the response
    res.send = function(body) {
        // Log the response
        const responseLogMessage = `[${timestamp}] Response sent for ${method} ${url} - IP: ${ip} - Status: ${res.statusCode}`;
        logger.info(responseLogMessage);

        // Call the original response.send function
        originalSend.call(this, body);
    };

    // Handle errors
    res.on('finish', () => {
        // Log any errors
        if (res.statusCode >= 400) {
            const errorLogMessage = `[${timestamp}] Error response for ${method} ${url} - IP: ${ip} - Status: ${res.statusCode}`;
            logger.error(errorLogMessage);
        }
    });

    next();
}

module.exports = requestLogger;