@mdf.js/tasks
Version:
MMS - API Core - Tasks
141 lines • 5.73 kB
JavaScript
"use strict";
/**
* Copyright 2024 Mytra Control S.L. All rights reserved.
*
* Use of this source code is governed by an MIT-style license that can be found in the LICENSE file
* or at https://opensource.org/licenses/MIT.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.PollingMetricsHandler = void 0;
const tslib_1 = require("tslib");
const core_1 = require("@mdf.js/core");
const ms_1 = tslib_1.__importDefault(require("ms"));
const types_1 = require("./types");
class PollingMetricsHandler {
/**
* Create a polling stats manager
* @param componentId - Component identifier
* @param resource - Resource identifier
* @param pollingGroup - Polling group assigned to this manager
* @param cyclesOnStats - Number of cycles on stats
* @param metrics - Metrics instances
*/
constructor(componentId, resource, pollingGroup, cyclesOnStats = types_1.DEFAULT_SCAN_CYCLES_ON_STATS, metrics) {
this.componentId = componentId;
this.resource = resource;
this.pollingGroup = pollingGroup;
this.cyclesOnStats = cyclesOnStats;
this.metrics = metrics;
/** Polling stats */
this.pollingStats = { ...types_1.DEFAULT_POLLING_STATS };
/** Scan cycles duration in milliseconds */
this.scanCyclesDuration = [];
this.statsLabels = { resource: this.resource, pollingGroup: this.pollingGroup };
this.metrics.scan_cycles_on_stats.set(this.statsLabels, this.cyclesOnStats);
}
/** Set the initial point of a cycle */
initializeCycle() {
if (!this.cycleTimer) {
this.cycleTimer = process.hrtime();
this.pollingStats.scanTime = new Date();
}
}
/** Set the final point of a cycle */
finalizeCycle() {
this.checkOverruns(this.duration);
this.checkDurationStats(this.duration);
}
/**
* Get the duration of a cycle
* @returns Duration of a cycle
*/
get duration() {
if (this.cycleTimer) {
const [seconds, nanoseconds] = process.hrtime(this.cycleTimer);
this.pollingStats.lastCycleDuration = seconds * 1e3 + nanoseconds / 1e6;
this.cycleTimer = undefined;
this.metrics.scan_cycle_duration_milliseconds.observe(this.statsLabels, this.pollingStats.lastCycleDuration);
}
return this.pollingStats.lastCycleDuration;
}
/**
* Check if the cycle has overruns and update the metrics
* @param duration - Duration of the cycle
*/
checkOverruns(duration) {
this.metrics.scan_cycles_total.inc(this.statsLabels);
this.pollingStats.cycles++;
if (duration > (0, ms_1.default)(this.pollingGroup)) {
this.pollingStats.overruns++;
this.pollingStats.consecutiveOverruns++;
this.metrics.scan_overruns_total.inc(this.statsLabels);
this.metrics.scan_overruns_consecutive.inc(this.statsLabels);
}
else {
this.pollingStats.consecutiveOverruns = 0;
this.metrics.scan_overruns_consecutive.set(this.statsLabels, 0);
}
}
/**
* Check the duration stats of a cycle
* @param duration - Duration of the cycle
*/
checkDurationStats(duration) {
this.scanCyclesDuration.push(duration);
if (this.scanCyclesDuration.length > this.cyclesOnStats) {
this.scanCyclesDuration.shift();
}
if (duration > this.pollingStats.maxCycleDuration) {
this.pollingStats.maxCycleDuration = duration;
this.metrics.scan_duration_max_milliseconds.set(this.statsLabels, duration);
}
if (duration < this.pollingStats.minCycleDuration) {
this.pollingStats.minCycleDuration = duration;
this.metrics.scan_duration_min_milliseconds.set(this.statsLabels, duration);
}
this.pollingStats.averageCycleDuration =
this.scanCyclesDuration.reduce((acc, val) => acc + val, 0) / this.scanCyclesDuration.length;
this.metrics.scan_duration_avg_milliseconds.set(this.statsLabels, this.pollingStats.averageCycleDuration);
}
/**
* Add a task to the in progress stats
* @param taskId - Task identifier
*/
addTaskInProgress(taskId) {
this.metrics.task_in_progress.inc({ resource: this.resource, taskId });
}
/**
* Remove a task from the in progress stats
* @param taskId - Task identifier
* @param duration - Task duration
* @param error - Task error
*/
removeTaskInProgress(taskId, duration = 0, error) {
const labels = { resource: this.resource, taskId };
this.metrics.task_in_progress.dec(labels);
this.metrics.task_total.inc(labels);
if (error) {
this.metrics.task_errors_total.inc(labels);
}
this.metrics.task_duration_milliseconds.observe(labels, duration);
}
/** Get health check of the component */
get check() {
const overrunsStatus = this.pollingStats.consecutiveOverruns < types_1.DEFAULT_MAX_CONSECUTIVE_SCAN_OVERRUNS
? core_1.Health.STATUS.PASS
: core_1.Health.STATUS.WARN;
const _check = {
componentId: this.componentId,
resource: this.resource,
pollingGroup: this.pollingGroup,
componentType: 'pollingGroup',
observedValue: this.pollingStats,
observedUnit: 'polling stats',
status: overrunsStatus,
time: this.pollingStats.scanTime.toISOString(),
};
return _check;
}
}
exports.PollingMetricsHandler = PollingMetricsHandler;
//# sourceMappingURL=PollingStatsManager.js.map