RequestLogger.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. const logger = require('logger-sharelatex')
  2. const metrics = require('metrics-sharelatex')
  3. class RequestLogger {
  4. constructor() {
  5. this._logInfo = {}
  6. this._logMessage = 'http request'
  7. }
  8. addFields(fields) {
  9. Object.assign(this._logInfo, fields)
  10. }
  11. setMessage(message) {
  12. this._logMessage = message
  13. }
  14. static attach(app) {
  15. app.use(RequestLogger.middleware)
  16. app.use(RequestLogger.errorHandler)
  17. }
  18. static errorHandler(err, req, res, next) {
  19. this._logInfo.error = err
  20. res
  21. .send(err.message)
  22. .status(500)
  23. .end()
  24. }
  25. static middleware(req, res, next) {
  26. const startTime = new Date()
  27. req.requestLogger = new RequestLogger()
  28. // override the 'end' method to log and record metrics
  29. const end = res.end
  30. res.end = function() {
  31. // apply the standard request 'end' method before logging and metrics
  32. end.apply(this, arguments)
  33. const responseTime = new Date() - startTime
  34. const routePath = req.route && req.route.path.toString()
  35. if (routePath) {
  36. metrics.timing('http_request', responseTime, null, {
  37. method: req.method,
  38. status_code: res.statusCode,
  39. path: routePath
  40. .replace(/\//g, '_')
  41. .replace(/:/g, '')
  42. .slice(1)
  43. })
  44. }
  45. const level = res.statusCode >= 500 ? 'err' : 'log'
  46. logger[level](
  47. {
  48. req: {
  49. url: req.originalUrl || req.url,
  50. route: routePath,
  51. method: req.method,
  52. referrer: req.headers.referer || req.headers.referrer,
  53. 'remote-addr':
  54. req.ip ||
  55. (req.socket && req.socket.remoteAddress) ||
  56. (req.socket &&
  57. req.socket.socket &&
  58. req.socket.socket.remoteAddress),
  59. 'user-agent': req.headers['user-agent'],
  60. 'content-length': req.headers['content-length']
  61. },
  62. res: {
  63. 'content-length': res._headers['content-length'],
  64. statusCode: res.statusCode,
  65. 'response-time': responseTime
  66. },
  67. info: req.requestLogger._logInfo
  68. },
  69. req.requestLogger._logMessage
  70. )
  71. }
  72. next()
  73. }
  74. }
  75. module.exports = RequestLogger