vrack-db
Version:
This is an In Memory database designed for storing time series (graphs).
182 lines (181 loc) • 5.82 kB
JavaScript
"use strict";
/*
* Copyright © 2023 Boris Bobylev. All rights reserved.
* Licensed under the Apache License, Version 2.0
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EAlertStatus = void 0;
const ErrorManager_1 = __importDefault(require("./Errors/ErrorManager"));
const Interval_1 = __importDefault(require("./Interval"));
const MetricResult_1 = __importDefault(require("./MetricResult"));
const Utility_1 = __importDefault(require("./Utility"));
/**
* Alert status list
*/
var EAlertStatus;
(function (EAlertStatus) {
EAlertStatus["created"] = "created";
EAlertStatus["updated"] = "updated";
EAlertStatus["ok"] = "ok";
})(EAlertStatus = exports.EAlertStatus || (exports.EAlertStatus = {}));
ErrorManager_1.default.register('9gaaPv5DFoh5', 'VDB_ALERTING_DUBLICATE_UID', 'Dublicate key of watch point');
/**
* Simple implementation of data tracking to generate alarm messages
*
* Used with the AlertCondition and AlertQuery classes
*/
class Alerting {
/**
* @param database VRack db database instance
* */
constructor(database) {
this.listeners = [];
/**
* Alerting points
* Each point have a unique ID
* @see watch
*/
this.points = {};
/**
* List of watch timers
* List item contain Array of point IDS
* @see initTimer
*/
this.timers = {};
this.database = database;
}
/**
* Add listener for getting alert messages
*
* @param f function for listening
* @see makeAlert
*/
addListener(f) {
this.listeners.push(f);
}
/**
* Start watch of alert point
*
* Automatically queries the data at the specified `query` interval for the `path`
* metric and checks the received data against `condition`.
*
* @param path Metric path in vrack database
* @param query Query parameters
* @param condition Condition settings class
* @param id Unique id for this point. If you don't specify it, it will be filled in automatically
* @param additional Additional information that will be specified in the created message
*/
watch(path, query, condition, id, additional) {
if (id === "")
id = Utility_1.default.uid();
if (this.points[id] !== undefined)
throw ErrorManager_1.default.make(new Error, 'VDB_ALERTING_DUBLICATE_UID', { id });
const fconf = { status: 'ok', created: 0, path, query, condition, additional, id, count: 0 };
this.points[id] = fconf;
this.initTimer(id);
return id;
}
/**
* Stop watching
*
* @see watch
* @param id Unique id of point
*/
unwatch(id) {
if (this.points[id]) {
const tInterval = this.points[id].query.getEvaluateInterval();
const isec = Interval_1.default.parseInterval(tInterval);
const timer = this.timers[isec];
for (let i = 0; i < timer.length; i++)
if (timer[i] === id)
timer.splice(i, 1);
delete this.points[id];
}
}
/**
* Initializing the Data Refresh Timer
*
* @param id Unique id of point
*/
initTimer(id) {
const tInterval = this.points[id].query.query.evaluateInterval;
const isec = Interval_1.default.parseInterval(tInterval);
if (this.timers[isec] === undefined) {
this.timers[isec] = [];
setInterval(() => { this.runTimer(isec); }, isec * 1000);
}
this.timers[isec].push(id);
}
/**
* Run a timer
*
* @see initTimer
*
* @param isec Timer evaluate interval in second
*/
runTimer(isec) {
for (const id of this.timers[isec])
this.evaluate(id);
}
/**
* Running a evaluate AlertPoint
*
* @param id Unique id of point
*/
evaluate(id) {
const point = this.points[id];
const value = this.getQueryValue(point);
if (point.condition.check(value, id)) {
point.count++;
if (point.status === 'ok') {
point.status = "created";
point.created = Math.floor(Date.now() / 1000);
return this.makeAlert(id, value, point);
}
point.status = "updated";
this.makeAlert(id, value, point);
}
else {
if (point.status !== "ok") {
point.status = "ok";
point.count = 0;
this.makeAlert(id, value, point);
}
}
}
/**
* Return query result
*
* @param point Alert point
*/
getQueryValue(point) {
const query = point.query;
const qr = this.database.read(point.path, query.query.period, query.query.interval);
return MetricResult_1.default.aggregate(qr, query.query.func);
}
/**
* Creates an alarm and sends information to all subscribers
*
* @param id UID of point
* @param value alert evaluate value
* @param point
*/
makeAlert(id, value, point) {
const nAlert = {
id, value, status: this.points[id].status,
count: this.points[id].count,
timestamp: Math.floor(Date.now() / 1000),
created: this.points[id].created,
condition: point.condition.condition,
areas: point.condition.areas(),
threshholds: point.condition.threshholds(),
additional: point.additional
};
for (const f of this.listeners)
f(nAlert);
}
}
exports.default = Alerting;