@qrvey/health-checker
Version:
 
127 lines • 5.49 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RuntimeHealth = exports.RuntimeHealthService = void 0;
exports.evaluateThresholds = evaluateThresholds;
const os_1 = __importDefault(require("os"));
const v8_1 = __importDefault(require("v8"));
const perf_hooks_1 = require("perf_hooks");
const constants_1 = require("../utils/constants");
const runtimeHealth_constants_1 = require("../utils/runtimeHealth.constants");
const runtimeHealth_utils_1 = require("../utils/runtimeHealth.utils");
const logger_1 = __importDefault(require("../utils/logger"));
class RuntimeHealthService {
static async getMetrics(options = {}) {
var _a;
const windowMs = (_a = options.windowMs) !== null && _a !== void 0 ? _a : runtimeHealth_constants_1.DEFAULT_RUNTIME_HEALTH_WINDOW_MS;
const enabledMetrics = getEnabledMetrics();
const [cpuPercent, eventLoopDelayMs] = await Promise.all([
enabledMetrics.cpuPercent ? getCpuPercent(windowMs) : null,
enabledMetrics.eventLoopDelayMs
? getEventLoopDelay(windowMs)
: null,
]);
let heapPercent = null;
let heapLimitMb = null;
if (enabledMetrics.heapPercent) {
const heapStats = v8_1.default.getHeapStatistics();
heapLimitMb = (0, runtimeHealth_utils_1.bytesToMb)(heapStats.heap_size_limit);
heapPercent =
heapStats.heap_size_limit > 0
? (process.memoryUsage().heapUsed /
heapStats.heap_size_limit) *
100
: 0;
}
return {
cpuPercent,
heapPercent,
eventLoopDelayMs,
heapLimitMb,
};
}
static async get(options = {}) {
const thresholds = getThresholds(options);
const enabledMetrics = getEnabledMetrics();
const metrics = await this.getMetrics(options);
const failedMetrics = evaluateThresholds(metrics, thresholds, enabledMetrics);
const status = failedMetrics.length > 0 ? constants_1.FAILED : constants_1.OK;
const details = {
status,
metrics,
enabledMetrics,
thresholds,
failedMetrics,
};
const runtimeStatus = {
status,
details,
};
if (runtimeHealth_constants_1.DEFAULT_RUNTIME_HEALTH_LOG_GET) {
logger_1.default.info('[RuntimeHealthService.get]', runtimeStatus);
}
return runtimeStatus;
}
static async getStatus(options = {}) {
return this.get(options);
}
}
exports.RuntimeHealthService = RuntimeHealthService;
exports.RuntimeHealth = RuntimeHealthService;
function evaluateThresholds(metrics, thresholds, enabledMetrics = runtimeHealth_constants_1.DEFAULT_RUNTIME_HEALTH_ENABLED_METRICS) {
const failedMetrics = [];
if (enabledMetrics.cpuPercent &&
typeof metrics.cpuPercent === 'number' &&
metrics.cpuPercent >= thresholds.cpuPercent) {
failedMetrics.push('cpuPercent');
}
if (enabledMetrics.heapPercent &&
typeof metrics.heapPercent === 'number' &&
metrics.heapPercent >= thresholds.heapPercent) {
failedMetrics.push('heapPercent');
}
if (enabledMetrics.eventLoopDelayMs &&
typeof metrics.eventLoopDelayMs === 'number' &&
metrics.eventLoopDelayMs >= thresholds.eventLoopDelayMs) {
failedMetrics.push('eventLoopDelayMs');
}
return failedMetrics;
}
function getEnabledMetrics() {
return Object.assign({}, runtimeHealth_constants_1.DEFAULT_RUNTIME_HEALTH_ENABLED_METRICS);
}
function getThresholds(options) {
const directThresholds = {};
if (typeof (options === null || options === void 0 ? void 0 : options.cpuPercent) === 'number') {
directThresholds.cpuPercent = options.cpuPercent;
}
if (typeof (options === null || options === void 0 ? void 0 : options.heapPercent) === 'number') {
directThresholds.heapPercent = options.heapPercent;
}
if (typeof (options === null || options === void 0 ? void 0 : options.eventLoopDelayMs) === 'number') {
directThresholds.eventLoopDelayMs = options.eventLoopDelayMs;
}
return Object.assign(Object.assign(Object.assign({}, runtimeHealth_constants_1.DEFAULT_RUNTIME_HEALTH_THRESHOLDS), directThresholds), options === null || options === void 0 ? void 0 : options.thresholds);
}
async function getCpuPercent(windowMs) {
const startUsage = process.cpuUsage();
const startTime = process.hrtime.bigint();
await (0, runtimeHealth_utils_1.wait)(windowMs);
const endUsage = process.cpuUsage(startUsage);
const elapsedMicros = Number(process.hrtime.bigint() - startTime) / 1000;
const cpuCount = Math.max(os_1.default.cpus().length, 1);
const cpuMicros = endUsage.user + endUsage.system;
if (elapsedMicros <= 0)
return 0;
return (cpuMicros / (elapsedMicros * cpuCount)) * 100;
}
async function getEventLoopDelay(windowMs) {
const histogram = (0, perf_hooks_1.monitorEventLoopDelay)({ resolution: 20 });
histogram.enable();
await (0, runtimeHealth_utils_1.wait)(windowMs);
histogram.disable();
return histogram.mean / 1000000;
}
//# sourceMappingURL=runtimeHealth.service.js.map