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. 44
      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 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 METRICS_PATH = path.join(DATA_PATH, 'metrics');
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();
rootRouter.use('/anomalies', anomaliesRouter.routes(), anomaliesRouter.allowedMethods());
rootRouter.use('/analyticUnits', anomaliesRouter.routes(), anomaliesRouter.allowedMethods());
rootRouter.use('/segments', segmentsRouter.routes(), segmentsRouter.allowedMethods());
rootRouter.use('/alerts', alertsRouter.routes(), alertsRouter.allowedMethods());
rootRouter.get('/', async (ctx) => {

69
server/src/models/analytic_unit.ts

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

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

44
server/src/routes/analytic_units.ts

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

14
server/src/routes/segments.ts

@ -6,20 +6,12 @@ import {
removeSegments,
} from '../services/segments';
import {
AnalyticUnit, AnalyticUnitId, loadById
} from '../models/analytic_unit';
import { AnalyticUnitId } from '../models/analytic_unit';
import { runLearning } from '../services/analytics';
async function sendSegments(ctx: Router.IRouterContext) {
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 timeFrom = ctx.request.query.from;
@ -48,14 +40,10 @@ async function sendSegments(ctx: Router.IRouterContext) {
async function updateSegments(ctx: Router.IRouterContext) {
try {
let segmentsUpdate = ctx.request.body;
let key = segmentsUpdate.analyticUnitKey;
let addedIds = insertSegments(key, segmentsUpdate.addedSegments, true);
removeSegments(key, segmentsUpdate.removedSegments);
ctx.response.body = { addedIds };
runLearning(key);
} catch(e) {
ctx.response.status = 500;

4
server/src/services/alerts.ts

@ -4,14 +4,14 @@ import { runPredict } from './analytics';
import { sendNotification } from './notification';
import { getLabeledSegments } from './segments';
import { ANOMALIES_PATH } from '../config';
import { ANALYTIC_UNITS_PATH } from '../config';
import * as path from 'path';
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[] {
if(!fs.existsSync(ALERTS_DB_PATH)) {

10
server/src/services/analytics.ts

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

2
server/src/services/data.ts

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

14
server/src/services/segments.ts

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

Loading…
Cancel
Save