http.js 2.8 KB

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