|
|
|
/******/ (function(modules) { // webpackBootstrap
|
|
|
|
/******/ // The module cache
|
|
|
|
/******/ var installedModules = {};
|
|
|
|
/******/
|
|
|
|
/******/ // The require function
|
|
|
|
/******/ function __webpack_require__(moduleId) {
|
|
|
|
/******/
|
|
|
|
/******/ // Check if module is in cache
|
|
|
|
/******/ if(installedModules[moduleId]) {
|
|
|
|
/******/ return installedModules[moduleId].exports;
|
|
|
|
/******/ }
|
|
|
|
/******/ // Create a new module (and put it into the cache)
|
|
|
|
/******/ var module = installedModules[moduleId] = {
|
|
|
|
/******/ i: moduleId,
|
|
|
|
/******/ l: false,
|
|
|
|
/******/ exports: {}
|
|
|
|
/******/ };
|
|
|
|
/******/
|
|
|
|
/******/ // Execute the module function
|
|
|
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
|
|
/******/
|
|
|
|
/******/ // Flag the module as loaded
|
|
|
|
/******/ module.l = true;
|
|
|
|
/******/
|
|
|
|
/******/ // Return the exports of the module
|
|
|
|
/******/ return module.exports;
|
|
|
|
/******/ }
|
|
|
|
/******/
|
|
|
|
/******/
|
|
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
|
|
/******/ __webpack_require__.m = modules;
|
|
|
|
/******/
|
|
|
|
/******/ // expose the module cache
|
|
|
|
/******/ __webpack_require__.c = installedModules;
|
|
|
|
/******/
|
|
|
|
/******/ // define getter function for harmony exports
|
|
|
|
/******/ __webpack_require__.d = function(exports, name, getter) {
|
|
|
|
/******/ if(!__webpack_require__.o(exports, name)) {
|
|
|
|
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
|
|
|
/******/ }
|
|
|
|
/******/ };
|
|
|
|
/******/
|
|
|
|
/******/ // define __esModule on exports
|
|
|
|
/******/ __webpack_require__.r = function(exports) {
|
|
|
|
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
|
|
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
|
/******/ }
|
|
|
|
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
/******/ };
|
|
|
|
/******/
|
|
|
|
/******/ // create a fake namespace object
|
|
|
|
/******/ // mode & 1: value is a module id, require it
|
|
|
|
/******/ // mode & 2: merge all properties of value into the ns
|
|
|
|
/******/ // mode & 4: return value when already ns object
|
|
|
|
/******/ // mode & 8|1: behave like require
|
|
|
|
/******/ __webpack_require__.t = function(value, mode) {
|
|
|
|
/******/ if(mode & 1) value = __webpack_require__(value);
|
|
|
|
/******/ if(mode & 8) return value;
|
|
|
|
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
|
|
|
/******/ var ns = Object.create(null);
|
|
|
|
/******/ __webpack_require__.r(ns);
|
|
|
|
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
|
|
|
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
|
|
|
/******/ return ns;
|
|
|
|
/******/ };
|
|
|
|
/******/
|
|
|
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
|
|
/******/ __webpack_require__.n = function(module) {
|
|
|
|
/******/ var getter = module && module.__esModule ?
|
|
|
|
/******/ function getDefault() { return module['default']; } :
|
|
|
|
/******/ function getModuleExports() { return module; };
|
|
|
|
/******/ __webpack_require__.d(getter, 'a', getter);
|
|
|
|
/******/ return getter;
|
|
|
|
/******/ };
|
|
|
|
/******/
|
|
|
|
/******/ // Object.prototype.hasOwnProperty.call
|
|
|
|
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
|
|
|
/******/
|
|
|
|
/******/ // __webpack_public_path__
|
|
|
|
/******/ __webpack_require__.p = "";
|
|
|
|
/******/
|
|
|
|
/******/
|
|
|
|
/******/ // Load entry module and return exports
|
|
|
|
/******/ return __webpack_require__(__webpack_require__.s = 0);
|
|
|
|
/******/ })
|
|
|
|
/************************************************************************/
|
|
|
|
/******/ ({
|
|
|
|
|
|
|
|
/***/ "./src/config.ts":
|
|
|
|
/*!***********************!*\
|
|
|
|
!*** ./src/config.ts ***!
|
|
|
|
\***********************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const path = __webpack_require__(/*! path */ "path");
|
|
|
|
exports.ANALYTICS_PATH = path.join(__dirname, '../../analytics');
|
|
|
|
exports.DATA_PATH = path.join(__dirname, '../../data');
|
|
|
|
exports.DATASETS_PATH = path.join(exports.DATA_PATH, 'datasets');
|
|
|
|
exports.ANOMALIES_PATH = path.join(exports.DATA_PATH, 'anomalies');
|
|
|
|
exports.MODELS_PATH = path.join(exports.DATA_PATH, 'models');
|
|
|
|
exports.METRICS_PATH = path.join(exports.DATA_PATH, 'metrics');
|
|
|
|
exports.SEGMENTS_PATH = path.join(exports.DATA_PATH, 'segments');
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/index.ts":
|
|
|
|
/*!**********************!*\
|
|
|
|
!*** ./src/index.ts ***!
|
|
|
|
\**********************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
|
|
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
|
|
function fulfilled(value) {
|
|
|
|
try {
|
|
|
|
step(generator.next(value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function rejected(value) {
|
|
|
|
try {
|
|
|
|
step(generator["throw"](value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function step(result) {
|
|
|
|
result.done ? resolve(result.value) : new P(function (resolve) {
|
|
|
|
resolve(result.value);
|
|
|
|
}).then(fulfilled, rejected);
|
|
|
|
}
|
|
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
|
|
});
|
|
|
|
};
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const Koa = __webpack_require__(/*! koa */ "koa");
|
|
|
|
const Router = __webpack_require__(/*! koa-router */ "koa-router");
|
|
|
|
const bodyParser = __webpack_require__(/*! koa-bodyparser */ "koa-bodyparser");
|
|
|
|
const anomalies_1 = __webpack_require__(/*! ./routes/anomalies */ "./src/routes/anomalies.ts");
|
|
|
|
const segments_1 = __webpack_require__(/*! ./routes/segments */ "./src/routes/segments.ts");
|
|
|
|
const alerts_1 = __webpack_require__(/*! ./routes/alerts */ "./src/routes/alerts.ts");
|
|
|
|
const data_1 = __webpack_require__(/*! ./services/data */ "./src/services/data.ts");
|
|
|
|
data_1.checkDataFolders();
|
|
|
|
var app = new Koa();
|
|
|
|
const PORT = process.env.HASTIC_PORT || 8000;
|
|
|
|
app.use(bodyParser());
|
|
|
|
app.use(function (ctx, next) {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
ctx.set('Access-Control-Allow-Origin', '*');
|
|
|
|
ctx.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
|
|
|
|
ctx.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
|
|
|
|
next();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
var rootRouter = new Router();
|
|
|
|
rootRouter.use('/anomalies', anomalies_1.router.routes(), anomalies_1.router.allowedMethods());
|
|
|
|
rootRouter.use('/segments', segments_1.router.routes(), segments_1.router.allowedMethods());
|
|
|
|
rootRouter.use('/alerts', alerts_1.router.routes(), alerts_1.router.allowedMethods());
|
|
|
|
rootRouter.get('/', ctx => __awaiter(undefined, void 0, void 0, function* () {
|
|
|
|
ctx.response.body = { status: 'Ok ok' };
|
|
|
|
}));
|
|
|
|
app.use(rootRouter.routes()).use(rootRouter.allowedMethods());
|
|
|
|
app.listen(PORT, () => {
|
|
|
|
console.log(`Server is running on :${PORT}`);
|
|
|
|
});
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/routes/alerts.ts":
|
|
|
|
/*!******************************!*\
|
|
|
|
!*** ./src/routes/alerts.ts ***!
|
|
|
|
\******************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const anomalyType_1 = __webpack_require__(/*! ../services/anomalyType */ "./src/services/anomalyType.ts");
|
|
|
|
const alerts_1 = __webpack_require__(/*! ../services/alerts */ "./src/services/alerts.ts");
|
|
|
|
const Router = __webpack_require__(/*! koa-router */ "koa-router");
|
|
|
|
function getAlert(ctx) {
|
|
|
|
let anomalyId = ctx.request.query.anomaly_id;
|
|
|
|
let anomaly = anomalyType_1.loadAnomalyById(anomalyId);
|
|
|
|
if (anomaly == null) {
|
|
|
|
anomalyId = anomalyType_1.getAnomalyIdByName(anomalyId.toLowerCase());
|
|
|
|
}
|
|
|
|
let alertsAnomalies = alerts_1.getAlertsAnomalies();
|
|
|
|
let pos = alertsAnomalies.indexOf(anomalyId);
|
|
|
|
let enable = pos !== -1;
|
|
|
|
ctx.response.body = { enable };
|
|
|
|
}
|
|
|
|
function changeAlert(ctx) {
|
|
|
|
let anomalyId = ctx.request.body.anomaly_id;
|
|
|
|
let enable = ctx.request.body.enable;
|
|
|
|
let anomaly = anomalyType_1.loadAnomalyById(anomalyId);
|
|
|
|
if (anomaly == null) {
|
|
|
|
anomalyId = anomalyType_1.getAnomalyIdByName(anomalyId.toLowerCase());
|
|
|
|
}
|
|
|
|
let alertsAnomalies = alerts_1.getAlertsAnomalies();
|
|
|
|
let pos = alertsAnomalies.indexOf(anomalyId);
|
|
|
|
if (enable && pos == -1) {
|
|
|
|
alertsAnomalies.push(anomalyId);
|
|
|
|
alerts_1.saveAlertsAnomalies(alertsAnomalies);
|
|
|
|
} else if (!enable && pos > -1) {
|
|
|
|
alertsAnomalies.splice(pos, 1);
|
|
|
|
alerts_1.saveAlertsAnomalies(alertsAnomalies);
|
|
|
|
}
|
|
|
|
ctx.response.body = { status: 'OK' };
|
|
|
|
}
|
|
|
|
exports.router = new Router();
|
|
|
|
exports.router.get('/', getAlert);
|
|
|
|
exports.router.post('/', changeAlert);
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/routes/anomalies.ts":
|
|
|
|
/*!*********************************!*\
|
|
|
|
!*** ./src/routes/anomalies.ts ***!
|
|
|
|
\*********************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
|
|
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
|
|
function fulfilled(value) {
|
|
|
|
try {
|
|
|
|
step(generator.next(value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function rejected(value) {
|
|
|
|
try {
|
|
|
|
step(generator["throw"](value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function step(result) {
|
|
|
|
result.done ? resolve(result.value) : new P(function (resolve) {
|
|
|
|
resolve(result.value);
|
|
|
|
}).then(fulfilled, rejected);
|
|
|
|
}
|
|
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
|
|
});
|
|
|
|
};
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const Router = __webpack_require__(/*! koa-router */ "koa-router");
|
|
|
|
const anomalyType_1 = __webpack_require__(/*! ../services/anomalyType */ "./src/services/anomalyType.ts");
|
|
|
|
const analytics_1 = __webpack_require__(/*! ../services/analytics */ "./src/services/analytics.ts");
|
|
|
|
const metrics_1 = __webpack_require__(/*! ../services/metrics */ "./src/services/metrics.ts");
|
|
|
|
function sendAnomalyTypeStatus(ctx) {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
let id = ctx.request.query.id;
|
|
|
|
let name = ctx.request.query.name;
|
|
|
|
try {
|
|
|
|
let anomaly;
|
|
|
|
if (id !== undefined) {
|
|
|
|
anomaly = anomalyType_1.loadAnomalyById(id);
|
|
|
|
} else {
|
|
|
|
anomaly = anomalyType_1.loadAnomalyByName(name);
|
|
|
|
}
|
|
|
|
if (anomaly === null) {
|
|
|
|
ctx.response.status = 404;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (anomaly.status === undefined) {
|
|
|
|
throw new Error('No status for ' + name);
|
|
|
|
}
|
|
|
|
ctx.response.body = { status: anomaly.status, errorMessage: anomaly.error };
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
// TODO: better send 404 when we know than isn`t found
|
|
|
|
ctx.response.status = 500;
|
|
|
|
ctx.response.body = { error: 'Can`t return anything' };
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function getAnomaly(ctx) {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
try {
|
|
|
|
let id = ctx.request.query.id;
|
|
|
|
let name = ctx.request.query.name;
|
|
|
|
let anomaly;
|
|
|
|
if (id !== undefined) {
|
|
|
|
anomaly = anomalyType_1.loadAnomalyById(id);
|
|
|
|
} else {
|
|
|
|
anomaly = anomalyType_1.loadAnomalyByName(name.toLowerCase());
|
|
|
|
}
|
|
|
|
if (anomaly === null) {
|
|
|
|
ctx.response.status = 404;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ctx.response.body = {
|
|
|
|
name: anomaly.name,
|
|
|
|
metric: anomaly.metric,
|
|
|
|
status: anomaly.status
|
|
|
|
};
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
// TODO: better send 404 when we know than isn`t found
|
|
|
|
ctx.response.status = 500;
|
|
|
|
ctx.response.body = 'Can`t get anything';
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function createAnomaly(ctx) {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
try {
|
|
|
|
let body = ctx.request.body;
|
|
|
|
const metric = {
|
|
|
|
datasource: body.metric.datasource,
|
|
|
|
targets: metrics_1.saveTargets(body.metric.targets)
|
|
|
|
};
|
|
|
|
const anomaly = {
|
|
|
|
name: body.name,
|
|
|
|
panelUrl: body.panelUrl,
|
|
|
|
pattern: body.pattern.toLowerCase(),
|
|
|
|
metric: metric,
|
|
|
|
datasource: body.datasource,
|
|
|
|
status: 'learning',
|
|
|
|
last_prediction_time: 0,
|
|
|
|
next_id: 0
|
|
|
|
};
|
|
|
|
let anomalyId = anomalyType_1.insertAnomaly(anomaly);
|
|
|
|
if (anomalyId === null) {
|
|
|
|
ctx.response.status = 403;
|
|
|
|
ctx.response.body = {
|
|
|
|
code: 403,
|
|
|
|
message: 'Already exists'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
ctx.response.body = { anomaly_id: anomalyId };
|
|
|
|
analytics_1.runLearning(anomalyId);
|
|
|
|
} catch (e) {
|
|
|
|
ctx.response.status = 500;
|
|
|
|
ctx.response.body = {
|
|
|
|
code: 500,
|
|
|
|
message: 'Internal error'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function deleteAnomaly(ctx) {
|
|
|
|
try {
|
|
|
|
let id = ctx.request.query.id;
|
|
|
|
let name = ctx.request.query.name;
|
|
|
|
if (id !== undefined) {
|
|
|
|
anomalyType_1.removeAnomaly(id);
|
|
|
|
} else {
|
|
|
|
anomalyType_1.removeAnomaly(name.toLowerCase());
|
|
|
|
}
|
|
|
|
ctx.response.body = {
|
|
|
|
code: 200,
|
|
|
|
message: 'Success'
|
|
|
|
};
|
|
|
|
} catch (e) {
|
|
|
|
ctx.response.status = 500;
|
|
|
|
ctx.response.body = {
|
|
|
|
code: 500,
|
|
|
|
message: 'Internal error'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
exports.router = new Router();
|
|
|
|
exports.router.get('/status', sendAnomalyTypeStatus);
|
|
|
|
exports.router.get('/', getAnomaly);
|
|
|
|
exports.router.post('/', createAnomaly);
|
|
|
|
exports.router.delete('/', deleteAnomaly);
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/routes/segments.ts":
|
|
|
|
/*!********************************!*\
|
|
|
|
!*** ./src/routes/segments.ts ***!
|
|
|
|
\********************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
|
|
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
|
|
function fulfilled(value) {
|
|
|
|
try {
|
|
|
|
step(generator.next(value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function rejected(value) {
|
|
|
|
try {
|
|
|
|
step(generator["throw"](value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function step(result) {
|
|
|
|
result.done ? resolve(result.value) : new P(function (resolve) {
|
|
|
|
resolve(result.value);
|
|
|
|
}).then(fulfilled, rejected);
|
|
|
|
}
|
|
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
|
|
});
|
|
|
|
};
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const Router = __webpack_require__(/*! koa-router */ "koa-router");
|
|
|
|
const segments_1 = __webpack_require__(/*! ../services/segments */ "./src/services/segments.ts");
|
|
|
|
const anomalyType_1 = __webpack_require__(/*! ../services/anomalyType */ "./src/services/anomalyType.ts");
|
|
|
|
const analytics_1 = __webpack_require__(/*! ../services/analytics */ "./src/services/analytics.ts");
|
|
|
|
function sendSegments(ctx) {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
let anomalyId = ctx.request.query.anomaly_id;
|
|
|
|
let anomaly = anomalyType_1.loadAnomalyById(anomalyId);
|
|
|
|
if (anomaly === null) {
|
|
|
|
anomalyId = anomalyType_1.getAnomalyIdByName(anomalyId);
|
|
|
|
}
|
|
|
|
let lastSegmentId = ctx.request.query.last_segment;
|
|
|
|
let timeFrom = ctx.request.query.from;
|
|
|
|
let timeTo = ctx.request.query.to;
|
|
|
|
let segments = segments_1.getLabeledSegments(anomalyId);
|
|
|
|
// Id filtering
|
|
|
|
if (lastSegmentId !== undefined) {
|
|
|
|
segments = segments.filter(el => el.id > lastSegmentId);
|
|
|
|
}
|
|
|
|
// Time filtering
|
|
|
|
if (timeFrom !== undefined) {
|
|
|
|
segments = segments.filter(el => el.finish > timeFrom);
|
|
|
|
}
|
|
|
|
if (timeTo !== undefined) {
|
|
|
|
segments = segments.filter(el => el.start < timeTo);
|
|
|
|
}
|
|
|
|
ctx.response.body = { segments };
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function updateSegments(ctx) {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
try {
|
|
|
|
let segmentsUpdate = ctx.request.body;
|
|
|
|
let anomalyId = segmentsUpdate.anomaly_id;
|
|
|
|
let anomalyName = segmentsUpdate.name;
|
|
|
|
if (anomalyId === undefined) {
|
|
|
|
anomalyId = anomalyType_1.getAnomalyIdByName(anomalyName.toLowerCase());
|
|
|
|
}
|
|
|
|
let addedIds = segments_1.insertSegments(anomalyId, segmentsUpdate.added_segments, true);
|
|
|
|
segments_1.removeSegments(anomalyId, segmentsUpdate.removed_segments);
|
|
|
|
ctx.response.body = { added_ids: addedIds };
|
|
|
|
analytics_1.runLearning(anomalyId);
|
|
|
|
} catch (e) {
|
|
|
|
ctx.response.status = 500;
|
|
|
|
ctx.response.body = {
|
|
|
|
code: 500,
|
|
|
|
message: 'Internal error'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
exports.router = new Router();
|
|
|
|
exports.router.get('/', sendSegments);
|
|
|
|
exports.router.patch('/', updateSegments);
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/services/alerts.ts":
|
|
|
|
/*!********************************!*\
|
|
|
|
!*** ./src/services/alerts.ts ***!
|
|
|
|
\********************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
|
|
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
|
|
function fulfilled(value) {
|
|
|
|
try {
|
|
|
|
step(generator.next(value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function rejected(value) {
|
|
|
|
try {
|
|
|
|
step(generator["throw"](value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function step(result) {
|
|
|
|
result.done ? resolve(result.value) : new P(function (resolve) {
|
|
|
|
resolve(result.value);
|
|
|
|
}).then(fulfilled, rejected);
|
|
|
|
}
|
|
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
|
|
});
|
|
|
|
};
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const json_1 = __webpack_require__(/*! ./json */ "./src/services/json.ts");
|
|
|
|
const analytics_1 = __webpack_require__(/*! ./analytics */ "./src/services/analytics.ts");
|
|
|
|
const notification_1 = __webpack_require__(/*! ./notification */ "./src/services/notification.ts");
|
|
|
|
const segments_1 = __webpack_require__(/*! ./segments */ "./src/services/segments.ts");
|
|
|
|
const config_1 = __webpack_require__(/*! ../config */ "./src/config.ts");
|
|
|
|
const path = __webpack_require__(/*! path */ "path");
|
|
|
|
const fs = __webpack_require__(/*! fs */ "fs");
|
|
|
|
const ALERTS_DB_PATH = path.join(config_1.ANOMALIES_PATH, `alerts_anomalies.json`);
|
|
|
|
function getAlertsAnomalies() {
|
|
|
|
if (!fs.existsSync(ALERTS_DB_PATH)) {
|
|
|
|
saveAlertsAnomalies([]);
|
|
|
|
}
|
|
|
|
return json_1.getJsonDataSync(ALERTS_DB_PATH);
|
|
|
|
}
|
|
|
|
exports.getAlertsAnomalies = getAlertsAnomalies;
|
|
|
|
function saveAlertsAnomalies(anomalies) {
|
|
|
|
return json_1.writeJsonDataSync(ALERTS_DB_PATH, anomalies);
|
|
|
|
}
|
|
|
|
exports.saveAlertsAnomalies = saveAlertsAnomalies;
|
|
|
|
function processAlerts(anomalyId) {
|
|
|
|
let segments = segments_1.getLabeledSegments(anomalyId);
|
|
|
|
const currentTime = new Date().getTime();
|
|
|
|
const activeAlert = activeAlerts.has(anomalyId);
|
|
|
|
let newActiveAlert = false;
|
|
|
|
if (segments.length > 0) {
|
|
|
|
let lastSegment = segments[segments.length - 1];
|
|
|
|
if (lastSegment.finish >= currentTime - alertTimeout) {
|
|
|
|
newActiveAlert = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!activeAlert && newActiveAlert) {
|
|
|
|
activeAlerts.add(anomalyId);
|
|
|
|
notification_1.sendNotification(anomalyId, true);
|
|
|
|
} else if (activeAlert && !newActiveAlert) {
|
|
|
|
activeAlerts.delete(anomalyId);
|
|
|
|
notification_1.sendNotification(anomalyId, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function alertsTick() {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
let alertsAnomalies = getAlertsAnomalies();
|
|
|
|
for (let anomalyId of alertsAnomalies) {
|
|
|
|
try {
|
|
|
|
yield analytics_1.runPredict(anomalyId);
|
|
|
|
processAlerts(anomalyId);
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setTimeout(alertsTick, 5000);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
const alertTimeout = 60000; // ms
|
|
|
|
const activeAlerts = new Set();
|
|
|
|
setTimeout(alertsTick, 5000);
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/services/analytics.ts":
|
|
|
|
/*!***********************************!*\
|
|
|
|
!*** ./src/services/analytics.ts ***!
|
|
|
|
\***********************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
|
|
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
|
|
function fulfilled(value) {
|
|
|
|
try {
|
|
|
|
step(generator.next(value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function rejected(value) {
|
|
|
|
try {
|
|
|
|
step(generator["throw"](value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function step(result) {
|
|
|
|
result.done ? resolve(result.value) : new P(function (resolve) {
|
|
|
|
resolve(result.value);
|
|
|
|
}).then(fulfilled, rejected);
|
|
|
|
}
|
|
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
|
|
});
|
|
|
|
};
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const child_process_1 = __webpack_require__(/*! child_process */ "child_process");
|
|
|
|
const config_1 = __webpack_require__(/*! ../config */ "./src/config.ts");
|
|
|
|
const anomalyType_1 = __webpack_require__(/*! ./anomalyType */ "./src/services/anomalyType.ts");
|
|
|
|
const metrics_1 = __webpack_require__(/*! ./metrics */ "./src/services/metrics.ts");
|
|
|
|
const segments_1 = __webpack_require__(/*! ./segments */ "./src/services/segments.ts");
|
|
|
|
const event_stream_1 = __webpack_require__(/*! event-stream */ "event-stream");
|
|
|
|
const fs = __webpack_require__(/*! fs */ "fs");
|
|
|
|
const path = __webpack_require__(/*! path */ "path");
|
|
|
|
var learnWorker;
|
|
|
|
if (fs.existsSync(path.join(config_1.ANALYTICS_PATH, 'dist/worker/worker'))) {
|
|
|
|
learnWorker = child_process_1.spawn('dist/worker/worker', [], { cwd: config_1.ANALYTICS_PATH });
|
|
|
|
} else {
|
|
|
|
// If compiled analytics script doesn't exist - fallback to regular python
|
|
|
|
learnWorker = child_process_1.spawn('python3', ['worker.py'], { cwd: config_1.ANALYTICS_PATH });
|
|
|
|
}
|
|
|
|
learnWorker.stdout.pipe(event_stream_1.split()).pipe(event_stream_1.mapSync(onMessage));
|
|
|
|
learnWorker.stderr.on('data', data => console.error(`worker stderr: ${data}`));
|
|
|
|
const taskMap = {};
|
|
|
|
let nextTaskId = 0;
|
|
|
|
function onMessage(data) {
|
|
|
|
console.log(`worker stdout: ${data}`);
|
|
|
|
let response = JSON.parse(data);
|
|
|
|
let taskId = response.__task_id;
|
|
|
|
// let anomalyName = response.anomaly_name;
|
|
|
|
// let task = response.task;
|
|
|
|
let status = response.status;
|
|
|
|
if (status === 'success' || status === 'failed') {
|
|
|
|
if (taskId in taskMap) {
|
|
|
|
let resolver = taskMap[taskId];
|
|
|
|
resolver(response);
|
|
|
|
delete taskMap[taskId];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function runTask(task) {
|
|
|
|
let anomaly = anomalyType_1.loadAnomalyById(task.anomaly_id);
|
|
|
|
task.metric = {
|
|
|
|
datasource: anomaly.metric.datasource,
|
|
|
|
targets: anomaly.metric.targets.map(t => metrics_1.getTarget(t))
|
|
|
|
};
|
|
|
|
task.__task_id = nextTaskId++;
|
|
|
|
let command = JSON.stringify(task);
|
|
|
|
learnWorker.stdin.write(`${command}\n`);
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
taskMap[task.__task_id] = resolve;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function runLearning(anomalyId) {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
let segments = segments_1.getLabeledSegments(anomalyId);
|
|
|
|
anomalyType_1.setAnomalyStatus(anomalyId, 'learning');
|
|
|
|
let anomaly = anomalyType_1.loadAnomalyById(anomalyId);
|
|
|
|
let pattern = anomaly.pattern;
|
|
|
|
let task = {
|
|
|
|
type: 'learn',
|
|
|
|
anomaly_id: anomalyId,
|
|
|
|
pattern,
|
|
|
|
segments: segments
|
|
|
|
};
|
|
|
|
let result = yield runTask(task);
|
|
|
|
if (result.status === 'success') {
|
|
|
|
anomalyType_1.setAnomalyStatus(anomalyId, 'ready');
|
|
|
|
segments_1.insertSegments(anomalyId, result.segments, false);
|
|
|
|
anomalyType_1.setAnomalyPredictionTime(anomalyId, result.last_prediction_time);
|
|
|
|
} else {
|
|
|
|
anomalyType_1.setAnomalyStatus(anomalyId, 'failed', result.error);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
exports.runLearning = runLearning;
|
|
|
|
function runPredict(anomalyId) {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
let anomaly = anomalyType_1.loadAnomalyById(anomalyId);
|
|
|
|
let pattern = anomaly.pattern;
|
|
|
|
let task = {
|
|
|
|
type: 'predict',
|
|
|
|
anomaly_id: anomalyId,
|
|
|
|
pattern,
|
|
|
|
last_prediction_time: anomaly.last_prediction_time
|
|
|
|
};
|
|
|
|
let result = yield runTask(task);
|
|
|
|
if (result.status === 'failed') {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
// Merging segments
|
|
|
|
let segments = segments_1.getLabeledSegments(anomalyId);
|
|
|
|
if (segments.length > 0 && result.segments.length > 0) {
|
|
|
|
let lastOldSegment = segments[segments.length - 1];
|
|
|
|
let firstNewSegment = result.segments[0];
|
|
|
|
if (firstNewSegment.start <= lastOldSegment.finish) {
|
|
|
|
result.segments[0].start = lastOldSegment.start;
|
|
|
|
segments_1.removeSegments(anomalyId, [lastOldSegment.id]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
segments_1.insertSegments(anomalyId, result.segments, false);
|
|
|
|
anomalyType_1.setAnomalyPredictionTime(anomalyId, result.last_prediction_time);
|
|
|
|
return result.segments;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
exports.runPredict = runPredict;
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/services/anomalyType.ts":
|
|
|
|
/*!*************************************!*\
|
|
|
|
!*** ./src/services/anomalyType.ts ***!
|
|
|
|
\*************************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const path = __webpack_require__(/*! path */ "path");
|
|
|
|
const json_1 = __webpack_require__(/*! ./json */ "./src/services/json.ts");
|
|
|
|
const config_1 = __webpack_require__(/*! ../config */ "./src/config.ts");
|
|
|
|
const fs = __webpack_require__(/*! fs */ "fs");
|
|
|
|
const crypto = __webpack_require__(/*! crypto */ "crypto");
|
|
|
|
let anomaliesNameToIdMap = {};
|
|
|
|
function loadAnomaliesMap() {
|
|
|
|
let filename = path.join(config_1.ANOMALIES_PATH, `all_anomalies.json`);
|
|
|
|
if (!fs.existsSync(filename)) {
|
|
|
|
saveAnomaliesMap();
|
|
|
|
}
|
|
|
|
anomaliesNameToIdMap = json_1.getJsonDataSync(filename);
|
|
|
|
}
|
|
|
|
function saveAnomaliesMap() {
|
|
|
|
let filename = path.join(config_1.ANOMALIES_PATH, `all_anomalies.json`);
|
|
|
|
json_1.writeJsonDataSync(filename, anomaliesNameToIdMap);
|
|
|
|
}
|
|
|
|
function getAnomalyIdByName(anomalyName) {
|
|
|
|
loadAnomaliesMap();
|
|
|
|
anomalyName = anomalyName.toLowerCase();
|
|
|
|
if (anomalyName in anomaliesNameToIdMap) {
|
|
|
|
return anomaliesNameToIdMap[anomalyName];
|
|
|
|
}
|
|
|
|
return anomalyName;
|
|
|
|
}
|
|
|
|
exports.getAnomalyIdByName = getAnomalyIdByName;
|
|
|
|
function insertAnomaly(anomaly) {
|
|
|
|
const hashString = anomaly.name + new Date().toString();
|
|
|
|
const anomalyId = crypto.createHash('md5').update(hashString).digest('hex');
|
|
|
|
anomaliesNameToIdMap[anomaly.name] = anomalyId;
|
|
|
|
saveAnomaliesMap();
|
|
|
|
// return anomalyId
|
|
|
|
// const anomalyId:AnomalyId = anomaly.name;
|
|
|
|
let filename = path.join(config_1.ANOMALIES_PATH, `${anomalyId}.json`);
|
|
|
|
if (fs.existsSync(filename)) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
saveAnomaly(anomalyId, anomaly);
|
|
|
|
return anomalyId;
|
|
|
|
}
|
|
|
|
exports.insertAnomaly = insertAnomaly;
|
|
|
|
function removeAnomaly(anomalyId) {
|
|
|
|
let filename = path.join(config_1.ANOMALIES_PATH, `${anomalyId}.json`);
|
|
|
|
fs.unlinkSync(filename);
|
|
|
|
}
|
|
|
|
exports.removeAnomaly = removeAnomaly;
|
|
|
|
function saveAnomaly(anomalyId, anomaly) {
|
|
|
|
let filename = path.join(config_1.ANOMALIES_PATH, `${anomalyId}.json`);
|
|
|
|
return json_1.writeJsonDataSync(filename, anomaly);
|
|
|
|
}
|
|
|
|
exports.saveAnomaly = saveAnomaly;
|
|
|
|
function loadAnomalyById(anomalyId) {
|
|
|
|
let filename = path.join(config_1.ANOMALIES_PATH, `${anomalyId}.json`);
|
|
|
|
if (!fs.existsSync(filename)) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return json_1.getJsonDataSync(filename);
|
|
|
|
}
|
|
|
|
exports.loadAnomalyById = loadAnomalyById;
|
|
|
|
function loadAnomalyByName(anomalyName) {
|
|
|
|
let anomalyId = getAnomalyIdByName(anomalyName);
|
|
|
|
return loadAnomalyById(anomalyId);
|
|
|
|
}
|
|
|
|
exports.loadAnomalyByName = loadAnomalyByName;
|
|
|
|
function saveAnomalyTypeInfo(info) {
|
|
|
|
console.log('Saving');
|
|
|
|
let filename = path.join(config_1.ANOMALIES_PATH, `${info.name}.json`);
|
|
|
|
if (info.next_id === undefined) {
|
|
|
|
info.next_id = 0;
|
|
|
|
}
|
|
|
|
if (info.last_prediction_time === undefined) {
|
|
|
|
info.last_prediction_time = 0;
|
|
|
|
}
|
|
|
|
return json_1.writeJsonDataSync(filename, info);
|
|
|
|
}
|
|
|
|
exports.saveAnomalyTypeInfo = saveAnomalyTypeInfo;
|
|
|
|
function getAnomalyTypeInfo(name) {
|
|
|
|
return json_1.getJsonDataSync(path.join(config_1.ANOMALIES_PATH, `${name}.json`));
|
|
|
|
}
|
|
|
|
exports.getAnomalyTypeInfo = getAnomalyTypeInfo;
|
|
|
|
function setAnomalyStatus(anomalyId, status, error) {
|
|
|
|
let info = loadAnomalyById(anomalyId);
|
|
|
|
info.status = status;
|
|
|
|
if (error !== undefined) {
|
|
|
|
info.error = error;
|
|
|
|
} else {
|
|
|
|
info.error = '';
|
|
|
|
}
|
|
|
|
saveAnomaly(anomalyId, info);
|
|
|
|
}
|
|
|
|
exports.setAnomalyStatus = setAnomalyStatus;
|
|
|
|
function setAnomalyPredictionTime(anomalyId, lastPredictionTime) {
|
|
|
|
let info = loadAnomalyById(anomalyId);
|
|
|
|
info.last_prediction_time = lastPredictionTime;
|
|
|
|
saveAnomaly(anomalyId, info);
|
|
|
|
}
|
|
|
|
exports.setAnomalyPredictionTime = setAnomalyPredictionTime;
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/services/data.ts":
|
|
|
|
/*!******************************!*\
|
|
|
|
!*** ./src/services/data.ts ***!
|
|
|
|
\******************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const config = __webpack_require__(/*! ../config */ "./src/config.ts");
|
|
|
|
const fs = __webpack_require__(/*! fs */ "fs");
|
|
|
|
// see analytics/pattern_detection_model.py with folders available
|
|
|
|
function maybeCreate(path) {
|
|
|
|
if (fs.existsSync(path)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
fs.mkdirSync(path);
|
|
|
|
}
|
|
|
|
function checkDataFolders() {
|
|
|
|
var folders = [config.DATA_PATH, config.DATASETS_PATH, config.ANOMALIES_PATH, config.MODELS_PATH, config.METRICS_PATH, config.SEGMENTS_PATH].forEach(maybeCreate);
|
|
|
|
}
|
|
|
|
exports.checkDataFolders = checkDataFolders;
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/services/json.ts":
|
|
|
|
/*!******************************!*\
|
|
|
|
!*** ./src/services/json.ts ***!
|
|
|
|
\******************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
|
|
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
|
|
function fulfilled(value) {
|
|
|
|
try {
|
|
|
|
step(generator.next(value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function rejected(value) {
|
|
|
|
try {
|
|
|
|
step(generator["throw"](value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function step(result) {
|
|
|
|
result.done ? resolve(result.value) : new P(function (resolve) {
|
|
|
|
resolve(result.value);
|
|
|
|
}).then(fulfilled, rejected);
|
|
|
|
}
|
|
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
|
|
});
|
|
|
|
};
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const fs = __webpack_require__(/*! fs */ "fs");
|
|
|
|
function getJsonData(filename) {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
var data = yield new Promise((resolve, reject) => {
|
|
|
|
fs.readFile(filename, 'utf8', (err, data) => {
|
|
|
|
if (err) {
|
|
|
|
console.error(err);
|
|
|
|
reject('Can`t read file');
|
|
|
|
} else {
|
|
|
|
resolve(data);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
try {
|
|
|
|
return JSON.parse(data);
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
throw new Error('Wrong file format');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
exports.getJsonData = getJsonData;
|
|
|
|
function writeJsonData(filename, data) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
fs.writeFile(filename, JSON.stringify(data), 'utf8', err => {
|
|
|
|
if (err) {
|
|
|
|
console.error(err);
|
|
|
|
reject('Cat`t write file');
|
|
|
|
} else {
|
|
|
|
resolve();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
exports.writeJsonData = writeJsonData;
|
|
|
|
function getJsonDataSync(filename) {
|
|
|
|
let data = fs.readFileSync(filename, 'utf8');
|
|
|
|
try {
|
|
|
|
return JSON.parse(data);
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
throw new Error('Wrong file format');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
exports.getJsonDataSync = getJsonDataSync;
|
|
|
|
function writeJsonDataSync(filename, data) {
|
|
|
|
fs.writeFileSync(filename, JSON.stringify(data));
|
|
|
|
}
|
|
|
|
exports.writeJsonDataSync = writeJsonDataSync;
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/services/metrics.ts":
|
|
|
|
/*!*********************************!*\
|
|
|
|
!*** ./src/services/metrics.ts ***!
|
|
|
|
\*********************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const path = __webpack_require__(/*! path */ "path");
|
|
|
|
const json_1 = __webpack_require__(/*! ./json */ "./src/services/json.ts");
|
|
|
|
const config_1 = __webpack_require__(/*! ../config */ "./src/config.ts");
|
|
|
|
const crypto = __webpack_require__(/*! crypto */ "crypto");
|
|
|
|
function saveTargets(targets) {
|
|
|
|
let metrics = [];
|
|
|
|
for (let target of targets) {
|
|
|
|
metrics.push(saveTarget(target));
|
|
|
|
}
|
|
|
|
return metrics;
|
|
|
|
}
|
|
|
|
exports.saveTargets = saveTargets;
|
|
|
|
function saveTarget(target) {
|
|
|
|
//const md5 = crypto.createHash('md5')
|
|
|
|
const targetId = crypto.createHash('md5').update(JSON.stringify(target)).digest('hex');
|
|
|
|
let filename = path.join(config_1.METRICS_PATH, `${targetId}.json`);
|
|
|
|
json_1.writeJsonDataSync(filename, target);
|
|
|
|
return targetId;
|
|
|
|
}
|
|
|
|
function getTarget(targetId) {
|
|
|
|
let filename = path.join(config_1.METRICS_PATH, `${targetId}.json`);
|
|
|
|
return json_1.getJsonDataSync(filename);
|
|
|
|
}
|
|
|
|
exports.getTarget = getTarget;
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/services/notification.ts":
|
|
|
|
/*!**************************************!*\
|
|
|
|
!*** ./src/services/notification.ts ***!
|
|
|
|
\**************************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
|
|
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
|
|
function fulfilled(value) {
|
|
|
|
try {
|
|
|
|
step(generator.next(value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function rejected(value) {
|
|
|
|
try {
|
|
|
|
step(generator["throw"](value));
|
|
|
|
} catch (e) {
|
|
|
|
reject(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function step(result) {
|
|
|
|
result.done ? resolve(result.value) : new P(function (resolve) {
|
|
|
|
resolve(result.value);
|
|
|
|
}).then(fulfilled, rejected);
|
|
|
|
}
|
|
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
|
|
});
|
|
|
|
};
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const axios_1 = __webpack_require__(/*! axios */ "axios");
|
|
|
|
const anomalyType_1 = __webpack_require__(/*! ./anomalyType */ "./src/services/anomalyType.ts");
|
|
|
|
function sendNotification(anomalyId, active) {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
let anomalyName = anomalyType_1.loadAnomalyById(anomalyId).name;
|
|
|
|
console.log('Notification ' + anomalyName);
|
|
|
|
let notification = {
|
|
|
|
anomaly: anomalyName,
|
|
|
|
status: ''
|
|
|
|
};
|
|
|
|
if (active) {
|
|
|
|
notification.status = 'alert';
|
|
|
|
} else {
|
|
|
|
notification.status = 'OK';
|
|
|
|
}
|
|
|
|
let endpoint = process.env.HASTIC_ALERT_ENDPOINT;
|
|
|
|
if (endpoint === undefined) {
|
|
|
|
console.error(`Can't send alert, env HASTIC_ALERT_ENDPOINT is undefined`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
var data = yield axios_1.default.post(endpoint, {
|
|
|
|
method: 'POST',
|
|
|
|
body: JSON.stringify(notification)
|
|
|
|
});
|
|
|
|
console.log(data);
|
|
|
|
} catch (err) {
|
|
|
|
console.error(`Can't send alert to ${endpoint}. Error: ${err}`);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
exports.sendNotification = sendNotification;
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "./src/services/segments.ts":
|
|
|
|
/*!**********************************!*\
|
|
|
|
!*** ./src/services/segments.ts ***!
|
|
|
|
\**********************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const path = __webpack_require__(/*! path */ "path");
|
|
|
|
const json_1 = __webpack_require__(/*! ./json */ "./src/services/json.ts");
|
|
|
|
const config_1 = __webpack_require__(/*! ../config */ "./src/config.ts");
|
|
|
|
const anomalyType_1 = __webpack_require__(/*! ./anomalyType */ "./src/services/anomalyType.ts");
|
|
|
|
const _ = __webpack_require__(/*! lodash */ "lodash");
|
|
|
|
function getLabeledSegments(anomalyId) {
|
|
|
|
let filename = path.join(config_1.SEGMENTS_PATH, `${anomalyId}_labeled.json`);
|
|
|
|
let segments = [];
|
|
|
|
try {
|
|
|
|
segments = json_1.getJsonDataSync(filename);
|
|
|
|
for (let segment of segments) {
|
|
|
|
if (segment.labeled === undefined) {
|
|
|
|
segment.labeled = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e.message);
|
|
|
|
}
|
|
|
|
return segments;
|
|
|
|
}
|
|
|
|
exports.getLabeledSegments = getLabeledSegments;
|
|
|
|
function getPredictedSegments(anomalyId) {
|
|
|
|
let filename = path.join(config_1.SEGMENTS_PATH, `${anomalyId}_segments.json`);
|
|
|
|
let jsonData;
|
|
|
|
try {
|
|
|
|
jsonData = json_1.getJsonDataSync(filename);
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e.message);
|
|
|
|
jsonData = [];
|
|
|
|
}
|
|
|
|
return jsonData;
|
|
|
|
}
|
|
|
|
exports.getPredictedSegments = getPredictedSegments;
|
|
|
|
function saveSegments(anomalyId, segments) {
|
|
|
|
let filename = path.join(config_1.SEGMENTS_PATH, `${anomalyId}_labeled.json`);
|
|
|
|
try {
|
|
|
|
return json_1.writeJsonDataSync(filename, _.uniqBy(segments, 'start'));
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e.message);
|
|
|
|
throw new Error('Can`t write to db');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
exports.saveSegments = saveSegments;
|
|
|
|
function insertSegments(anomalyId, addedSegments, labeled) {
|
|
|
|
// Set status
|
|
|
|
let info = anomalyType_1.loadAnomalyById(anomalyId);
|
|
|
|
let segments = getLabeledSegments(anomalyId);
|
|
|
|
let nextId = info.next_id;
|
|
|
|
let addedIds = [];
|
|
|
|
for (let segment of addedSegments) {
|
|
|
|
segment.id = nextId;
|
|
|
|
segment.labeled = labeled;
|
|
|
|
addedIds.push(nextId);
|
|
|
|
nextId++;
|
|
|
|
segments.push(segment);
|
|
|
|
}
|
|
|
|
info.next_id = nextId;
|
|
|
|
saveSegments(anomalyId, segments);
|
|
|
|
anomalyType_1.saveAnomaly(anomalyId, info);
|
|
|
|
return addedIds;
|
|
|
|
}
|
|
|
|
exports.insertSegments = insertSegments;
|
|
|
|
function removeSegments(anomalyId, removedSegments) {
|
|
|
|
let segments = getLabeledSegments(anomalyId);
|
|
|
|
for (let segmentId of removedSegments) {
|
|
|
|
segments = segments.filter(el => el.id !== segmentId);
|
|
|
|
}
|
|
|
|
saveSegments(anomalyId, segments);
|
|
|
|
}
|
|
|
|
exports.removeSegments = removeSegments;
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ 0:
|
|
|
|
/*!****************************!*\
|
|
|
|
!*** multi ./src/index.ts ***!
|
|
|
|
\****************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
module.exports = __webpack_require__(/*! ./src/index.ts */"./src/index.ts");
|
|
|
|
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "axios":
|
|
|
|
/*!***********************************!*\
|
|
|
|
!*** external "require('axios')" ***!
|
|
|
|
\***********************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
module.exports = require('axios');
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "child_process":
|
|
|
|
/*!*******************************************!*\
|
|
|
|
!*** external "require('child_process')" ***!
|
|
|
|
\*******************************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
module.exports = require('child_process');
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "crypto":
|
|
|
|
/*!************************************!*\
|
|
|
|
!*** external "require('crypto')" ***!
|
|
|
|
\************************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
module.exports = require('crypto');
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "event-stream":
|
|
|
|
/*!******************************************!*\
|
|
|
|
!*** external "require('event-stream')" ***!
|
|
|
|
\******************************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
module.exports = require('event-stream');
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "fs":
|
|
|
|
/*!********************************!*\
|
|
|
|
!*** external "require('fs')" ***!
|
|
|
|
\********************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
module.exports = require('fs');
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "koa":
|
|
|
|
/*!*********************************!*\
|
|
|
|
!*** external "require('koa')" ***!
|
|
|
|
\*********************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
module.exports = require('koa');
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "koa-bodyparser":
|
|
|
|
/*!********************************************!*\
|
|
|
|
!*** external "require('koa-bodyparser')" ***!
|
|
|
|
\********************************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
module.exports = require('koa-bodyparser');
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "koa-router":
|
|
|
|
/*!****************************************!*\
|
|
|
|
!*** external "require('koa-router')" ***!
|
|
|
|
\****************************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
module.exports = require('koa-router');
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "lodash":
|
|
|
|
/*!************************************!*\
|
|
|
|
!*** external "require('lodash')" ***!
|
|
|
|
\************************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
module.exports = require('lodash');
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
|
|
|
|
/***/ "path":
|
|
|
|
/*!**********************************!*\
|
|
|
|
!*** external "require('path')" ***!
|
|
|
|
\**********************************/
|
|
|
|
/*! no static exports found */
|
|
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
module.exports = require('path');
|
|
|
|
|
|
|
|
/***/ })
|
|
|
|
|
|
|
|
/******/ });
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbmZpZy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JvdXRlcy9hbGVydHMudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JvdXRlcy9hbm9tYWxpZXMudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JvdXRlcy9zZWdtZW50cy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvc2VydmljZXMvYWxlcnRzLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9hbmFseXRpY3MudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3NlcnZpY2VzL2Fub21hbHlUeXBlLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9kYXRhLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9qc29uLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9tZXRyaWNzLnRzIiwid2VicGFjazovLy8uL3NyYy9zZXJ2aWNlcy9ub3RpZmljYXRpb24udHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3NlcnZpY2VzL3NlZ21lbnRzLnRzIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2F4aW9zJylcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZXF1aXJlKCdjaGlsZF9wcm9jZXNzJylcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZXF1aXJlKCdjcnlwdG8nKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2V2ZW50LXN0cmVhbScpXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVxdWlyZSgnZnMnKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2tvYScpXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVxdWlyZSgna29hLWJvZHlwYXJzZXInKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2tvYS1yb3V0ZXInKVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlcXVpcmUoJ2xvZGFzaCcpXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVxdWlyZSgncGF0aCcpXCIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0RBQTBDLGdDQUFnQztBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGdFQUF3RCxrQkFBa0I7QUFDMUU7QUFDQSx5REFBaUQsY0FBYztBQUMvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQXlDLGlDQUFpQztBQUMxRSx3SEFBZ0gsbUJBQW1CLEVBQUU7QUFDckk7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7O0FBR0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ2xGQTtBQUVhLHlCQUFpQixLQUFLLElBQUwsQ0FBVSxTQUFWLEVBQXFCLGlCQUFyQixDQUFqQjtBQUVBLG9CQUFZLEtBQUssSUFBTCxDQUFVLFNBQVYsRUFBcUIsWUFBckIsQ0FBWjtBQUVBLHdCQUFnQixLQUFLLElBQUwsQ0FBVSxpQkFBVixFQUFxQixVQUFyQixDQUFoQjtBQUNBLHlCQUFpQixLQUFLLElBQUwsQ0FBVSxpQkFBVixFQUFxQixXQUFyQixDQUFqQjtBQUNBLHNCQUFjLEtBQUssSUFBTCxDQUFVLGlCQUFWLEVBQXFCLFFBQXJCLENBQWQ7QUFDQSx1QkFBZSxLQUFLLElBQUwsQ0FBVSxpQkFBVixFQUFxQixTQUFyQixDQUFmO0FBQ0Esd0JBQWdCLEtBQUssSUFBTCxDQUFVLGlCQUFWLEVBQXFCLFVBQXJCLENBQWhCLEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ1ZiO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQSxJQUFJLE1BQU0sSUFBSSxHQUFKLEVBQVY7QUFDQSxNQUFNLE9BQU8sUUFBUSxHQUFSLENBQVksV0FBWixJQUEyQixJQUF4QztBQUVBLElBQUksR0FBSixDQUFRLFlBQVI7QUFFQSxJQUFJLEdBQUosQ0FBUSxVQUFlLEdBQWYsRUFBb0IsSUFBcEIsRUFBd0I7O0FBQzlCLFlBQUksR0FBSixDQUFRLDZCQUFSLEVBQXVDLEdBQXZDO0FBQ0EsWUFBSSxHQUFKLENBQVEsOEJBQVIsRUFBd0Msd0NBQXhDO0FBQ0EsWUFBSSxHQUFKLENBQVEsOEJBQVIsRUFBd0MsZ0RBQXhDO0FBQ0E7QUFDRCxLO0FBQUEsQ0FMRDtBQVFBLElBQUksYUFBYSxJQUFJLE1BQUosRUFBakI7QUFDQSxXQUFXLEdBQVgsQ0FBZSxZQUFmLEVBQTZCLG1CQUFnQixNQUFoQixFQUE3QixFQUF1RCxtQkFBZ0IsY0FBaEIsRUFBdkQ7QUFDQSxXQUFXLEdBQVgsQ0FBZSxXQUFmLEVBQTRCLGtCQUFlLE1BQWYsRUFBNUIsRUFBcUQsa0JBQWUsY0FBZixFQUFyRDtBQUNBLFdBQVcsR0FBWCxDQUFlLFNBQWYsRUFBMEIsZ0JBQWEsTUFBYixFQUExQixFQUFpRCxnQkFBYSxjQUFiLEVBQWpEO0FBQ0EsV0FBVyxHQUFYLENBQWUsR0FBZixFQUEyQixHQUFQLElBQWM7QUFDaEMsUUFBSSxRQUFKLENBQWEsSUFBYixHQUFvQixFQUFFLFFBQVEsT0FBVixFQUFwQjtBQUNELENBRmlDLENBQWxDO0FBSUEsSUFDRyxHQURILENBQ08sV0FBVyxNQUFYLEVBRFAsRUFFRyxHQUZILENBRU8sV0FBVyxjQUFYLEVBRlA7QUFJQSxJQUFJLE1BQUosQ0FBVyxJQUFYLEVBQWlCLE1BQUs7QUFDcEIsWUFBUSxHQUFSLENBQVkseUJBQXlCLElBQUksRUFBekM7QUFDRCxDQUZELEU7Ozs7Ozs7Ozs7Ozs7OztBQ3RDQTtBQUNBO0FBRUE7QUFHQSxrQkFBa0IsR0FBbEIsRUFBNEM7QUFFMUMsUUFBSSxZQUF1QixJQUFJLE9BQUosQ0FBWSxLQUFaLENBQWtCLFVBQTdDO0FBQ0EsUUFBSSxVQUFVLDhCQUFnQixTQUFoQixDQUFkO0FBQ0EsUUFBRyxXQUFXLElBQWQsRUFBb0I7QUFDbEIsb0JBQVksaUNBQW1CLFVBQVUsV0FBVixFQUFuQixDQUFaO0FBQ0Q7QUFFRCxRQUFJLGtCQUFrQiw2QkFBdEI7QUFDQSxRQUFJLE1BQU0sZ0JBQWdCLE9BQWhCLENBQXdCLFNBQXhCLEN
|