Browse Source

more renaming

pull/1/head
Alexey Velikiy 6 years ago
parent
commit
e0458555c7
  1. 2
      server/src/config.ts
  2. 2
      server/src/index.ts
  3. 69
      server/src/models/analytic_unit.ts
  4. 29
      server/src/routes/alerts.ts
  5. 42
      server/src/routes/analytic_units.ts
  6. 14
      server/src/routes/segments.ts
  7. 4
      server/src/services/alerts.ts
  8. 10
      server/src/services/analytics.ts
  9. 2
      server/src/services/data.ts
  10. 14
      server/src/services/segments.ts

2
server/src/config.ts

@ -11,7 +11,7 @@ export const ANALYTICS_PATH = path.join(__dirname, '../../analytics');
export const DATA_PATH = path.join(__dirname, '../../data'); export const DATA_PATH = path.join(__dirname, '../../data');
export const DATASETS_PATH = path.join(DATA_PATH, 'datasets'); export const DATASETS_PATH = path.join(DATA_PATH, 'datasets');
export const ANOMALIES_PATH = path.join(DATA_PATH, 'anomalies'); export const ANALYTIC_UNITS_PATH = path.join(DATA_PATH, 'analytic_units ');
export const MODELS_PATH = path.join(DATA_PATH, 'models'); export const MODELS_PATH = path.join(DATA_PATH, 'models');
export const METRICS_PATH = path.join(DATA_PATH, 'metrics'); export const METRICS_PATH = path.join(DATA_PATH, 'metrics');
export const SEGMENTS_PATH = path.join(DATA_PATH, 'segments'); export const SEGMENTS_PATH = path.join(DATA_PATH, 'segments');

2
server/src/index.ts

