const logger = require('../utils/logger'); const apiLogger = (req, res, next) => { const startTime = Date.now(); const reqLogger = logger.withRequestId(req.id); const requestData = { method: req.method, url: req.url, userAgent: req.get('User-Agent'), ip: req.ip, userId: req.user?.id || 'anonymous', body: logger.sanitize(req.body), params: req.params, query: req.query, headers: { 'content-type': req.get('Content-Type'), 'content-length': req.get('Content-Length'), 'referer': req.get('Referer'), } }; reqLogger.info('API Request', requestData); const originalSend = res.send; res.send = function(body) { const endTime = Date.now(); const responseTime = endTime - startTime; const responseData = { statusCode: res.statusCode, responseTime: `${responseTime}ms`, contentLength: res.get('Content-Length') || (body ? body.length : 0), method: req.method, url: req.url, userId: req.user?.id || 'anonymous' }; // Parse response body for error responses to include error details if (res.statusCode >= 400) { let errorDetails = null; if (body) { try { const parsed = typeof body === 'string' ? JSON.parse(body) : body; // Extract error message, validation errors, or full response errorDetails = { error: parsed.error || parsed.message || null, errors: parsed.errors || null, // validation errors array details: parsed.details || null }; // Remove null values Object.keys(errorDetails).forEach(key => { if (errorDetails[key] === null) delete errorDetails[key]; }); if (Object.keys(errorDetails).length > 0) { responseData.errorDetails = errorDetails; } } catch (e) { // Body is not JSON, include as string (truncated) if (typeof body === 'string' && body.length > 0) { responseData.errorDetails = { raw: body.substring(0, 500) }; } } } } if (res.statusCode >= 400 && res.statusCode < 500) { // Don't log 401s for /users/profile - these are expected auth checks if (!(res.statusCode === 401 && req.url === '/profile')) { reqLogger.warn('API Response - Client Error', responseData); } } else if (res.statusCode >= 500) { reqLogger.error('API Response - Server Error', responseData); } else { reqLogger.info('API Response - Success', responseData); } return originalSend.call(this, body); }; next(); }; module.exports = apiLogger;