timeAsyncMethod.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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.log(
  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(this, ...Array.from(firstArgs), function(
  42. ...callbackArgs
  43. ) {
  44. const elapsedTime = timer.done()
  45. const possibleError = callbackArgs[0]
  46. if (possibleError != null) {
  47. metrics.inc(`${startPrefix}_result`, 1, {
  48. status: 'failed',
  49. method: modifedMethodName
  50. })
  51. } else {
  52. metrics.inc(`${startPrefix}_result`, 1, {
  53. status: 'success',
  54. method: modifedMethodName
  55. })
  56. }
  57. if (logger != null) {
  58. const loggableArgs = {}
  59. try {
  60. for (let idx = 0; idx < firstArgs.length; idx++) {
  61. const arg = firstArgs[idx]
  62. if (arg.toString().match(/^[0-9a-f]{24}$/)) {
  63. loggableArgs[`${idx}`] = arg
  64. }
  65. }
  66. } catch (error) {}
  67. logger.log(
  68. { key, args: loggableArgs, elapsedTime },
  69. '[Metrics] timed async method call'
  70. )
  71. }
  72. return callback.apply(this, callbackArgs)
  73. })
  74. })
  75. }