Browse Source

Change anomaly id to predictor id everywhere (#65)

* Change anomaly id to predictor id everywhere

* some fiex
pull/1/head
rozetko 6 years ago committed by Alexey Velikiy
parent
commit
e85df8c2c1
  1. 3
      README.md
  2. 16
      REST.md
  3. 12
      analytics/pattern_detection_model.py
  4. 2
      analytics/server.py
  5. 34
      analytics/worker.py
  6. 20
      server/src/routes/alerts.ts
  7. 10
      server/src/routes/anomalies.ts
  8. 22
      server/src/routes/segments.ts
  9. 26
      server/src/services/alerts.ts
  10. 38
      server/src/services/analytics.ts
  11. 50
      server/src/services/anomalyType.ts
  12. 2
      server/src/services/data.ts
  13. 4
      server/src/services/notification.ts
  14. 30
      server/src/services/segments.ts

3
README.md

@ -95,6 +95,9 @@ docker run -d --name hastic-server -p 80:8000 -e HASTIC_API_KEY=<your_grafana_ap
### Changelog ### Changelog
### [0.2.0-alpha] - Not released yet
`Please note: hastic-panels of older versions are not supported`
### [0.1.4-alpha] - 2018-06-29 ### [0.1.4-alpha] - 2018-06-29
#### Changed #### Changed
- Informative error messages instead of "Internal error" [#40](https://github.com/hastic/hastic-server/issues/33) - Informative error messages instead of "Internal error" [#40](https://github.com/hastic/hastic-server/issues/33)

16
REST.md

@ -3,7 +3,7 @@
## /anomalies ## /anomalies
### Get anomalies ### Get anomalies
`GET /anomalies?id=<anomaly_id>[&name=<anomaly_name>]` `GET /anomalies?id=<predictor_id>[&name=<anomaly_name>]`
NOTE: `name` param is deprecated, use `id` instead NOTE: `name` param is deprecated, use `id` instead
@ -24,7 +24,7 @@ status field can be one of:
- `failed` - `failed`
### Get anomaly status ### Get anomaly status
`GET /anomalies/status?id=<anomaly_id>[&name=<anomaly_name>]` `GET /anomalies/status?id=<predictor_id>[&name=<anomaly_name>]`
NOTE: `name` param is deprecated, use `id` instead NOTE: `name` param is deprecated, use `id` instead
@ -102,7 +102,7 @@ Return data format:
``` ```
{ {
"anomaly_id": "<anomaly_id>" "predictor_id": "<predictor_id>"
} }
``` ```
@ -113,7 +113,7 @@ Data format:
``` ```
{ {
"id": "<anomaly_id>", "id": "<predictor_id>",
"name": "<anomaly_name>" // deprecated, use id instead "name": "<anomaly_name>" // deprecated, use id instead
} }
``` ```
@ -127,7 +127,7 @@ Success
## /segments ## /segments
### Get segments ### Get segments
`GET /segments?anomaly_id=<anomaly_id>[&last_segment=<id>][&from=<time_from>][&to=<time_to>]` `GET /segments?predictor_id=<predictor_id>[&last_segment=<id>][&from=<time_from>][&to=<time_to>]`
Return data format: Return data format:
@ -153,7 +153,7 @@ Data format:
``` ```
{ {
"anomaly_id": "<anomaly_id>", "predictor_id": "<predictor_id>",
"name": "<anomaly_name>", // deprecated, use id instead "name": "<anomaly_name>", // deprecated, use id instead
"added_segments": [ "added_segments": [
{ {
@ -178,7 +178,7 @@ Return data format:
### Check if alert is enabled for anomaly ### Check if alert is enabled for anomaly
`GET /alerts?anomaly_id=<anomaly_id>` `GET /alerts?predictor_id=<predictor_id>`
Return data format: Return data format:
@ -196,7 +196,7 @@ Data format:
``` ```
{ {
"anomaly_id": "<anomaly_id>", "predictor_id": "<predictor_id>",
"enable": true "enable": true
} }
``` ```

12
analytics/pattern_detection_model.py

@ -24,8 +24,8 @@ def segments_box(segments):
class PatternDetectionModel: class PatternDetectionModel:
def __init__(self, anomaly_id, pattern): def __init__(self, predictor_id, pattern):
self.anomaly_id = anomaly_id self.predictor_id = predictor_id
self.pattern = pattern self.pattern = pattern
self.__load_anomaly_config() self.__load_anomaly_config()
@ -101,16 +101,16 @@ class PatternDetectionModel:
return StepDetector(pattern) return StepDetector(pattern)
def __load_anomaly_config(self): def __load_anomaly_config(self):
with open(os.path.join(config.ANOMALIES_FOLDER, self.anomaly_id + ".json"), 'r') as config_file: with open(os.path.join(config.ANOMALIES_FOLDER, self.predictor_id + ".json"), 'r') as config_file:
self.anomaly_config = json.load(config_file) self.anomaly_config = json.load(config_file)
def __save_model(self): def __save_model(self):
logger.info("Save model '%s'" % self.anomaly_id) logger.info("Save model '%s'" % self.predictor_id)
model_filename = os.path.join(config.MODELS_FOLDER, self.anomaly_id + ".m") model_filename = os.path.join(config.MODELS_FOLDER, self.predictor_id + ".m")
self.model.save(model_filename) self.model.save(model_filename)
def __load_model(self, pattern): def __load_model(self, pattern):
logger.info("Load model '%s'" % self.anomaly_id) logger.info("Load model '%s'" % self.predictor_id)
model_filename = os.path.join(config.MODELS_FOLDER, self.pattern + ".m") model_filename = os.path.join(config.MODELS_FOLDER, self.pattern + ".m")
if os.path.exists(model_filename): if os.path.exists(model_filename):
self.model = self.__create_model(pattern) self.model = self.__create_model(pattern)

2
analytics/server.py

@ -28,7 +28,7 @@ def handleTask(text):
socket.send_string(json.dumps({ socket.send_string(json.dumps({
'task': task['type'], 'task': task['type'],
'anomaly_id': task['anomaly_id'], 'predictor_id': task['predictor_id'],
'__task_id': task['__task_id'], '__task_id': task['__task_id'],
'status': "in progress" 'status': "in progress"
})) }))

34
analytics/worker.py

@ -41,15 +41,15 @@ class Worker(object):
def do_task(self, task): def do_task(self, task):
try: try:
type = task['type'] type = task['type']
anomaly_id = task['anomaly_id'] predictor_id = task['predictor_id']
if type == "predict": if type == "predict":
last_prediction_time = task['last_prediction_time'] last_prediction_time = task['last_prediction_time']
pattern = task['pattern'] pattern = task['pattern']
result = self.do_predict(anomaly_id, last_prediction_time, pattern) result = self.do_predict(predictor_id, last_prediction_time, pattern)
elif type == "learn": elif type == "learn":
segments = task['segments'] segments = task['segments']
pattern = task['pattern'] pattern = task['pattern']
result = self.do_learn(anomaly_id, segments, pattern) result = self.do_learn(predictor_id, segments, pattern)
else: else:
result = { result = {
'status': "failed", 'status': "failed",
@ -62,48 +62,48 @@ class Worker(object):
result = { result = {
'task': type, 'task': type,
'status': "failed", 'status': "failed",
'anomaly_id': anomaly_id, 'predictor_id': predictor_id,
'error': str(e) 'error': str(e)
} }
return result return result
def do_learn(self, anomaly_id, segments, pattern): def do_learn(self, predictor_id, segments, pattern):
model = self.get_model(anomaly_id, pattern) model = self.get_model(predictor_id, pattern)
model.synchronize_data() model.synchronize_data()
last_prediction_time = model.learn(segments) last_prediction_time = model.learn(segments)
# TODO: we should not do predict before labeling in all models, not just in drops # TODO: we should not do predict before labeling in all models, not just in drops
if pattern == 'drops' and len(segments) == 0: if pattern == 'drops' and len(segments) == 0:
result = { result = {
'status': 'success', 'status': 'success',
'anomaly_id': anomaly_id, 'predictor_id': predictor_id,
'segments': [], 'segments': [],
'last_prediction_time': last_prediction_time 'last_prediction_time': last_prediction_time
} }
else: else:
result = self.do_predict(anomaly_id, last_prediction_time, pattern) result = self.do_predict(predictor_id, last_prediction_time, pattern)
result['task'] = 'learn' result['task'] = 'learn'
return result return result
def do_predict(self, anomaly_id, last_prediction_time, pattern): def do_predict(self, predictor_id, last_prediction_time, pattern):
model = self.get_model(anomaly_id, pattern) model = self.get_model(predictor_id, pattern)
model.synchronize_data() model.synchronize_data()
segments, last_prediction_time = model.predict(last_prediction_time) segments, last_prediction_time = model.predict(last_prediction_time)
return { return {
'task': "predict", 'task': "predict",
'status': "success", 'status': "success",
'anomaly_id': anomaly_id, 'predictor_id': predictor_id,
'segments': segments, 'segments': segments,
'last_prediction_time': last_prediction_time 'last_prediction_time': last_prediction_time
} }
def get_model(self, anomaly_id, pattern): def get_model(self, predictor_id, pattern):
if anomaly_id not in self.models_cache: if predictor_id not in self.models_cache:
if pattern.find('general') != -1: if pattern.find('general') != -1:
model = AnomalyModel(anomaly_id) model = AnomalyModel(predictor_id)
else: else:
model = PatternDetectionModel(anomaly_id, pattern) model = PatternDetectionModel(predictor_id, pattern)
self.models_cache[anomaly_id] = model self.models_cache[predictor_id] = model
return self.models_cache[anomaly_id] return self.models_cache[predictor_id]

20
server/src/routes/alerts.ts

@ -1,4 +1,4 @@
import { AnomalyId, getAnomalyIdByName, loadAnomalyById } from '../services/anomalyType'; import { PredictorId, getPredictorIdByName, loadAnomalyById } from '../services/anomalyType';
import { getAlertsAnomalies, saveAlertsAnomalies } from '../services/alerts'; import { getAlertsAnomalies, saveAlertsAnomalies } from '../services/alerts';
import * as Router from 'koa-router'; import * as Router from 'koa-router';
@ -6,14 +6,14 @@ import * as Router from 'koa-router';
function getAlert(ctx: Router.IRouterContext) { function getAlert(ctx: Router.IRouterContext) {
let anomalyId: AnomalyId = ctx.request.query.anomaly_id.toLowerCase(); let predictorId: PredictorId = ctx.request.query.predictor_id.toLowerCase();
let anomaly = loadAnomalyById(anomalyId) let anomaly = loadAnomalyById(predictorId)
if(anomaly == null) { if(anomaly == null) {
anomalyId = getAnomalyIdByName(anomalyId); predictorId = getPredictorIdByName(predictorId);
} }
let alertsAnomalies = getAlertsAnomalies(); let alertsAnomalies = getAlertsAnomalies();
let pos = alertsAnomalies.indexOf(anomalyId); let pos = alertsAnomalies.indexOf(predictorId);
let enable: boolean = (pos !== -1); let enable: boolean = (pos !== -1);
ctx.response.body = { enable }; ctx.response.body = { enable };
@ -22,18 +22,18 @@ function getAlert(ctx: Router.IRouterContext) {
function changeAlert(ctx: Router.IRouterContext) { function changeAlert(ctx: Router.IRouterContext) {
let anomalyId: AnomalyId = ctx.request.body.anomaly_id.toLowerCase(); let predictorId: PredictorId = ctx.request.body.predictor_id.toLowerCase();
let enable: boolean = ctx.request.body.enable; let enable: boolean = ctx.request.body.enable;
let anomaly = loadAnomalyById(anomalyId) let anomaly = loadAnomalyById(predictorId)
if(anomaly == null) { if(anomaly == null) {
anomalyId = getAnomalyIdByName(anomalyId); predictorId = getPredictorIdByName(predictorId);
} }
let alertsAnomalies = getAlertsAnomalies(); let alertsAnomalies = getAlertsAnomalies();
let pos: number = alertsAnomalies.indexOf(anomalyId); let pos: number = alertsAnomalies.indexOf(predictorId);
if(enable && pos == -1) { if(enable && pos == -1) {
alertsAnomalies.push(anomalyId); alertsAnomalies.push(predictorId);
saveAlertsAnomalies(alertsAnomalies); saveAlertsAnomalies(alertsAnomalies);
} else if(!enable && pos > -1) { } else if(!enable && pos > -1) {
alertsAnomalies.splice(pos, 1); alertsAnomalies.splice(pos, 1);

10
server/src/routes/anomalies.ts

@ -5,7 +5,7 @@ import {
Metric, Metric,
Anomaly, Anomaly,
saveAnomaly, saveAnomaly,
insertAnomaly, removeAnomaly, loadAnomalyByName, loadAnomalyById, getAnomalyIdByName insertAnomaly, removeAnomaly, loadAnomalyByName, loadAnomalyById, getPredictorIdByName
} from '../services/anomalyType'; } from '../services/anomalyType';
import { runLearning } from '../services/analytics' import { runLearning } from '../services/analytics'
import { saveTargets } from '../services/metrics'; import { saveTargets } from '../services/metrics';
@ -84,8 +84,8 @@ async function createAnomaly(ctx: Router.IRouterContext) {
last_prediction_time: 0, last_prediction_time: 0,
next_id: 0 next_id: 0
}; };
let anomalyId = insertAnomaly(anomaly); let predictorId = insertAnomaly(anomaly);
if(anomalyId === null) { if(predictorId === null) {
ctx.response.status = 403; ctx.response.status = 403;
ctx.response.body = { ctx.response.body = {
code: 403, code: 403,
@ -93,9 +93,9 @@ async function createAnomaly(ctx: Router.IRouterContext) {
}; };
} }
ctx.response.body = { anomaly_id: anomalyId }; ctx.response.body = { predictor_id: predictorId };
runLearning(anomalyId); runLearning(predictorId);
} catch(e) { } catch(e) {
ctx.response.status = 500; ctx.response.status = 500;
ctx.response.body = { ctx.response.body = {

22
server/src/routes/segments.ts

@ -7,7 +7,7 @@ import {
} from '../services/segments'; } from '../services/segments';
import { import {
Anomaly, AnomalyId, getAnomalyIdByName, loadAnomalyById Anomaly, PredictorId, getPredictorIdByName, loadAnomalyById
} from '../services/anomalyType'; } from '../services/anomalyType';
import { runLearning } from '../services/analytics'; import { runLearning } from '../services/analytics';
@ -15,17 +15,17 @@ import { runLearning } from '../services/analytics';
async function sendSegments(ctx: Router.IRouterContext) { async function sendSegments(ctx: Router.IRouterContext) {
let anomalyId: AnomalyId = ctx.request.query.anomaly_id.toLowerCase(); let predictorId: PredictorId = ctx.request.query.predictor_id.toLowerCase();
let anomaly:Anomaly = loadAnomalyById(anomalyId); let anomaly:Anomaly = loadAnomalyById(predictorId);
if(anomaly === null) { if(anomaly === null) {
anomalyId = getAnomalyIdByName(anomalyId); predictorId = getPredictorIdByName(predictorId);
} }
let lastSegmentId = ctx.request.query.last_segment; let lastSegmentId = ctx.request.query.last_segment;
let timeFrom = ctx.request.query.from; let timeFrom = ctx.request.query.from;
let timeTo = ctx.request.query.to; let timeTo = ctx.request.query.to;
let segments = getLabeledSegments(anomalyId); let segments = getLabeledSegments(predictorId);
// Id filtering // Id filtering
if(lastSegmentId !== undefined) { if(lastSegmentId !== undefined) {
@ -49,19 +49,19 @@ async function updateSegments(ctx: Router.IRouterContext) {
try { try {
let segmentsUpdate = ctx.request.body; let segmentsUpdate = ctx.request.body;
let anomalyId = segmentsUpdate.anomaly_id; let predictorId = segmentsUpdate.predictor_id;
let anomalyName = segmentsUpdate.name.toLowerCase(); let anomalyName = segmentsUpdate.name.toLowerCase();
if(anomalyId === undefined) { if(predictorId === undefined) {
anomalyId = getAnomalyIdByName(anomalyName); predictorId = getPredictorIdByName(anomalyName);
} }
let addedIds = insertSegments(anomalyId, segmentsUpdate.added_segments, true); let addedIds = insertSegments(predictorId, segmentsUpdate.added_segments, true);
removeSegments(anomalyId, segmentsUpdate.removed_segments); removeSegments(predictorId, segmentsUpdate.removed_segments);
ctx.response.body = { added_ids: addedIds }; ctx.response.body = { added_ids: addedIds };
runLearning(anomalyId); runLearning(predictorId);
} catch(e) { } catch(e) {
ctx.response.status = 500; ctx.response.status = 500;
ctx.response.body = { ctx.response.body = {

26
server/src/services/alerts.ts

@ -1,5 +1,5 @@
import { getJsonDataSync, writeJsonDataSync } from './json'; import { getJsonDataSync, writeJsonDataSync } from './json';
import { AnomalyId } from './anomalyType'; import { PredictorId } from './anomalyType';
import { runPredict } from './analytics'; import { runPredict } from './analytics';
import { sendNotification } from './notification'; import { sendNotification } from './notification';
import { getLabeledSegments } from './segments'; import { getLabeledSegments } from './segments';
@ -13,22 +13,22 @@ import * as fs from 'fs';
const ALERTS_DB_PATH = path.join(ANOMALIES_PATH, `alerts_anomalies.json`); const ALERTS_DB_PATH = path.join(ANOMALIES_PATH, `alerts_anomalies.json`);
function getAlertsAnomalies(): AnomalyId[] { function getAlertsAnomalies(): PredictorId[] {
if(!fs.existsSync(ALERTS_DB_PATH)) { if(!fs.existsSync(ALERTS_DB_PATH)) {
saveAlertsAnomalies([]); saveAlertsAnomalies([]);
} }
return getJsonDataSync(ALERTS_DB_PATH); return getJsonDataSync(ALERTS_DB_PATH);
} }
function saveAlertsAnomalies(anomalies: AnomalyId[]) { function saveAlertsAnomalies(anomalies: PredictorId[]) {
return writeJsonDataSync(ALERTS_DB_PATH, anomalies); return writeJsonDataSync(ALERTS_DB_PATH, anomalies);
} }
function processAlerts(anomalyId) { function processAlerts(predictorId) {
let segments = getLabeledSegments(anomalyId); let segments = getLabeledSegments(predictorId);
const currentTime = new Date().getTime(); const currentTime = new Date().getTime();
const activeAlert = activeAlerts.has(anomalyId); const activeAlert = activeAlerts.has(predictorId);
let newActiveAlert = false; let newActiveAlert = false;
if(segments.length > 0) { if(segments.length > 0) {
@ -39,20 +39,20 @@ function processAlerts(anomalyId) {
} }
if(!activeAlert && newActiveAlert) { if(!activeAlert && newActiveAlert) {
activeAlerts.add(anomalyId); activeAlerts.add(predictorId);
sendNotification(anomalyId, true); sendNotification(predictorId, true);
} else if(activeAlert && !newActiveAlert) { } else if(activeAlert && !newActiveAlert) {
activeAlerts.delete(anomalyId); activeAlerts.delete(predictorId);
sendNotification(anomalyId, false); sendNotification(predictorId, false);
} }
} }
async function alertsTick() { async function alertsTick() {
let alertsAnomalies = getAlertsAnomalies(); let alertsAnomalies = getAlertsAnomalies();
for (let anomalyId of alertsAnomalies) { for (let predictorId of alertsAnomalies) {
try { try {
await runPredict(anomalyId); await runPredict(predictorId);
processAlerts(anomalyId); processAlerts(predictorId);
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }

38
server/src/services/analytics.ts

@ -1,6 +1,6 @@
import { import {
Anomaly, Anomaly,
AnomalyId, getAnomalyTypeInfo, PredictorId, getAnomalyTypeInfo,
loadAnomalyById, loadAnomalyById,
setAnomalyPredictionTime, setAnomalyPredictionTime,
setAnomalyStatus setAnomalyStatus
@ -28,7 +28,7 @@ function onResponse(response: any) {
} }
async function runTask(task): Promise<any> { async function runTask(task): Promise<any> {
let anomaly: Anomaly = loadAnomalyById(task.anomaly_id); let anomaly: Anomaly = loadAnomalyById(task.predictor_id);
task.metric = { task.metric = {
datasource: anomaly.metric.datasource, datasource: anomaly.metric.datasource,
targets: anomaly.metric.targets.map(t => getTarget(t)) targets: anomaly.metric.targets.map(t => getTarget(t))
@ -42,14 +42,14 @@ async function runTask(task): Promise<any> {
}) })
} }
export async function runLearning(anomalyId:AnomalyId) { export async function runLearning(predictorId:PredictorId) {
let segments = getLabeledSegments(anomalyId); let segments = getLabeledSegments(predictorId);
setAnomalyStatus(anomalyId, 'learning'); setAnomalyStatus(predictorId, 'learning');
let anomaly:Anomaly = loadAnomalyById(anomalyId); let anomaly:Anomaly = loadAnomalyById(predictorId);
let pattern = anomaly.pattern; let pattern = anomaly.pattern;
let task = { let task = {
type: 'learn', type: 'learn',
anomaly_id: anomalyId, predictor_id: predictorId,
pattern, pattern,
segments: segments segments: segments
}; };
@ -57,20 +57,20 @@ export async function runLearning(anomalyId:AnomalyId) {
let result = await runTask(task); let result = await runTask(task);
if (result.status === 'success') { if (result.status === 'success') {
setAnomalyStatus(anomalyId, 'ready'); setAnomalyStatus(predictorId, 'ready');
insertSegments(anomalyId, result.segments, false); insertSegments(predictorId, result.segments, false);
setAnomalyPredictionTime(anomalyId, result.last_prediction_time); setAnomalyPredictionTime(predictorId, result.last_prediction_time);
} else { } else {
setAnomalyStatus(anomalyId, 'failed', result.error); setAnomalyStatus(predictorId, 'failed', result.error);
} }
} }
export async function runPredict(anomalyId:AnomalyId) { export async function runPredict(predictorId:PredictorId) {
let anomaly:Anomaly = loadAnomalyById(anomalyId); let anomaly:Anomaly = loadAnomalyById(predictorId);
let pattern = anomaly.pattern; let pattern = anomaly.pattern;
let task = { let task = {
type: 'predict', type: 'predict',
anomaly_id: anomalyId, predictor_id: predictorId,
pattern, pattern,
last_prediction_time: anomaly.last_prediction_time last_prediction_time: anomaly.last_prediction_time
}; };
@ -80,18 +80,18 @@ export async function runPredict(anomalyId:AnomalyId) {
return []; return [];
} }
// Merging segments // Merging segments
let segments = getLabeledSegments(anomalyId); let segments = getLabeledSegments(predictorId);
if(segments.length > 0 && result.segments.length > 0) { if(segments.length > 0 && result.segments.length > 0) {
let lastOldSegment = segments[segments.length - 1]; let lastOldSegment = segments[segments.length - 1];
let firstNewSegment = result.segments[0]; let firstNewSegment = result.segments[0];
if(firstNewSegment.start <= lastOldSegment.finish) { if(firstNewSegment.start <= lastOldSegment.finish) {
result.segments[0].start = lastOldSegment.start; result.segments[0].start = lastOldSegment.start;
removeSegments(anomalyId, [lastOldSegment.id]); removeSegments(predictorId, [lastOldSegment.id]);
} }
} }
insertSegments(anomalyId, result.segments, false); insertSegments(predictorId, result.segments, false);
setAnomalyPredictionTime(anomalyId, result.last_prediction_time); setAnomalyPredictionTime(predictorId, result.last_prediction_time);
return result.segments; return result.segments;
} }

50
server/src/services/anomalyType.ts

@ -32,7 +32,7 @@ export type Anomaly = {
next_id: number next_id: number
} }
export type AnomalyId = string; export type PredictorId = string;
let anomaliesNameToIdMap = {}; let anomaliesNameToIdMap = {};
@ -49,7 +49,7 @@ function saveAnomaliesMap() {
writeJsonDataSync(filename, anomaliesNameToIdMap); writeJsonDataSync(filename, anomaliesNameToIdMap);
} }
function getAnomalyIdByName(anomalyName:string) : AnomalyId { function getPredictorIdByName(anomalyName:string): PredictorId {
loadAnomaliesMap(); loadAnomaliesMap();
anomalyName = anomalyName.toLowerCase(); anomalyName = anomalyName.toLowerCase();
if(anomalyName in anomaliesNameToIdMap) { if(anomalyName in anomaliesNameToIdMap) {
@ -58,42 +58,40 @@ function getAnomalyIdByName(anomalyName:string) : AnomalyId {
return anomalyName; return anomalyName;
} }
function insertAnomaly(anomaly: Anomaly) : AnomalyId { function insertAnomaly(anomaly: Anomaly): PredictorId {
const hashString = anomaly.name + (new Date()).toString(); const hashString = anomaly.name + (new Date()).toString();
const anomalyId:AnomalyId = crypto.createHash('md5').update(hashString).digest('hex'); const predictorId:PredictorId = crypto.createHash('md5').update(hashString).digest('hex');
anomaliesNameToIdMap[anomaly.name] = anomalyId; anomaliesNameToIdMap[anomaly.name] = predictorId;
saveAnomaliesMap(); saveAnomaliesMap();
// return anomalyId let filename = path.join(ANOMALIES_PATH, `${predictorId}.json`);
// const anomalyId:AnomalyId = anomaly.name;
let filename = path.join(ANOMALIES_PATH, `${anomalyId}.json`);
if(fs.existsSync(filename)) { if(fs.existsSync(filename)) {
return null; return null;
} }
saveAnomaly(anomalyId, anomaly); saveAnomaly(predictorId, anomaly);
return anomalyId; return predictorId;
} }
function removeAnomaly(anomalyId:AnomalyId) { function removeAnomaly(predictorId: PredictorId) {
let filename = path.join(ANOMALIES_PATH, `${anomalyId}.json`); let filename = path.join(ANOMALIES_PATH, `${predictorId}.json`);
fs.unlinkSync(filename); fs.unlinkSync(filename);
} }
function saveAnomaly(anomalyId: AnomalyId, anomaly: Anomaly) { function saveAnomaly(predictorId: PredictorId, anomaly: Anomaly) {
let filename = path.join(ANOMALIES_PATH, `${anomalyId}.json`); let filename = path.join(ANOMALIES_PATH, `${predictorId}.json`);
return writeJsonDataSync(filename, anomaly); return writeJsonDataSync(filename, anomaly);
} }
function loadAnomalyById(anomalyId: AnomalyId) : Anomaly { function loadAnomalyById(predictorId: PredictorId): Anomaly {
let filename = path.join(ANOMALIES_PATH, `${anomalyId}.json`); let filename = path.join(ANOMALIES_PATH, `${predictorId}.json`);
if(!fs.existsSync(filename)) { if(!fs.existsSync(filename)) {
return null; return null;
} }
return getJsonDataSync(filename); return getJsonDataSync(filename);
} }
function loadAnomalyByName(anomalyName: string) : Anomaly { function loadAnomalyByName(anomalyName: string): Anomaly {
let anomalyId = getAnomalyIdByName(anomalyName); let predictorId = getPredictorIdByName(anomalyName);
return loadAnomalyById(anomalyId); return loadAnomalyById(predictorId);
} }
function saveAnomalyTypeInfo(info) { function saveAnomalyTypeInfo(info) {
@ -113,24 +111,24 @@ function getAnomalyTypeInfo(name) {
return getJsonDataSync(path.join(ANOMALIES_PATH, `${name}.json`)); return getJsonDataSync(path.join(ANOMALIES_PATH, `${name}.json`));
} }
function setAnomalyStatus(anomalyId:AnomalyId, status:string, error?:string) { function setAnomalyStatus(predictorId: PredictorId, status: string, error?: string) {
let info = loadAnomalyById(anomalyId); let info = loadAnomalyById(predictorId);
info.status = status; info.status = status;
if(error !== undefined) { if(error !== undefined) {
info.error = error; info.error = error;
} else { } else {
info.error = ''; info.error = '';
} }
saveAnomaly(anomalyId, info); saveAnomaly(predictorId, info);
} }
function setAnomalyPredictionTime(anomalyId:AnomalyId, lastPredictionTime:number) { function setAnomalyPredictionTime(predictorId: PredictorId, lastPredictionTime: number) {
let info = loadAnomalyById(anomalyId); let info = loadAnomalyById(predictorId);
info.last_prediction_time = lastPredictionTime; info.last_prediction_time = lastPredictionTime;
saveAnomaly(anomalyId, info); saveAnomaly(predictorId, info);
} }
export { export {
saveAnomaly, loadAnomalyById, loadAnomalyByName, insertAnomaly, removeAnomaly, saveAnomalyTypeInfo, saveAnomaly, loadAnomalyById, loadAnomalyByName, insertAnomaly, removeAnomaly, saveAnomalyTypeInfo,
getAnomalyTypeInfo, getAnomalyIdByName, setAnomalyStatus, setAnomalyPredictionTime getAnomalyTypeInfo, getPredictorIdByName, setAnomalyStatus, setAnomalyPredictionTime
} }

2
server/src/services/data.ts

@ -12,7 +12,7 @@ function maybeCreate(path: string): void {
} }
export function checkDataFolders(): void { export function checkDataFolders(): void {
var folders = [ [
config.DATA_PATH, config.DATA_PATH,
config.DATASETS_PATH, config.DATASETS_PATH,
config.ANOMALIES_PATH, config.ANOMALIES_PATH,

4
server/src/services/notification.ts

@ -1,8 +1,8 @@
import axios from 'axios'; import axios from 'axios';
import { loadAnomalyById } from './anomalyType'; import { loadAnomalyById } from './anomalyType';
export async function sendNotification(anomalyId, active) { export async function sendNotification(predictorId, active) {
let anomalyName = loadAnomalyById(anomalyId).name; let anomalyName = loadAnomalyById(predictorId).name;
console.log('Notification ' + anomalyName); console.log('Notification ' + anomalyName);
let notification = { let notification = {

30
server/src/services/segments.ts

@ -2,12 +2,12 @@ import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import { getJsonDataSync, writeJsonDataSync } from './json'; import { getJsonDataSync, writeJsonDataSync } from './json';
import { SEGMENTS_PATH } from '../config'; import { SEGMENTS_PATH } from '../config';
import { AnomalyId, loadAnomalyById, saveAnomaly } from './anomalyType'; import { PredictorId, loadAnomalyById, saveAnomaly } from './anomalyType';
import * as _ from 'lodash'; import * as _ from 'lodash';
function getLabeledSegments(anomalyId: AnomalyId) { function getLabeledSegments(predictorId: PredictorId) {
let filename = path.join(SEGMENTS_PATH, `${anomalyId}_labeled.json`); let filename = path.join(SEGMENTS_PATH, `${predictorId}_labeled.json`);
if(!fs.existsSync(filename)) { if(!fs.existsSync(filename)) {
return []; return [];
@ -22,8 +22,8 @@ function getLabeledSegments(anomalyId: AnomalyId) {
} }
} }
function getPredictedSegments(anomalyId: AnomalyId) { function getPredictedSegments(predictorId: PredictorId) {
let filename = path.join(SEGMENTS_PATH, `${anomalyId}_segments.json`); let filename = path.join(SEGMENTS_PATH, `${predictorId}_segments.json`);
let jsonData; let jsonData;
try { try {
@ -35,8 +35,8 @@ function getPredictedSegments(anomalyId: AnomalyId) {
return jsonData; return jsonData;
} }
function saveSegments(anomalyId: AnomalyId, segments) { function saveSegments(predictorId: PredictorId, segments) {
let filename = path.join(SEGMENTS_PATH, `${anomalyId}_labeled.json`); let filename = path.join(SEGMENTS_PATH, `${predictorId}_labeled.json`);
try { try {
return writeJsonDataSync(filename, _.uniqBy(segments, 'start')); return writeJsonDataSync(filename, _.uniqBy(segments, 'start'));
@ -46,10 +46,10 @@ function saveSegments(anomalyId: AnomalyId, segments) {
} }
} }
function insertSegments(anomalyId: AnomalyId, addedSegments, labeled:boolean) { function insertSegments(predictorId: PredictorId, addedSegments, labeled:boolean) {
// Set status // Set status
let info = loadAnomalyById(anomalyId); let info = loadAnomalyById(predictorId);
let segments = getLabeledSegments(anomalyId); let segments = getLabeledSegments(predictorId);
let nextId = info.next_id; let nextId = info.next_id;
let addedIds = [] let addedIds = []
@ -61,17 +61,17 @@ function insertSegments(anomalyId: AnomalyId, addedSegments, labeled:boolean) {
segments.push(segment); segments.push(segment);
} }
info.next_id = nextId; info.next_id = nextId;
saveSegments(anomalyId, segments); saveSegments(predictorId, segments);
saveAnomaly(anomalyId, info); saveAnomaly(predictorId, info);
return addedIds; return addedIds;
} }
function removeSegments(anomalyId: AnomalyId, removedSegments) { function removeSegments(predictorId: PredictorId, removedSegments) {
let segments = getLabeledSegments(anomalyId); let segments = getLabeledSegments(predictorId);
for (let segmentId of removedSegments) { for (let segmentId of removedSegments) {
segments = segments.filter(el => el.id !== segmentId); segments = segments.filter(el => el.id !== segmentId);
} }
saveSegments(anomalyId, segments); saveSegments(predictorId, segments);
} }
export { getLabeledSegments, getPredictedSegments, saveSegments, insertSegments, removeSegments } export { getLabeledSegments, getPredictedSegments, saveSegments, insertSegments, removeSegments }

Loading…
Cancel
Save