| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- const { logInfo, logError } = require('../utils/logger')
- const SENSITIVE_KEYS = ['password', 'token', 'otp', 'authorization']
- const sanitize = (obj) => {
- if (!obj || typeof obj !== 'object') return obj
- const clone = { ...obj }
- Object.keys(clone).forEach((key) => {
- if (SENSITIVE_KEYS.includes(key.toLowerCase())) clone[key] = '[REDACTED]'
- })
- return clone
- }
- /**
- * Logs every request (method, url, body, query, params) and its response
- * (status code, body) to application.log. Errors (4xx/5xx or thrown) are
- * logged via logError with full detail.
- */
- const middleware = (req, res, next) => {
- const start = Date.now()
- const originalJson = res.json.bind(res)
- res.json = (body) => {
- const durationMs = Date.now() - start
- const meta = {
- method: req.method,
- url: req.originalUrl,
- status: res.statusCode,
- durationMs,
- requestBody: sanitize(req.body),
- requestQuery: sanitize(req.query),
- responseBody: body,
- }
- if (res.statusCode >= 400) {
- logError('HTTP', `${req.method} ${req.originalUrl} failed`, meta)
- } else {
- logInfo('HTTP', `${req.method} ${req.originalUrl}`, meta)
- }
- return originalJson(body)
- }
- next()
- }
- middleware.logUncaughtError = (req, err) => {
- logError('HTTP_UNCAUGHT', `${req.method} ${req.originalUrl} threw`, {
- method: req.method,
- url: req.originalUrl,
- requestBody: sanitize(req.body),
- error: err.message,
- stack: err.stack,
- })
- }
- module.exports = middleware
|