2021-10-27 12:06:50 +00:00
|
|
|
const Metrics = require('./index')
|
2020-07-17 15:01:58 +00:00
|
|
|
|
2022-05-16 12:20:22 +00:00
|
|
|
function monitor(logger, level = 'debug') {
|
|
|
|
return function (req, res, next) {
|
2021-10-27 12:06:50 +00:00
|
|
|
const startTime = Date.now()
|
2022-05-16 12:20:22 +00:00
|
|
|
req.logger = new RequestLogger(logger, level)
|
2020-09-11 18:18:22 +00:00
|
|
|
const { end } = res
|
2021-12-16 09:04:32 +00:00
|
|
|
res.end = function (...args) {
|
2021-10-27 12:06:50 +00:00
|
|
|
end.apply(this, args)
|
|
|
|
const responseTimeMs = Date.now() - startTime
|
2020-09-11 18:18:22 +00:00
|
|
|
const requestSize = parseInt(req.headers['content-length'], 10)
|
2021-01-08 19:53:29 +00:00
|
|
|
const routePath = getRoutePath(req)
|
|
|
|
|
|
|
|
if (routePath != null) {
|
2020-09-11 18:18:22 +00:00
|
|
|
Metrics.timing('http_request', responseTimeMs, null, {
|
|
|
|
method: req.method,
|
|
|
|
status_code: res.statusCode,
|
2021-12-16 09:04:32 +00:00
|
|
|
path: routePath,
|
2020-09-11 18:18:22 +00:00
|
|
|
})
|
|
|
|
if (requestSize) {
|
|
|
|
Metrics.summary('http_request_size_bytes', requestSize, {
|
|
|
|
method: req.method,
|
|
|
|
status_code: res.statusCode,
|
2021-12-16 09:04:32 +00:00
|
|
|
path: routePath,
|
2020-09-11 18:18:22 +00:00
|
|
|
})
|
2020-07-17 15:01:58 +00:00
|
|
|
}
|
2020-09-11 18:18:22 +00:00
|
|
|
}
|
2022-05-16 12:20:22 +00:00
|
|
|
req.logger.addFields({ responseTimeMs })
|
|
|
|
req.logger.emit(req, res)
|
2020-09-11 18:18:22 +00:00
|
|
|
}
|
2021-01-08 19:41:50 +00:00
|
|
|
next()
|
2020-09-11 18:18:22 +00:00
|
|
|
}
|
2022-05-16 12:20:22 +00:00
|
|
|
}
|
2021-01-08 19:53:29 +00:00
|
|
|
|
|
|
|
function getRoutePath(req) {
|
|
|
|
if (req.route && req.route.path != null) {
|
|
|
|
return req.route.path
|
|
|
|
.toString()
|
|
|
|
.replace(/\//g, '_')
|
|
|
|
.replace(/:/g, '')
|
|
|
|
.slice(1)
|
|
|
|
}
|
|
|
|
if (req.swagger && req.swagger.apiPath != null) {
|
|
|
|
return req.swagger.apiPath
|
|
|
|
}
|
|
|
|
return null
|
|
|
|
}
|
2022-05-16 12:20:22 +00:00
|
|
|
|
|
|
|
class RequestLogger {
|
|
|
|
constructor(logger, level) {
|
|
|
|
this._logger = logger
|
|
|
|
this._level = level
|
|
|
|
this._info = {}
|
|
|
|
}
|
|
|
|
|
|
|
|
addFields(fields) {
|
|
|
|
Object.assign(this._info, fields)
|
|
|
|
}
|
|
|
|
|
|
|
|
setLevel(level) {
|
|
|
|
this._level = level
|
|
|
|
}
|
|
|
|
|
|
|
|
disable() {
|
|
|
|
this._disabled = true
|
|
|
|
}
|
|
|
|
|
|
|
|
emit(req, res) {
|
|
|
|
if (this._disabled) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
this.addFields({ req, res })
|
|
|
|
const url = req.originalUrl || req.url
|
|
|
|
this._logger[this._level](this._info, '%s %s', req.method, url)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports.monitor = monitor
|