http.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * decaffeinate suggestions:
  3. * DS102: Remove unnecessary code created because of implicit returns
  4. * DS103: Rewrite code to no longer use __guard__
  5. * DS207: Consider shorter variations of null checks
  6. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  7. */
  8. const yn = require('yn')
  9. const STACKDRIVER_LOGGING = yn(process.env.STACKDRIVER_LOGGING)
  10. module.exports.monitor = logger =>
  11. function(req, res, next) {
  12. const Metrics = require('./index')
  13. const startTime = process.hrtime()
  14. const { end } = res
  15. res.end = function() {
  16. let info
  17. end.apply(this, arguments)
  18. const responseTime = process.hrtime(startTime)
  19. const responseTimeMs = Math.round(
  20. responseTime[0] * 1000 + responseTime[1] / 1000000
  21. )
  22. const requestSize = parseInt(req.headers['content-length'], 10)
  23. if ((req.route != null ? req.route.path : undefined) != null) {
  24. const routePath = req.route.path
  25. .toString()
  26. .replace(/\//g, '_')
  27. .replace(/:/g, '')
  28. .slice(1)
  29. Metrics.timing('http_request', responseTimeMs, null, {
  30. method: req.method,
  31. status_code: res.statusCode,
  32. path: routePath
  33. })
  34. if (requestSize) {
  35. Metrics.summary('http_request_size_bytes', requestSize, {
  36. method: req.method,
  37. status_code: res.statusCode,
  38. path: routePath
  39. })
  40. }
  41. }
  42. const remoteIp =
  43. req.ip ||
  44. __guard__(
  45. req.socket != null ? req.socket.socket : undefined,
  46. x => x.remoteAddress
  47. ) ||
  48. (req.socket != null ? req.socket.remoteAddress : undefined)
  49. const reqUrl = req.originalUrl || req.url
  50. const referrer = req.headers.referer || req.headers.referrer
  51. if (STACKDRIVER_LOGGING) {
  52. info = {
  53. httpRequest: {
  54. requestMethod: req.method,
  55. requestUrl: reqUrl,
  56. requestSize,
  57. status: res.statusCode,
  58. responseSize: res.getHeader('content-length'),
  59. userAgent: req.headers['user-agent'],
  60. remoteIp,
  61. referer: referrer,
  62. latency: {
  63. seconds: responseTime[0],
  64. nanos: responseTime[1]
  65. },
  66. protocol: req.protocol
  67. }
  68. }
  69. } else {
  70. info = {
  71. req: {
  72. url: reqUrl,
  73. method: req.method,
  74. referrer,
  75. 'remote-addr': remoteIp,
  76. 'user-agent': req.headers['user-agent'],
  77. 'content-length': req.headers['content-length']
  78. },
  79. res: {
  80. 'content-length': res.getHeader('content-length'),
  81. statusCode: res.statusCode
  82. },
  83. 'response-time': responseTimeMs
  84. }
  85. }
  86. return logger.info(info, '%s %s', req.method, reqUrl)
  87. }
  88. return next()
  89. }
  90. function __guard__(value, transform) {
  91. return typeof value !== 'undefined' && value !== null
  92. ? transform(value)
  93. : undefined
  94. }