@ -26,7 +26,7 @@ app.use(async function(ctx, next) {
var rootRouter = new Router(); var rootRouter = new Router();
rootRouter.use('/anomalies', anomaliesRouter.routes(), anomaliesRouter.allowedMethods()); rootRouter.use('/analyticUnits', anomaliesRouter.routes(), anomaliesRouter.allowedMethods());
rootRouter.use('/segments', segmentsRouter.routes(), segmentsRouter.allowedMethods()); rootRouter.use('/segments', segmentsRouter.routes(), segmentsRouter.allowedMethods());
rootRouter.use('/alerts', alertsRouter.routes(), alertsRouter.allowedMethods()); rootRouter.use('/alerts', alertsRouter.routes(), alertsRouter.allowedMethods());
rootRouter.get('/', async (ctx) => { rootRouter.get('/', async (ctx) => {

69
server/src/models/analytic_unit.ts

@ -1,5 +1,5 @@
import { getJsonDataSync, writeJsonDataSync } from '../services/json' import { getJsonDataSync, writeJsonDataSync } from '../services/json'
import { ANOMALIES_PATH } from '../config' import { ANALYTIC_UNITS_PATH } from '../config'
import * as crypto from 'crypto'; import * as crypto from 'crypto';
@ -20,71 +20,57 @@ export type Metric = {
targets: string[] targets: string[]
} }
export type AnalyticUnitId = string;
export type AnalyticUnit = { export type AnalyticUnit = {
id?: AnalyticUnitId,
name: string, name: string,
panelUrl: string, panelUrl: string,
type: string,
pattern: string,
metric: Metric, metric: Metric,
datasource: Datasource datasource: Datasource
status: string, status: string,
error?: string, error?: string,
lastPredictionTime: number, lastPredictionTime: number,
nextId: number nextId: number
} }
export type AnalyticUnitId = string; export function createItem(item: AnalyticUnit): AnalyticUnitId {
function createItem(item: AnalyticUnit): AnalyticUnitId {
const hashString = item.name + (new Date()).toString(); const hashString = item.name + (new Date()).toString();
const newId: AnalyticUnitId = crypto.createHash('md5').update(hashString).digest('hex'); const newId: AnalyticUnitId = crypto.createHash('md5').update(hashString).digest('hex');
let filename = path.join(ANOMALIES_PATH, `${newId}.json`); let filename = path.join(ANALYTIC_UNITS_PATH, `${newId}.json`);
if(fs.existsSync(filename)) { if(fs.existsSync(filename)) {
return null; throw new Error(`Can't create item with id ${newId}`);
} }
save(newId, item); save(newId, item);
item.id = newId;
return newId; return newId;
} }
function removeItem(key: AnalyticUnitId) { export function removeItem(id: AnalyticUnitId) {
let filename = path.join(ANOMALIES_PATH, `${key}.json`); let filename = path.join(ANALYTIC_UNITS_PATH, `${id}.json`);
fs.unlinkSync(filename); fs.unlinkSync(filename);
} }
function save(predictorId: AnalyticUnitId, anomaly: AnalyticUnit) { export function save(id: AnalyticUnitId, unit: AnalyticUnit) {
let filename = path.join(ANOMALIES_PATH, `${predictorId}.json`); let filename = path.join(ANALYTIC_UNITS_PATH, `${id}.json`);
return writeJsonDataSync(filename, anomaly); return writeJsonDataSync(filename, unit);
} }
function loadById(predictorId: AnalyticUnitId): AnalyticUnit { // TODO: make async
let filename = path.join(ANOMALIES_PATH, `${predictorId}.json`); export function loadById(id: AnalyticUnitId): AnalyticUnit {
let filename = path.join(ANALYTIC_UNITS_PATH, `${id}.json`);
if(!fs.existsSync(filename)) { if(!fs.existsSync(filename)) {
return null; throw new Error(`Can't find Analytic Unit with id ${id}`);
} }
return getJsonDataSync(filename); return getJsonDataSync(filename);
} }
function saveAnomalyTypeInfo(info) { export function getAnomalyTypeInfo(name) {
console.log('Saving'); return getJsonDataSync(path.join(ANALYTIC_UNITS_PATH, `${name}.json`));
let filename = path.join(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 writeJsonDataSync(filename, info);
}
function getAnomalyTypeInfo(name) {
return getJsonDataSync(path.join(ANOMALIES_PATH, `${name}.json`));
} }
function setAnomalyStatus(predictorId: AnalyticUnitId, status: string, error?: string) { export function setAnomalyStatus(predictorId: AnalyticUnitId, status: string, error?: string) {
let info = loadById(predictorId); let info = loadById(predictorId);
info.status = status; info.status = status;
if(error !== undefined) { if(error !== undefined) {
@ -95,13 +81,8 @@ function setAnomalyStatus(predictorId: AnalyticUnitId, status: string, error?: s
save(predictorId, info); save(predictorId, info);
} }
function setAnomalyPredictionTime(predictorId: AnalyticUnitId, lastPredictionTime: number) { export function setPredictionTime(id: AnalyticUnitId, time: number) {
let info = loadById(predictorId); let info = loadById(id);
info.lastPredictionTime = lastPredictionTime; info.lastPredictionTime = time;
save(predictorId, info); save(id, info);
}
export {
save, loadById, createItem, removeItem, saveAnomalyTypeInfo,
getAnomalyTypeInfo, setAnomalyStatus, setAnomalyPredictionTime
} }

29
server/src/routes/alerts.ts

@ -1,37 +1,31 @@
import { AnalyticUnitId, loadById } from '../models/analytic_unit'; import * as AnalyticUnit from '../models/analytic_unit';
import { getAlertsAnomalies, saveAlertsAnomalies } from '../services/alerts'; import { getAlertsAnomalies, saveAlertsAnomalies } from '../services/alerts';
import * as Router from 'koa-router'; import * as Router from 'koa-router';
function getAlert(ctx: Router.IRouterContext) { function getAlert(ctx: Router.IRouterContext) {
let predictorId: AnalyticUnit.AnalyticUnitId = ctx.request.query.predictor_id.toLowerCase();
let predictorId: AnalyticUnitId = ctx.request.query.predictor_id.toLowerCase();
let alertsAnomalies = getAlertsAnomalies(); let alertsAnomalies = getAlertsAnomalies();
let pos = alertsAnomalies.indexOf(predictorId); let pos = alertsAnomalies.indexOf(predictorId);
let enable: boolean = (pos !== -1); let enable: boolean = (pos !== -1);
ctx.response.body = { enable }; ctx.response.body = { enable };
} }
function changeAlert(ctx: Router.IRouterContext) { function setAlertEnabled(ctx: Router.IRouterContext) {
let id: AnalyticUnit.AnalyticUnitId = ctx.request.body.id;
let enabled: boolean = ctx.request.body.enabled;
let predictorId: AnalyticUnitId = ctx.request.body.predictor_id.toLowerCase(); let unit = AnalyticUnit.loadById(id)
let enable: boolean = ctx.request.body.enable;
let predictor = loadById(predictorId)
if(predictor == null) {
throw new Error('Predctor is null');
}
let alertsAnomalies = getAlertsAnomalies(); let alertsAnomalies = getAlertsAnomalies();
let pos: number = alertsAnomalies.indexOf(predictorId); let pos: number = alertsAnomalies.indexOf(id);
if(enable && pos == -1) { if(enabled && pos == -1) {
alertsAnomalies.push(predictorId); alertsAnomalies.push(id);
saveAlertsAnomalies(alertsAnomalies); saveAlertsAnomalies(alertsAnomalies);
} else if(!enable && pos > -1) { } else if(!enabled && pos > -1) {
alertsAnomalies.splice(pos, 1); alertsAnomalies.splice(pos, 1);
saveAlertsAnomalies(alertsAnomalies); saveAlertsAnomalies(alertsAnomalies);
} }
@ -42,5 +36,4 @@ function changeAlert(ctx: Router.IRouterContext) {
export const router = new Router(); export const router = new Router();
router.get('/', getAlert); router.get('/', getAlert);
router.post('/', changeAlert); router.post('/', setAlertEnabled);

42
server/src/routes/analytic_units.ts

@ -6,19 +6,15 @@ import { runLearning } from '../services/analytics'
import { saveTargets } from '../services/metrics'; import { saveTargets } from '../services/metrics';
async function sendStatus(ctx: Router.IRouterContext) { async function sendStatus(ctx: Router.IRouterContext) {
try {
let id = ctx.request.query.id; let id = ctx.request.query.id;
let name = ctx.request.query.name; let name = ctx.request.query.name;
try {
let unit: AnalyticUnit.AnalyticUnit;
if(id === undefined) { if(id === undefined) {
throw new Error('Id is undefined'); throw new Error('Id is undefined');
} }
unit = AnalyticUnit.loadById(id); let unit = AnalyticUnit.loadById(id);
if(unit === null) {
ctx.response.status = 404;
return;
}
if(unit.status === undefined) { if(unit.status === undefined) {
throw new Error('No status for ' + name); throw new Error('No status for ' + name);
} }
@ -42,11 +38,6 @@ async function findItem(ctx: Router.IRouterContext) {
let unit: AnalyticUnit.AnalyticUnit = AnalyticUnit.loadById(id); let unit: AnalyticUnit.AnalyticUnit = AnalyticUnit.loadById(id);
if(unit === null) {
ctx.response.status = 404;
return;
}
ctx.response.body = { ctx.response.body = {
name: unit.name, name: unit.name,
metric: unit.metric, metric: unit.metric,
@ -63,18 +54,39 @@ async function findItem(ctx: Router.IRouterContext) {
async function createItem(ctx: Router.IRouterContext) { async function createItem(ctx: Router.IRouterContext) {
try { try {
let body = ctx.request.body; let body = ctx.request.body;
if(body.type === undefined) {
throw new Error(`Missing field: type`);
}
if(body.name === undefined) {
throw new Error(`Missing field: name`);
}
if(body.panelUrl === undefined) {
throw new Error(`Missing field: panelUrl`);
}
if(body.metric === undefined) {
throw new Error(`Missing field: datasource`);
}
if(body.metric.datasource === undefined) {
throw new Error(`Missing field: metric.datasource`);
}
if(body.metric.targets === undefined) {
throw new Error(`Missing field: metric.targets`);
}
const metric: AnalyticUnit.Metric = { const metric: AnalyticUnit.Metric = {
datasource: body.metric.datasource, datasource: body.metric.datasource,
targets: saveTargets(body.metric.targets) targets: saveTargets(body.metric.targets)
}; };
const unit: AnalyticUnit.AnalyticUnit = { const unit: AnalyticUnit.AnalyticUnit = {
name: body.name.toLowerCase(), name: body.name,
panelUrl: body.panelUrl, panelUrl: body.panelUrl,
pattern: body.pattern.toLowerCase(), type: body.type,
metric: metric,
datasource: body.datasource, datasource: body.datasource,
metric: metric,
status: 'learning', status: 'learning',
lastPredictionTime: 0, lastPredictionTime: 0,
nextId: 0 nextId: 0

14
server/src/routes/segments.ts

@ -6,20 +6,12 @@ import {
removeSegments, removeSegments,
} from '../services/segments'; } from '../services/segments';
import { import { AnalyticUnitId } from '../models/analytic_unit';
AnalyticUnit, AnalyticUnitId, loadById
} from '../models/analytic_unit';
import { runLearning } from '../services/analytics'; import { runLearning } from '../services/analytics';
async function sendSegments(ctx: Router.IRouterContext) { async function sendSegments(ctx: Router.IRouterContext) {
let id: AnalyticUnitId = ctx.request.query.id; let id: AnalyticUnitId = ctx.request.query.id;
let unit: AnalyticUnit = loadById(id);
if(unit === null) {
throw new Error(`Can't find Analitic unit with id ${id}`);
}
let lastSegmentId = ctx.request.query.lastSegmentId; let lastSegmentId = ctx.request.query.lastSegmentId;
let timeFrom = ctx.request.query.from; let timeFrom = ctx.request.query.from;
@ -48,14 +40,10 @@ async function sendSegments(ctx: Router.IRouterContext) {
async function updateSegments(ctx: Router.IRouterContext) { async function updateSegments(ctx: Router.IRouterContext) {
try { try {
let segmentsUpdate = ctx.request.body; let segmentsUpdate = ctx.request.body;
let key = segmentsUpdate.analyticUnitKey; let key = segmentsUpdate.analyticUnitKey;
let addedIds = insertSegments(key, segmentsUpdate.addedSegments, true); let addedIds = insertSegments(key, segmentsUpdate.addedSegments, true);
removeSegments(key, segmentsUpdate.removedSegments); removeSegments(key, segmentsUpdate.removedSegments);
ctx.response.body = { addedIds }; ctx.response.body = { addedIds };
runLearning(key); runLearning(key);
} catch(e) { } catch(e) {
ctx.response.status = 500; ctx.response.status = 500;

4
server/src/services/alerts.ts

@ -4,14 +4,14 @@ import { runPredict } from './analytics';
import { sendNotification } from './notification'; import { sendNotification } from './notification';
import { getLabeledSegments } from './segments'; import { getLabeledSegments } from './segments';
import { ANOMALIES_PATH } from '../config'; import { ANALYTIC_UNITS_PATH } from '../config';
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
const ALERTS_DB_PATH = path.join(ANOMALIES_PATH, `alerts_anomalies.json`); const ALERTS_DB_PATH = path.join(ANALYTIC_UNITS_PATH, `alerts_anomalies.json`);
function getAlertsAnomalies(): AnalyticUnitId[] { function getAlertsAnomalies(): AnalyticUnitId[] {
if(!fs.existsSync(ALERTS_DB_PATH)) { if(!fs.existsSync(ALERTS_DB_PATH)) {

10
server/src/services/analytics.ts

@ -2,7 +2,7 @@ import {
AnalyticUnit, AnalyticUnit,
AnalyticUnitId, getAnomalyTypeInfo, AnalyticUnitId, getAnomalyTypeInfo,
loadById, loadById,
setAnomalyPredictionTime, setPredictionTime,
setAnomalyStatus setAnomalyStatus
} from '../models/analytic_unit' } from '../models/analytic_unit'
import { getTarget } from './metrics'; import { getTarget } from './metrics';
@ -46,7 +46,7 @@ export async function runLearning(predictorId:AnalyticUnitId) {
let segments = getLabeledSegments(predictorId); let segments = getLabeledSegments(predictorId);
setAnomalyStatus(predictorId, 'learning'); setAnomalyStatus(predictorId, 'learning');
let anomaly:AnalyticUnit = loadById(predictorId); let anomaly:AnalyticUnit = loadById(predictorId);
let pattern = anomaly.pattern; let pattern = anomaly.type;
let task = { let task = {
type: 'learn', type: 'learn',
predictor_id: predictorId, predictor_id: predictorId,
@ -59,7 +59,7 @@ export async function runLearning(predictorId:AnalyticUnitId) {
if (result.status === 'success') { if (result.status === 'success') {
setAnomalyStatus(predictorId, 'ready'); setAnomalyStatus(predictorId, 'ready');
insertSegments(predictorId, result.segments, false); insertSegments(predictorId, result.segments, false);
setAnomalyPredictionTime(predictorId, result.last_prediction_time); setPredictionTime(predictorId, result.last_prediction_time);
} else { } else {
setAnomalyStatus(predictorId, 'failed', result.error); setAnomalyStatus(predictorId, 'failed', result.error);
} }
@ -67,7 +67,7 @@ export async function runLearning(predictorId:AnalyticUnitId) {
export async function runPredict(predictorId:AnalyticUnitId) { export async function runPredict(predictorId:AnalyticUnitId) {
let anomaly:AnalyticUnit = loadById(predictorId); let anomaly:AnalyticUnit = loadById(predictorId);
let pattern = anomaly.pattern; let pattern = anomaly.type;
let task = { let task = {
type: 'predict', type: 'predict',
predictor_id: predictorId, predictor_id: predictorId,
@ -92,6 +92,6 @@ export async function runPredict(predictorId:AnalyticUnitId) {
} }
insertSegments(predictorId, result.segments, false); insertSegments(predictorId, result.segments, false);
setAnomalyPredictionTime(predictorId, result.last_prediction_time); setPredictionTime(predictorId, result.last_prediction_time);
return result.segments; return result.segments;
} }

2
server/src/services/data.ts

@ -15,7 +15,7 @@ export function checkDataFolders(): void {
[ [
config.DATA_PATH, config.DATA_PATH,
config.DATASETS_PATH, config.DATASETS_PATH,
config.ANOMALIES_PATH, config.ANALYTIC_UNITS_PATH,
config.MODELS_PATH, config.MODELS_PATH,
config.METRICS_PATH, config.METRICS_PATH,
config.SEGMENTS_PATH config.SEGMENTS_PATH

14
server/src/services/segments.ts

@ -8,8 +8,8 @@ import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
export function getLabeledSegments(predictorId: AnalyticUnitId) { export function getLabeledSegments(id: AnalyticUnitId) {
let filename = path.join(SEGMENTS_PATH, `${predictorId}_labeled.json`); let filename = path.join(SEGMENTS_PATH, `${id}_labeled.json`);
if(!fs.existsSync(filename)) { if(!fs.existsSync(filename)) {
return []; return [];
@ -24,8 +24,8 @@ export function getLabeledSegments(predictorId: AnalyticUnitId) {
} }
} }
export function getPredictedSegments(predictorId: AnalyticUnitId) { export function getPredictedSegments(id: AnalyticUnitId) {
let filename = path.join(SEGMENTS_PATH, `${predictorId}_segments.json`); let filename = path.join(SEGMENTS_PATH, `${id}_segments.json`);
let jsonData; let jsonData;
try { try {
@ -68,10 +68,10 @@ export function insertSegments(id: AnalyticUnitId, addedSegments, labeled:boolea
return addedIds; return addedIds;
} }
export function removeSegments(predictorId: AnalyticUnitId, removedSegments) { export function removeSegments(id: AnalyticUnitId, removedSegments) {
let segments = getLabeledSegments(predictorId); let segments = getLabeledSegments(id);
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(predictorId, segments); saveSegments(id, segments);
} }

Loading…
Cancel
Save