timeAsyncMethod.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * decaffeinate suggestions:
  3. * DS101: Remove unnecessary use of Array.from
  4. * DS102: Remove unnecessary code created because of implicit returns
  5. * DS201: Simplify complex destructure assignments
  6. * DS207: Consider shorter variations of null checks
  7. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  8. */
  9. module.exports = function (obj, methodName, prefix, logger) {
  10. let modifedMethodName
  11. const metrics = require('./index')
  12. if (typeof obj[methodName] !== 'function') {
  13. throw new Error(
  14. `[Metrics] expected object property '${methodName}' to be a function`
  15. )
  16. }
  17. const key = `${prefix}.${methodName}`
  18. const realMethod = obj[methodName]
  19. const splitPrefix = prefix.split('.')
  20. const startPrefix = splitPrefix[0]
  21. if (splitPrefix[1] != null) {
  22. modifedMethodName = `${splitPrefix[1]}_${methodName}`
  23. } else {
  24. modifedMethodName = methodName
  25. }
  26. return (obj[methodName] = function (...originalArgs) {
  27. const adjustedLength = Math.max(originalArgs.length, 1)
  28. const firstArgs = originalArgs.slice(0, adjustedLength - 1)
  29. const callback = originalArgs[adjustedLength - 1]
  30. if (callback == null || typeof callback !== 'function') {
  31. if (logger != null) {
  32. logger.debug(
  33. `[Metrics] expected wrapped method '${methodName}' to be invoked with a callback`
  34. )
  35. }
  36. return realMethod.apply(this, originalArgs)
  37. }
  38. const timer = new metrics.Timer(startPrefix, 1, {
  39. method: modifedMethodName,
  40. })
  41. return realMethod.call(
  42. this,
  43. ...Array.from(firstArgs),
  44. function (...callbackArgs) {
  45. const elapsedTime = timer.done()
  46. const possibleError = callbackArgs[0]
  47. if (possibleError != null) {
  48. metrics.inc(`${startPrefix}_result`, 1, {
  49. status: 'failed',
  50. method: modifedMethodName,
  51. })
  52. } else {
  53. metrics.inc(`${startPrefix}_result`, 1, {
  54. status: 'success',
  55. method: modifedMethodName,
  56. })
  57. }
  58. if (logger != null) {
  59. const loggableArgs = {}
  60. try {
  61. for (let idx = 0; idx < firstArgs.length; idx++) {
  62. const arg = firstArgs[idx]
  63. if (arg.toString().match(/^[0-9a-f]{24}$/)) {
  64. loggableArgs[`${idx}`] = arg
  65. }
  66. }
  67. } catch (error) {}
  68. logger.debug(
  69. { key, args: loggableArgs, elapsedTime },
  70. '[Metrics] timed async method call'
  71. )
  72. }
  73. return callback.apply(this, callbackArgs)
  74. }
  75. )
  76. })
  77. }