Browse Source

HSR for anomaly analytic unit #302 (#303)

master
rozetko 6 years ago committed by GitHub
parent
commit
ea969dd952
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 62
      src/panel/graph_panel/controllers/analytic_controller.ts
  2. 6
      src/panel/graph_panel/models/detection.ts
  3. 8
      src/panel/graph_panel/services/analytic_service.ts

62
src/panel/graph_panel/controllers/analytic_controller.ts

@ -500,7 +500,10 @@ export class AnalyticController {
this.fetchAnalyticUnitsStatuses(); this.fetchAnalyticUnitsStatuses();
} }
async getHSR(from: number, to: number): Promise<HSRTimeSeries | null> { async getHSR(from: number, to: number): Promise<{
hsr: HSRTimeSeries,
smoothed?: HSRTimeSeries
} | null> {
// Returns HSR (Hastic Signal Representation) for analytic unit in "Inspect" mode // Returns HSR (Hastic Signal Representation) for analytic unit in "Inspect" mode
// Returns null when there are no analytic units in "Inspect" mode // Returns null when there are no analytic units in "Inspect" mode
// or if there is no response from server // or if there is no response from server
@ -508,50 +511,65 @@ export class AnalyticController {
return null; return null;
} }
const hsr = await this._analyticService.getHSR(this.inspectedAnalyticUnit.id, from, to); const response = await this._analyticService.getHSR(this.inspectedAnalyticUnit.id, from, to);
if(hsr === null) { if(response === null) {
return null; return null;
} }
const datapoints = hsr.values.map(value => value.reverse() as [number, number]);
return { target: 'HSR', datapoints }; const hsrDatapoints = response.hsr.values.map(value => value.reverse() as [number, number]);
const hsrTimeSeries = { target: 'HSR', datapoints: hsrDatapoints };
let smoothed: HSRTimeSeries;
if(response.smoothed !== undefined) {
// TODO: remove duplication with hsrDatapoints
const smoothedDatapoints = response.smoothed.values.map(value => value.reverse() as [number, number]);
smoothed = { target: 'Smoothed data', datapoints: smoothedDatapoints };
}
return {
hsr: hsrTimeSeries,
smoothed
};
} }
async getHSRSeries(from: number, to: number) { async getHSRSeries(from: number, to: number) {
const hsr = await this.getHSR(from, to); const response = await this.getHSR(from, to);
if(hsr === null) { if(response === null) {
return []; return [];
} }
if(this.inspectedAnalyticUnit.detectorType === DetectorType.ANOMALY) { const hsrSerie = {
...response.hsr,
color: ANALYTIC_UNIT_COLORS[0],
// TODO: render it separately from Metric series
overrides: [
{ alias: 'HSR', linewidth: 3, fill: 0 }
]
};
if(response.smoothed !== undefined) {
const confidence = (this.inspectedAnalyticUnit as AnomalyAnalyticUnit).confidence; const confidence = (this.inspectedAnalyticUnit as AnomalyAnalyticUnit).confidence;
// TODO: looks bad // TODO: looks bad
return [ return [
{ {
target: 'Confidence interval lower', target: '[AnomalyDetector]: lower bound',
datapoints: hsr.datapoints.map(datapoint => datapoints: response.smoothed.datapoints.map(datapoint =>
[datapoint[0] - confidence, datapoint[1]] [datapoint[0] - confidence, datapoint[1]]
), ),
color: ANALYTIC_UNIT_COLORS[0], color: ANALYTIC_UNIT_COLORS[0],
overrides: [{ alias: 'Confidence interval lower', linewidth: 1, fill: 0 }] overrides: [{ alias: '[AnomalyDetector]: lower bound', linewidth: 1, fill: 0 }]
}, },
{ {
target: 'Confidence interval upper', target: '[AnomalyDetector]: upper bound',
datapoints: hsr.datapoints.map(datapoint => datapoints: response.smoothed.datapoints.map(datapoint =>
[datapoint[0] + confidence, datapoint[1]] [datapoint[0] + confidence, datapoint[1]]
), ),
color: ANALYTIC_UNIT_COLORS[0], color: ANALYTIC_UNIT_COLORS[0],
overrides: [{ alias: 'Confidence interval upper', linewidth: 1, fill: 0 }] overrides: [{ alias: '[AnomalyDetector]: upper bound', linewidth: 1, fill: 0 }]
}, },
hsrSerie
]; ];
} }
return { return hsrSerie;
...hsr,
color: ANALYTIC_UNIT_COLORS[0],
// TODO: render it separately from Metric series
overrides: [
{ alias: 'HSR', linewidth: 3, fill: 0 }
]
};
} }
get inspectedAnalyticUnit(): AnalyticUnit | null { get inspectedAnalyticUnit(): AnalyticUnit | null {

6
src/panel/graph_panel/models/detection.ts

@ -14,7 +14,7 @@ export type DetectionSpan = {
}; };
export const DETECTION_STATUS_TEXT = new Map<DetectionStatus, string>([ export const DETECTION_STATUS_TEXT = new Map<DetectionStatus, string>([
[DetectionStatus.READY, 'Detection is done'], [DetectionStatus.READY, '[DetectionStatus]: done'],
[DetectionStatus.RUNNING, 'Detection is running...'], [DetectionStatus.RUNNING, '[DetectionStatus]: running...'],
[DetectionStatus.FAILED, 'Detection failed'] [DetectionStatus.FAILED, '[DetectionStatus]: failed']
]); ]);

8
src/panel/graph_panel/services/analytic_service.ts

@ -12,6 +12,10 @@ import { appEvents } from 'grafana/app/core/core';
import * as _ from 'lodash'; import * as _ from 'lodash';
type TableTimeSeries = {
values: [number, number][];
columns: string[];
};
export class AnalyticService { export class AnalyticService {
private _isUp: boolean = false; private _isUp: boolean = false;
@ -201,8 +205,8 @@ export class AnalyticService {
} }
async getHSR(analyticUnitId: AnalyticUnitId, from: number, to: number): Promise<{ async getHSR(analyticUnitId: AnalyticUnitId, from: number, to: number): Promise<{
values: [number, number][]; hsr: TableTimeSeries,
columns: string[]; smoothed?: TableTimeSeries
} | null> { } | null> {
const data = await this.get('/query', { analyticUnitId, from, to }); const data = await this.get('/query', { analyticUnitId, from, to });
if(data === undefined) { if(data === undefined) {

Loading…
Cancel
Save