const logger = require('@overleaf/logger') const metrics = require('@overleaf/metrics') class RequestLogger { constructor() { this._logInfo = {} this._logMessage = 'http request' } addFields(fields) { Object.assign(this._logInfo, fields) } setMessage(message) { this._logMessage = message } static errorHandler(err, req, res, next) { req.requestLogger.addFields({ error: err }) res.status(500).send(err.message) } static middleware(req, res, next) { const startTime = new Date() req.requestLogger = new RequestLogger() // override the 'end' method to log and record metrics const end = res.end res.end = function () { // apply the standard request 'end' method before logging and metrics end.apply(this, arguments) const responseTime = new Date() - startTime const routePath = req.route && req.route.path.toString() if (routePath) { metrics.timing('http_request', responseTime, null, { method: req.method, status_code: res.statusCode, path: routePath.replace(/\//g, '_').replace(/:/g, '').slice(1), }) } const level = res.statusCode >= 500 ? 'err' : 'log' logger[level]( { req, res, responseTimeMs: responseTime, info: req.requestLogger._logInfo, }, req.requestLogger._logMessage ) } next() } } module.exports = RequestLogger