eventLoopMetrics.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const metrics_1 = require("../services/metrics");
  4. const serviceManager_1 = require("../serviceManager");
  5. const Debug = require("debug");
  6. const histogram_1 = require("../utils/metrics/histogram");
  7. class EventLoopMetricOption {
  8. }
  9. exports.EventLoopMetricOption = EventLoopMetricOption;
  10. const defaultOptions = {
  11. eventLoopActive: true,
  12. eventLoopDelay: true
  13. };
  14. class EventLoopHandlesRequestsMetric {
  15. constructor() {
  16. this.logger = Debug('axm:features:metrics:eventloop');
  17. this.delayLoopInterval = 1000;
  18. }
  19. init(config) {
  20. if (config === false)
  21. return;
  22. if (config === undefined) {
  23. config = defaultOptions;
  24. }
  25. if (config === true) {
  26. config = defaultOptions;
  27. }
  28. this.metricService = serviceManager_1.ServiceManager.get('metrics');
  29. if (this.metricService === undefined)
  30. return this.logger('Failed to load metric service');
  31. this.logger('init');
  32. if (typeof process._getActiveRequests === 'function' && config.eventLoopActive === true) {
  33. const requestMetric = this.metricService.metric({
  34. name: 'Active requests',
  35. id: 'internal/libuv/requests',
  36. historic: true
  37. });
  38. this.requestTimer = setInterval(_ => {
  39. requestMetric.set(process._getActiveRequests().length);
  40. }, 1000);
  41. this.requestTimer.unref();
  42. }
  43. if (typeof process._getActiveHandles === 'function' && config.eventLoopActive === true) {
  44. const handleMetric = this.metricService.metric({
  45. name: 'Active handles',
  46. id: 'internal/libuv/handles',
  47. historic: true
  48. });
  49. this.handleTimer = setInterval(_ => {
  50. handleMetric.set(process._getActiveHandles().length);
  51. }, 1000);
  52. this.handleTimer.unref();
  53. }
  54. if (config.eventLoopDelay === false)
  55. return;
  56. const histogram = new histogram_1.default();
  57. const uvLatencyp50 = {
  58. name: 'Event Loop Latency',
  59. id: 'internal/libuv/latency/p50',
  60. type: metrics_1.MetricType.histogram,
  61. historic: true,
  62. implementation: histogram,
  63. handler: function () {
  64. const percentiles = this.implementation.percentiles([0.5]);
  65. if (percentiles[0.5] === null)
  66. return null;
  67. return percentiles[0.5].toFixed(2);
  68. },
  69. unit: 'ms'
  70. };
  71. const uvLatencyp95 = {
  72. name: 'Event Loop Latency p95',
  73. id: 'internal/libuv/latency/p95',
  74. type: metrics_1.MetricType.histogram,
  75. historic: true,
  76. implementation: histogram,
  77. handler: function () {
  78. const percentiles = this.implementation.percentiles([0.95]);
  79. if (percentiles[0.95] === null)
  80. return null;
  81. return percentiles[0.95].toFixed(2);
  82. },
  83. unit: 'ms'
  84. };
  85. this.metricService.registerMetric(uvLatencyp50);
  86. this.metricService.registerMetric(uvLatencyp95);
  87. this.runtimeStatsService = serviceManager_1.ServiceManager.get('runtimeStats');
  88. if (this.runtimeStatsService === undefined) {
  89. this.logger('runtimeStats module not found, fallbacking into pure js method');
  90. let oldTime = process.hrtime();
  91. this.delayTimer = setInterval(() => {
  92. const newTime = process.hrtime();
  93. const delay = (newTime[0] - oldTime[0]) * 1e3 + (newTime[1] - oldTime[1]) / 1e6 - this.delayLoopInterval;
  94. oldTime = newTime;
  95. histogram.update(delay);
  96. }, this.delayLoopInterval);
  97. this.delayTimer.unref();
  98. }
  99. else {
  100. this.logger('using runtimeStats module as data source for event loop latency');
  101. this.handle = (stats) => {
  102. if (typeof stats !== 'object' || !Array.isArray(stats.ticks))
  103. return;
  104. stats.ticks.forEach((tick) => {
  105. histogram.update(tick);
  106. });
  107. };
  108. this.runtimeStatsService.on('data', this.handle);
  109. }
  110. }
  111. destroy() {
  112. if (this.requestTimer !== undefined) {
  113. clearInterval(this.requestTimer);
  114. }
  115. if (this.handleTimer !== undefined) {
  116. clearInterval(this.handleTimer);
  117. }
  118. if (this.delayTimer !== undefined) {
  119. clearInterval(this.delayTimer);
  120. }
  121. if (this.runtimeStatsService !== undefined) {
  122. this.runtimeStatsService.removeListener('data', this.handle);
  123. }
  124. this.logger('destroy');
  125. }
  126. }
  127. exports.default = EventLoopHandlesRequestsMetric;
  128. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRMb29wTWV0cmljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tZXRyaWNzL2V2ZW50TG9vcE1ldHJpY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWSxDQUFBOztBQUVaLGlEQUErRTtBQUMvRSxzREFBa0Q7QUFDbEQsK0JBQThCO0FBRTlCLDBEQUFrRDtBQUdsRCxNQUFhLHFCQUFxQjtDQVdqQztBQVhELHNEQVdDO0FBRUQsTUFBTSxjQUFjLEdBQTBCO0lBQzVDLGVBQWUsRUFBRSxJQUFJO0lBQ3JCLGNBQWMsRUFBRSxJQUFJO0NBQ3JCLENBQUE7QUFFRCxNQUFxQiw4QkFBOEI7SUFBbkQ7UUFHVSxXQUFNLEdBQVEsS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUE7UUFJckQsc0JBQWlCLEdBQVcsSUFBSSxDQUFBO0lBaUgxQyxDQUFDO0lBN0dDLElBQUksQ0FBRSxNQUF3QztRQUM1QyxJQUFJLE1BQU0sS0FBSyxLQUFLO1lBQUUsT0FBTTtRQUM1QixJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUU7WUFDeEIsTUFBTSxHQUFHLGNBQWMsQ0FBQTtTQUN4QjtRQUNELElBQUksTUFBTSxLQUFLLElBQUksRUFBRTtZQUNuQixNQUFNLEdBQUcsY0FBYyxDQUFBO1NBQ3hCO1FBQ0QsSUFBSSxDQUFDLGFBQWEsR0FBRywrQkFBYyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUNsRCxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQywrQkFBK0IsQ0FBQyxDQUFBO1FBRXpGLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDbkIsSUFBSSxPQUFRLE9BQWUsQ0FBQyxrQkFBa0IsS0FBSyxVQUFVLElBQUksTUFBTSxDQUFDLGVBQWUsS0FBSyxJQUFJLEVBQUU7WUFDaEcsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLGFBQWEs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