UNPKG

proactive-deps

Version:

A library for managing proactive dependency checks in Node.js applications.

118 lines (117 loc) 5.36 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DependencyMonitor = void 0; const cache_manager_1 = require("cache-manager"); const constants_1 = require("./constants"); const format_check_result_1 = __importDefault(require("./lib/format-check-result")); const format_prometheus_metrics_1 = __importDefault(require("./lib/format-prometheus-metrics")); /** * DependencyMonitor is a class that monitors the status of various dependencies * (e.g., databases, APIs) and provides methods to check their health and latency. * It uses a cache to store the results of the checks and can be configured * to refresh the cache at specified intervals. * It also provides a method to get Prometheus metrics for the monitored dependencies. * @class DependencyMonitor */ class DependencyMonitor { /** * Creates an instance of DependencyMonitor. * @param {DependencyMonitorOptions} [options] - Optional configuration options for the monitor. * @default { cacheDurationMs: 60000, refreshThresholdMs: 5000, checkIntervalMs: 15000 } * @example * const monitor = new DependencyMonitor({ * cacheDurationMs: 60000, // Cache duration of 1 minute * refreshThresholdMs: 5000, // Refresh threshold of 5 seconds * checkIntervalMs: 15000, // Check interval of 15 seconds * }); */ constructor(options = {}) { this._dependencies = []; this._dependencyCheckInterval = null; this._refreshThresholdMs = constants_1.DEFAULT_REFRESH_THRESHOLD_MS; this._cacheDurationMs = constants_1.DEFAULT_CACHE_DURATION_MS; this._checkIntervalMs = constants_1.DEFAULT_CHECK_INTERVAL_MS; this.checkIntervalStarted = false; this._cacheDurationMs = options.cacheDurationMs || constants_1.DEFAULT_CACHE_DURATION_MS; this._refreshThresholdMs = options.refreshThresholdMs || constants_1.DEFAULT_REFRESH_THRESHOLD_MS; this._checkIntervalMs = options.checkIntervalMs || constants_1.DEFAULT_CHECK_INTERVAL_MS; this._cache = (0, cache_manager_1.createCache)({ ttl: this._cacheDurationMs, refreshThreshold: this._refreshThresholdMs, }); } startDependencyCheckInterval() { this.checkIntervalStarted = true; if (this._dependencyCheckInterval) { clearInterval(this._dependencyCheckInterval); } this._getAllDependenciesStatus(); // Initial check this._dependencyCheckInterval = setInterval(this._getAllDependenciesStatus.bind(this), this._checkIntervalMs); this._dependencyCheckInterval.unref(); // Allow the process to exit if this is the only thing running } stopDependencyCheckInterval() { this.checkIntervalStarted = false; if (this._dependencyCheckInterval) { clearInterval(this._dependencyCheckInterval); this._dependencyCheckInterval = null; } } register(dependency) { this._dependencies.push(dependency); } async _getDependencyStatus(dependency) { try { return await this._cache.wrap(dependency.name, async () => { if (dependency.skip) { return (0, format_check_result_1.default)(dependency, constants_1.SUCCESS_STATUS_CODE, 0, true); } const start = Date.now(); const checkResults = await dependency.check(); const latencyMs = Date.now() - start; return (0, format_check_result_1.default)(dependency, checkResults, latencyMs); }, dependency.cacheDurationMs || this._cacheDurationMs, dependency.refreshThresholdMs || this._refreshThresholdMs); } catch (error) { const status = (0, format_check_result_1.default)(dependency, { code: constants_1.ERROR_STATUS_CODE, error: error, errorMessage: `Error checking dependency ${dependency.name}`, }); await this._cache.set(dependency.name, status, dependency.cacheDurationMs); return status; } } async _getAllDependenciesStatus() { const checkPromises = this._dependencies.map(async (dep) => this._getDependencyStatus(dep)); // Run all checks concurrently return await Promise.all(checkPromises); } async getStatus(dependencyName) { const cacheKey = dependencyName; const cachedValue = await this._cache.get(cacheKey); if (cachedValue) { return cachedValue; } else { const dependency = this._dependencies.find((dep) => dep.name === dependencyName); if (dependency) { return await this._getDependencyStatus(dependency); } throw new Error(`Dependency ${dependencyName} not found`); } } async getAllStatuses() { return await this._getAllDependenciesStatus(); } async getPrometheusMetrics() { const statuses = await this._getAllDependenciesStatus(); return (0, format_prometheus_metrics_1.default)(statuses); } } exports.DependencyMonitor = DependencyMonitor;