Skip to content

Commit ed7a539

Browse files
committed
feat(alerting): thresholds rethink
1 parent dac8b35 commit ed7a539

File tree

9 files changed

+193
-173
lines changed

9 files changed

+193
-173
lines changed

public/app/plugins/panel/graph/alert_tab_ctrl.ts

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ var alertQueryDef = new QueryPartDef({
2222
export class AlertTabCtrl {
2323
panel: any;
2424
panelCtrl: any;
25-
metricTargets = [{ refId: '- select query -' } ];
25+
metricTargets;
2626
handlers = [{text: 'Grafana', value: 1}, {text: 'External', value: 0}];
2727
transforms = [
2828
{
@@ -36,6 +36,7 @@ export class AlertTabCtrl {
3636
];
3737
aggregators = ['avg', 'sum', 'min', 'max', 'last'];
3838
alert: any;
39+
thresholds: any;
3940
query: any;
4041
queryParams: any;
4142
transformDef: any;
@@ -45,32 +46,14 @@ export class AlertTabCtrl {
4546
{text: '=', value: '='},
4647
];
4748

48-
defaultValues = {
49-
frequency: '60s',
50-
notify: [],
51-
enabled: false,
52-
handler: 1,
53-
warn: { op: '>', level: undefined },
54-
critical: { op: '>', level: undefined },
55-
query: {
56-
refId: 'A',
57-
from: '5m',
58-
to: 'now',
59-
},
60-
transform: {
61-
type: 'aggregation',
62-
method: 'avg'
63-
}
64-
};
65-
6649
/** @ngInject */
6750
constructor($scope, private $timeout) {
6851
this.panelCtrl = $scope.ctrl;
6952
this.panel = this.panelCtrl.panel;
7053
$scope.ctrl = this;
7154

7255
this.metricTargets = this.panel.targets.map(val => val);
73-
this.initAlertModel();
56+
this.initModel();
7457

7558
// set panel alert edit mode
7659
$scope.$on("$destroy", () => {
@@ -79,32 +62,63 @@ export class AlertTabCtrl {
7962
});
8063
}
8164

82-
initAlertModel() {
83-
if (!this.panel.alert) {
65+
getThresholdWithDefaults(thresholds, type, copyFrom) {
66+
var threshold = thresholds[type] || {};
67+
var defaultValue = (copyFrom[type] || {}).value || undefined;
68+
69+
threshold.op = threshold.op || '>';
70+
threshold.value = threshold.value || defaultValue;
71+
return threshold;
72+
}
73+
74+
initThresholdsOnlyMode() {
75+
if (!this.panel.thresholds) {
8476
return;
8577
}
8678

87-
this.alert = this.panel.alert;
79+
this.thresholds = this.panel.thresholds;
80+
81+
// set threshold defaults
82+
this.thresholds.warn = this.getThresholdWithDefaults(this.thresholds, 'warn', {});
83+
this.thresholds.crit = this.getThresholdWithDefaults(this.thresholds, 'crit', {});
84+
85+
this.panelCtrl.editingAlert = true;
86+
this.panelCtrl.render();
87+
}
88+
89+
initModel() {
90+
var alert = this.alert = this.panel.alert = this.panel.alert || {};
91+
92+
// set threshold defaults
93+
alert.thresholds = alert.thresholds || {};
94+
alert.thresholds.warn = this.getThresholdWithDefaults(alert.thresholds, 'warn', this.panel.thresholds);
95+
alert.thresholds.crit = this.getThresholdWithDefaults(alert.thresholds, 'crit', this.panel.thresholds);
8896

89-
// set defaults
90-
_.defaults(this.alert, this.defaultValues);
97+
alert.frequency = alert.frequency || '60s';
98+
alert.handler = alert.handler || 1;
99+
alert.notifications = alert.notifications || [];
91100

92-
var defaultName = (this.panelCtrl.dashboard.title + ' ' + this.panel.title + ' alert');
93-
this.alert.name = this.alert.name || defaultName;
94-
this.alert.description = this.alert.description || defaultName;
101+
alert.query = alert.query || {};
102+
alert.query.refId = alert.query.refId || 'A';
103+
alert.query.from = alert.query.from || '5m';
104+
alert.query.to = alert.query.to || 'now';
105+
106+
alert.transform = alert.transform || {};
107+
alert.transform.type = alert.transform.type || 'aggregation';
108+
alert.transform.method = alert.transform.method || 'avg';
109+
110+
var defaultName = this.panel.title + ' alert';
111+
alert.name = alert.name || defaultName;
112+
alert.description = alert.description || defaultName;
95113

96114
// great temp working model
97115
this.queryParams = {
98-
params: [
99-
this.alert.query.refId,
100-
this.alert.query.from,
101-
this.alert.query.to
102-
]
116+
params: [alert.query.refId, alert.query.from, alert.query.to]
103117
};
104118

105119
// init the query part components model
106120
this.query = new QueryPart(this.queryParams, alertQueryDef);
107-
this.transformDef = _.findWhere(this.transforms, {type: this.alert.transform.type});
121+
this.transformDef = _.findWhere(this.transforms, {type: alert.transform.type});
108122

109123
this.panelCtrl.editingAlert = true;
110124
this.panelCtrl.render();
@@ -135,22 +149,26 @@ export class AlertTabCtrl {
135149
}
136150
}
137151

138-
operatorChanged() {
139-
this.panelCtrl.render();
140-
}
141-
142152
delete() {
153+
delete this.alert;
143154
delete this.panel.alert;
144-
this.panelCtrl.editingAlert = false;
145-
this.panelCtrl.render();
155+
// clear thresholds
156+
if (this.panel.thresholds) {
157+
this.panel.thresholds = {};
158+
}
159+
this.initModel();
146160
}
147161

148162
enable() {
163+
if (this.thresholds) {
164+
delete this.thresholds;
165+
this.panelCtrl.
166+
}
149167
this.panel.alert = {};
150-
this.initAlertModel();
168+
this.initModel();
151169
}
152170

153-
levelsUpdated() {
171+
thresholdsUpdated() {
154172
this.panelCtrl.render();
155173
}
156174
}

public/app/plugins/panel/graph/graph.js

Lines changed: 67 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ define([
55
'lodash',
66
'app/core/utils/kbn',
77
'./graph_tooltip',
8-
'./alert_handle',
8+
'./thresholds',
99
'jquery.flot',
1010
'jquery.flot.selection',
1111
'jquery.flot.time',
@@ -15,15 +15,15 @@ define([
1515
'jquery.flot.crosshair',
1616
'./jquery.flot.events',
1717
],
18-
function (angular, $, moment, _, kbn, GraphTooltip, AlertHandle) {
18+
function (angular, $, moment, _, kbn, GraphTooltip, thresholds) {
1919
'use strict';
2020

2121
var module = angular.module('grafana.directives');
2222
var labelWidthCache = {};
2323
var panelWidthCache = {};
2424

2525
// systemjs export
26-
var AlertHandleManager = AlertHandle.AlertHandleManager;
26+
var ThresholdControls = thresholds.ThresholdControls;
2727

2828
module.directive('grafanaGraph', function($rootScope, timeSrv) {
2929
return {
@@ -38,7 +38,7 @@ function (angular, $, moment, _, kbn, GraphTooltip, AlertHandle) {
3838
var legendSideLastValue = null;
3939
var rootScope = scope.$root;
4040
var panelWidth = 0;
41-
var alertHandles;
41+
var thresholdControls;
4242

4343
rootScope.onAppEvent('setCrosshair', function(event, info) {
4444
// do not need to to this if event is from this panel
@@ -167,8 +167,8 @@ function (angular, $, moment, _, kbn, GraphTooltip, AlertHandle) {
167167
rightLabel[0].style.marginTop = (getLabelWidth(panel.yaxes[1].label, rightLabel) / 2) + 'px';
168168
}
169169

170-
if (alertHandles) {
171-
alertHandles.draw(plot);
170+
if (thresholdControls) {
171+
thresholdControls.draw(plot);
172172
}
173173
}
174174

@@ -192,14 +192,14 @@ function (angular, $, moment, _, kbn, GraphTooltip, AlertHandle) {
192192

193193
// give space to alert editing
194194
if (ctrl.editingAlert) {
195-
if (!alertHandles) {
195+
if (!thresholdControls) {
196196
elem.css('margin-right', '220px');
197-
alertHandles = new AlertHandleManager(ctrl);
197+
thresholdControls = new ThresholdControls(ctrl);
198198
}
199-
} else if (alertHandles) {
199+
} else if (thresholdControls) {
200200
elem.css('margin-right', '0');
201-
alertHandles.cleanUp();
202-
alertHandles = null;
201+
thresholdControls.cleanUp();
202+
thresholdControls = null;
203203
}
204204

205205
var stack = panel.stack ? true : null;
@@ -333,70 +333,73 @@ function (angular, $, moment, _, kbn, GraphTooltip, AlertHandle) {
333333
}
334334

335335
function addGridThresholds(options, panel) {
336+
var thresholds = panel.thresholds;
337+
338+
// use alert thresholds if there are any
336339
if (panel.alert) {
337-
var crit = panel.alert.critical;
338-
var warn = panel.alert.warn;
339-
var critEdge = Infinity;
340-
var warnEdge = crit.level;
341-
342-
if (_.isNumber(crit.level)) {
343-
if (crit.op === '<') {
344-
critEdge = -Infinity;
345-
}
340+
thresholds = panel.alert.thresholds;
341+
}
346342

347-
// fill
348-
options.grid.markings.push({
349-
yaxis: {from: crit.level, to: critEdge},
350-
color: 'rgba(234, 112, 112, 0.10)',
351-
});
352-
353-
// line
354-
options.grid.markings.push({
355-
yaxis: {from: crit.level, to: crit.level},
356-
color: '#ed2e18'
357-
});
358-
}
343+
var crit = thresholds.crit;
344+
var warn = thresholds.warn;
345+
var critEdge = Infinity;
346+
var warnEdge = crit.value;
359347

360-
if (_.isNumber(warn.level)) {
361-
// if (warn.op === '<') {
362-
// }
363-
364-
// fill
365-
options.grid.markings.push({
366-
yaxis: {from: warn.level, to: warnEdge},
367-
color: 'rgba(216, 200, 27, 0.10)',
368-
});
369-
370-
// line
371-
options.grid.markings.push({
372-
yaxis: {from: warn.level, to: warn.level},
373-
color: '#F79520'
374-
});
348+
if (_.isNumber(crit.value)) {
349+
if (crit.op === '<') {
350+
critEdge = -Infinity;
375351
}
376352

377-
return;
353+
// fill
354+
options.grid.markings.push({
355+
yaxis: {from: crit.value, to: critEdge},
356+
color: 'rgba(234, 112, 112, 0.10)',
357+
});
358+
359+
// line
360+
options.grid.markings.push({
361+
yaxis: {from: crit.value, to: crit.value},
362+
color: '#ed2e18'
363+
});
378364
}
379365

380-
if (_.isNumber(panel.grid.threshold1)) {
381-
var limit1 = panel.grid.thresholdLine ? panel.grid.threshold1 : (panel.grid.threshold2 || null);
366+
if (_.isNumber(warn.value)) {
367+
// if (warn.op === '<') {
368+
// }
369+
370+
// fill
382371
options.grid.markings.push({
383-
yaxis: { from: panel.grid.threshold1, to: limit1 },
384-
color: panel.grid.threshold1Color
372+
yaxis: {from: warn.value, to: warnEdge},
373+
color: 'rgba(216, 200, 27, 0.10)',
385374
});
386375

387-
if (_.isNumber(panel.grid.threshold2)) {
388-
var limit2;
389-
if (panel.grid.thresholdLine) {
390-
limit2 = panel.grid.threshold2;
391-
} else {
392-
limit2 = panel.grid.threshold1 > panel.grid.threshold2 ? -Infinity : +Infinity;
393-
}
394-
options.grid.markings.push({
395-
yaxis: { from: panel.grid.threshold2, to: limit2 },
396-
color: panel.grid.threshold2Color
397-
});
398-
}
376+
// line
377+
options.grid.markings.push({
378+
yaxis: {from: warn.value, to: warn.value},
379+
color: '#F79520'
380+
});
399381
}
382+
383+
// if (_.isNumber(panel.grid.threshold1)) {
384+
// var limit1 = panel.grid.thresholdLine ? panel.grid.threshold1 : (panel.grid.threshold2 || null);
385+
// options.grid.markings.push({
386+
// yaxis: { from: panel.grid.threshold1, to: limit1 },
387+
// color: panel.grid.threshold1Color
388+
// });
389+
//
390+
// if (_.isNumber(panel.grid.threshold2)) {
391+
// var limit2;
392+
// if (panel.grid.thresholdLine) {
393+
// limit2 = panel.grid.threshold2;
394+
// } else {
395+
// limit2 = panel.grid.threshold1 > panel.grid.threshold2 ? -Infinity : +Infinity;
396+
// }
397+
// options.grid.markings.push({
398+
// yaxis: { from: panel.grid.threshold2, to: limit2 },
399+
// color: panel.grid.threshold2Color
400+
// });
401+
// }
402+
// }
400403
}
401404

402405
function addAnnotations(options) {

public/app/plugins/panel/graph/module.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,9 @@ class GraphCtrl extends MetricsPanelCtrl {
5454
xaxis: {
5555
show: true
5656
},
57-
grid : {
58-
threshold1: null,
59-
threshold2: null,
60-
threshold1Color: 'rgba(216, 200, 27, 0.27)',
61-
threshold2Color: 'rgba(234, 112, 112, 0.22)'
57+
thresholds: {
58+
warn: {op: '>', level: undefined},
59+
crit: {op: '>', level: undefined},
6260
},
6361
// show/hide lines
6462
lines : true,
@@ -115,7 +113,7 @@ class GraphCtrl extends MetricsPanelCtrl {
115113

116114
_.defaults(this.panel, this.panelDefaults);
117115
_.defaults(this.panel.tooltip, this.panelDefaults.tooltip);
118-
_.defaults(this.panel.grid, this.panelDefaults.grid);
116+
_.defaults(this.panel.thresholds, this.panelDefaults.thresholds);
119117
_.defaults(this.panel.legend, this.panelDefaults.legend);
120118

121119
this.colors = $scope.$root.colors;
@@ -132,6 +130,7 @@ class GraphCtrl extends MetricsPanelCtrl {
132130
this.addEditorTab('Axes', 'public/app/plugins/panel/graph/tab_axes.html', 2);
133131
this.addEditorTab('Legend', 'public/app/plugins/panel/graph/tab_legend.html', 3);
134132
this.addEditorTab('Display', 'public/app/plugins/panel/graph/tab_display.html', 4);
133+
135134
if (config.alertingEnabled) {
136135
this.addEditorTab('Alerting', graphAlertEditor, 5);
137136
}

0 commit comments

Comments
 (0)