diff --git a/public/app/plugins/panel/graph/alert_tab_ctrl.ts b/public/app/plugins/panel/graph/alert_tab_ctrl.ts index 7e3c8d7b963..4ee59248257 100644 --- a/public/app/plugins/panel/graph/alert_tab_ctrl.ts +++ b/public/app/plugins/panel/graph/alert_tab_ctrl.ts @@ -22,7 +22,7 @@ var alertQueryDef = new QueryPartDef({ export class AlertTabCtrl { panel: any; panelCtrl: any; - metricTargets = [{ refId: '- select query -' } ]; + metricTargets; handlers = [{text: 'Grafana', value: 1}, {text: 'External', value: 0}]; transforms = [ { @@ -36,6 +36,7 @@ export class AlertTabCtrl { ]; aggregators = ['avg', 'sum', 'min', 'max', 'last']; alert: any; + thresholds: any; query: any; queryParams: any; transformDef: any; @@ -45,24 +46,6 @@ export class AlertTabCtrl { {text: '=', value: '='}, ]; - defaultValues = { - frequency: '60s', - notify: [], - enabled: false, - handler: 1, - warn: { op: '>', level: undefined }, - critical: { op: '>', level: undefined }, - query: { - refId: 'A', - from: '5m', - to: 'now', - }, - transform: { - type: 'aggregation', - method: 'avg' - } - }; - /** @ngInject */ constructor($scope, private $timeout) { this.panelCtrl = $scope.ctrl; @@ -70,7 +53,7 @@ export class AlertTabCtrl { $scope.ctrl = this; this.metricTargets = this.panel.targets.map(val => val); - this.initAlertModel(); + this.initModel(); // set panel alert edit mode $scope.$on("$destroy", () => { @@ -79,32 +62,63 @@ export class AlertTabCtrl { }); } - initAlertModel() { - if (!this.panel.alert) { + getThresholdWithDefaults(thresholds, type, copyFrom) { + var threshold = thresholds[type] || {}; + var defaultValue = (copyFrom[type] || {}).value || undefined; + + threshold.op = threshold.op || '>'; + threshold.value = threshold.value || defaultValue; + return threshold; + } + + initThresholdsOnlyMode() { + if (!this.panel.thresholds) { return; } - this.alert = this.panel.alert; + this.thresholds = this.panel.thresholds; - // set defaults - _.defaults(this.alert, this.defaultValues); + // set threshold defaults + this.thresholds.warn = this.getThresholdWithDefaults(this.thresholds, 'warn', {}); + this.thresholds.crit = this.getThresholdWithDefaults(this.thresholds, 'crit', {}); - var defaultName = (this.panelCtrl.dashboard.title + ' ' + this.panel.title + ' alert'); - this.alert.name = this.alert.name || defaultName; - this.alert.description = this.alert.description || defaultName; + this.panelCtrl.editingAlert = true; + this.panelCtrl.render(); + } + + initModel() { + var alert = this.alert = this.panel.alert = this.panel.alert || {}; + + // set threshold defaults + alert.thresholds = alert.thresholds || {}; + alert.thresholds.warn = this.getThresholdWithDefaults(alert.thresholds, 'warn', this.panel.thresholds); + alert.thresholds.crit = this.getThresholdWithDefaults(alert.thresholds, 'crit', this.panel.thresholds); + + alert.frequency = alert.frequency || '60s'; + alert.handler = alert.handler || 1; + alert.notifications = alert.notifications || []; + + alert.query = alert.query || {}; + alert.query.refId = alert.query.refId || 'A'; + alert.query.from = alert.query.from || '5m'; + alert.query.to = alert.query.to || 'now'; + + alert.transform = alert.transform || {}; + alert.transform.type = alert.transform.type || 'aggregation'; + alert.transform.method = alert.transform.method || 'avg'; + + var defaultName = this.panel.title + ' alert'; + alert.name = alert.name || defaultName; + alert.description = alert.description || defaultName; // great temp working model this.queryParams = { - params: [ - this.alert.query.refId, - this.alert.query.from, - this.alert.query.to - ] + params: [alert.query.refId, alert.query.from, alert.query.to] }; // init the query part components model this.query = new QueryPart(this.queryParams, alertQueryDef); - this.transformDef = _.findWhere(this.transforms, {type: this.alert.transform.type}); + this.transformDef = _.findWhere(this.transforms, {type: alert.transform.type}); this.panelCtrl.editingAlert = true; this.panelCtrl.render(); @@ -135,22 +149,26 @@ export class AlertTabCtrl { } } - operatorChanged() { - this.panelCtrl.render(); - } - delete() { + delete this.alert; delete this.panel.alert; - this.panelCtrl.editingAlert = false; - this.panelCtrl.render(); + // clear thresholds + if (this.panel.thresholds) { + this.panel.thresholds = {}; + } + this.initModel(); } enable() { + if (this.thresholds) { + delete this.thresholds; + this.panelCtrl. + } this.panel.alert = {}; - this.initAlertModel(); + this.initModel(); } - levelsUpdated() { + thresholdsUpdated() { this.panelCtrl.render(); } } diff --git a/public/app/plugins/panel/graph/graph.js b/public/app/plugins/panel/graph/graph.js index 599bbe554bf..381565e8f3f 100755 --- a/public/app/plugins/panel/graph/graph.js +++ b/public/app/plugins/panel/graph/graph.js @@ -5,7 +5,7 @@ define([ 'lodash', 'app/core/utils/kbn', './graph_tooltip', - './alert_handle', + './thresholds', 'jquery.flot', 'jquery.flot.selection', 'jquery.flot.time', @@ -15,7 +15,7 @@ define([ 'jquery.flot.crosshair', './jquery.flot.events', ], -function (angular, $, moment, _, kbn, GraphTooltip, AlertHandle) { +function (angular, $, moment, _, kbn, GraphTooltip, thresholds) { 'use strict'; var module = angular.module('grafana.directives'); @@ -23,7 +23,7 @@ function (angular, $, moment, _, kbn, GraphTooltip, AlertHandle) { var panelWidthCache = {}; // systemjs export - var AlertHandleManager = AlertHandle.AlertHandleManager; + var ThresholdControls = thresholds.ThresholdControls; module.directive('grafanaGraph', function($rootScope, timeSrv) { return { @@ -38,7 +38,7 @@ function (angular, $, moment, _, kbn, GraphTooltip, AlertHandle) { var legendSideLastValue = null; var rootScope = scope.$root; var panelWidth = 0; - var alertHandles; + var thresholdControls; rootScope.onAppEvent('setCrosshair', function(event, info) { // do not need to to this if event is from this panel @@ -167,8 +167,8 @@ function (angular, $, moment, _, kbn, GraphTooltip, AlertHandle) { rightLabel[0].style.marginTop = (getLabelWidth(panel.yaxes[1].label, rightLabel) / 2) + 'px'; } - if (alertHandles) { - alertHandles.draw(plot); + if (thresholdControls) { + thresholdControls.draw(plot); } } @@ -192,14 +192,14 @@ function (angular, $, moment, _, kbn, GraphTooltip, AlertHandle) { // give space to alert editing if (ctrl.editingAlert) { - if (!alertHandles) { + if (!thresholdControls) { elem.css('margin-right', '220px'); - alertHandles = new AlertHandleManager(ctrl); + thresholdControls = new ThresholdControls(ctrl); } - } else if (alertHandles) { + } else if (thresholdControls) { elem.css('margin-right', '0'); - alertHandles.cleanUp(); - alertHandles = null; + thresholdControls.cleanUp(); + thresholdControls = null; } var stack = panel.stack ? true : null; @@ -333,70 +333,73 @@ function (angular, $, moment, _, kbn, GraphTooltip, AlertHandle) { } function addGridThresholds(options, panel) { + var thresholds = panel.thresholds; + + // use alert thresholds if there are any if (panel.alert) { - var crit = panel.alert.critical; - var warn = panel.alert.warn; - var critEdge = Infinity; - var warnEdge = crit.level; - - if (_.isNumber(crit.level)) { - if (crit.op === '<') { - critEdge = -Infinity; - } - - // fill - options.grid.markings.push({ - yaxis: {from: crit.level, to: critEdge}, - color: 'rgba(234, 112, 112, 0.10)', - }); - - // line - options.grid.markings.push({ - yaxis: {from: crit.level, to: crit.level}, - color: '#ed2e18' - }); - } - - if (_.isNumber(warn.level)) { - // if (warn.op === '<') { - // } - - // fill - options.grid.markings.push({ - yaxis: {from: warn.level, to: warnEdge}, - color: 'rgba(216, 200, 27, 0.10)', - }); - - // line - options.grid.markings.push({ - yaxis: {from: warn.level, to: warn.level}, - color: '#F79520' - }); - } - - return; + thresholds = panel.alert.thresholds; } - if (_.isNumber(panel.grid.threshold1)) { - var limit1 = panel.grid.thresholdLine ? panel.grid.threshold1 : (panel.grid.threshold2 || null); + var crit = thresholds.crit; + var warn = thresholds.warn; + var critEdge = Infinity; + var warnEdge = crit.value; + + if (_.isNumber(crit.value)) { + if (crit.op === '<') { + critEdge = -Infinity; + } + + // fill options.grid.markings.push({ - yaxis: { from: panel.grid.threshold1, to: limit1 }, - color: panel.grid.threshold1Color + yaxis: {from: crit.value, to: critEdge}, + color: 'rgba(234, 112, 112, 0.10)', }); - if (_.isNumber(panel.grid.threshold2)) { - var limit2; - if (panel.grid.thresholdLine) { - limit2 = panel.grid.threshold2; - } else { - limit2 = panel.grid.threshold1 > panel.grid.threshold2 ? -Infinity : +Infinity; - } - options.grid.markings.push({ - yaxis: { from: panel.grid.threshold2, to: limit2 }, - color: panel.grid.threshold2Color - }); - } + // line + options.grid.markings.push({ + yaxis: {from: crit.value, to: crit.value}, + color: '#ed2e18' + }); } + + if (_.isNumber(warn.value)) { + // if (warn.op === '<') { + // } + + // fill + options.grid.markings.push({ + yaxis: {from: warn.value, to: warnEdge}, + color: 'rgba(216, 200, 27, 0.10)', + }); + + // line + options.grid.markings.push({ + yaxis: {from: warn.value, to: warn.value}, + color: '#F79520' + }); + } + + // if (_.isNumber(panel.grid.threshold1)) { + // var limit1 = panel.grid.thresholdLine ? panel.grid.threshold1 : (panel.grid.threshold2 || null); + // options.grid.markings.push({ + // yaxis: { from: panel.grid.threshold1, to: limit1 }, + // color: panel.grid.threshold1Color + // }); + // + // if (_.isNumber(panel.grid.threshold2)) { + // var limit2; + // if (panel.grid.thresholdLine) { + // limit2 = panel.grid.threshold2; + // } else { + // limit2 = panel.grid.threshold1 > panel.grid.threshold2 ? -Infinity : +Infinity; + // } + // options.grid.markings.push({ + // yaxis: { from: panel.grid.threshold2, to: limit2 }, + // color: panel.grid.threshold2Color + // }); + // } + // } } function addAnnotations(options) { diff --git a/public/app/plugins/panel/graph/module.ts b/public/app/plugins/panel/graph/module.ts index c79fd421995..481b6223e33 100644 --- a/public/app/plugins/panel/graph/module.ts +++ b/public/app/plugins/panel/graph/module.ts @@ -54,11 +54,9 @@ class GraphCtrl extends MetricsPanelCtrl { xaxis: { show: true }, - grid : { - threshold1: null, - threshold2: null, - threshold1Color: 'rgba(216, 200, 27, 0.27)', - threshold2Color: 'rgba(234, 112, 112, 0.22)' + thresholds: { + warn: {op: '>', level: undefined}, + crit: {op: '>', level: undefined}, }, // show/hide lines lines : true, @@ -115,7 +113,7 @@ class GraphCtrl extends MetricsPanelCtrl { _.defaults(this.panel, this.panelDefaults); _.defaults(this.panel.tooltip, this.panelDefaults.tooltip); - _.defaults(this.panel.grid, this.panelDefaults.grid); + _.defaults(this.panel.thresholds, this.panelDefaults.thresholds); _.defaults(this.panel.legend, this.panelDefaults.legend); this.colors = $scope.$root.colors; @@ -132,6 +130,7 @@ class GraphCtrl extends MetricsPanelCtrl { this.addEditorTab('Axes', 'public/app/plugins/panel/graph/tab_axes.html', 2); this.addEditorTab('Legend', 'public/app/plugins/panel/graph/tab_legend.html', 3); this.addEditorTab('Display', 'public/app/plugins/panel/graph/tab_display.html', 4); + if (config.alertingEnabled) { this.addEditorTab('Alerting', graphAlertEditor, 5); } diff --git a/public/app/plugins/panel/graph/partials/tab_alerting.html b/public/app/plugins/panel/graph/partials/tab_alerting.html index 0b6ed66f066..38873ec829e 100644 --- a/public/app/plugins/panel/graph/partials/tab_alerting.html +++ b/public/app/plugins/panel/graph/partials/tab_alerting.html @@ -1,5 +1,29 @@ -
+
+
+
Visual Thresholds
+
+
+ + + Critcal if + + + +
+
+ + + Warn if + + + +
+
+
+
+ +
Alert Query
@@ -39,23 +63,23 @@
-
Levels
+
Thresholds
-
+
Critcal if - - + +
-
+
Warn if - - + +
@@ -111,10 +135,10 @@
- - +
diff --git a/public/app/plugins/panel/graph/tab_axes.html b/public/app/plugins/panel/graph/tab_axes.html index eeaf27aff78..bb051649424 100644 --- a/public/app/plugins/panel/graph/tab_axes.html +++ b/public/app/plugins/panel/graph/tab_axes.html @@ -42,33 +42,4 @@
-
-
Thresholds
-
-
- - -
-
- -
- -
-
-
-
-
- - -
-
- -
- -
-
-
- - -
diff --git a/public/app/plugins/panel/graph/alert_handle.ts b/public/app/plugins/panel/graph/thresholds.ts similarity index 71% rename from public/app/plugins/panel/graph/alert_handle.ts rename to public/app/plugins/panel/graph/thresholds.ts index cc37a346cec..efd3dbe89fb 100644 --- a/public/app/plugins/panel/graph/alert_handle.ts +++ b/public/app/plugins/panel/graph/thresholds.ts @@ -4,14 +4,14 @@ import 'jquery.flot'; import $ from 'jquery'; import _ from 'lodash'; -export class AlertHandleManager { +export class ThresholdControls { plot: any; placeholder: any; height: any; - alert: any; + thresholds: any; constructor(private panelCtrl) { - this.alert = panelCtrl.panel.alert; + this.thresholds = this.panelCtrl.thresholds; } getHandleInnerHtml(type, op, value) { @@ -36,7 +36,7 @@ export class AlertHandleManager { `; } - setupDragging(handleElem, levelModel) { + setupDragging(handleElem, threshold) { var isMoving = false; var lastY = null; var posTop; @@ -57,11 +57,11 @@ export class AlertHandleManager { function stopped() { isMoving = false; // calculate graph level - var graphLevel = plot.c2p({left: 0, top: posTop}).y; - graphLevel = parseInt(graphLevel.toFixed(0)); - levelModel.level = graphLevel; + var graphValue = plot.c2p({left: 0, top: posTop}).y; + graphValue = parseInt(graphValue.toFixed(0)); + threshold.value = graphValue; - var levelCanvasPos = plot.p2c({x: 0, y: graphLevel}); + var valueCanvasPos = plot.p2c({x: 0, y: graphValue}); handleElem.off("mousemove", dragging); handleElem.off("mouseup", dragging); @@ -90,28 +90,28 @@ export class AlertHandleManager { renderHandle(type, model, defaultHandleTopPos) { var handleElem = this.placeholder.find(`.alert-handle-wrapper--${type}`); - var level = model.level; - var levelStr = level; + var value = model.value; + var valueStr = value; var handleTopPos = 0; // handle no value - if (!_.isNumber(level)) { - levelStr = ''; + if (!_.isNumber(value)) { + valueStr = ''; handleTopPos = defaultHandleTopPos; } else { - var levelCanvasPos = this.plot.p2c({x: 0, y: level}); - handleTopPos = Math.min(Math.max(levelCanvasPos.top, 0), this.height) - 6; + var valueCanvasPos = this.plot.p2c({x: 0, y: value}); + handleTopPos = Math.min(Math.max(valueCanvasPos.top, 0), this.height) - 6; } if (handleElem.length === 0) { - handleElem = $(this.getFullHandleHtml(type, model.op, levelStr)); + handleElem = $(this.getFullHandleHtml(type, model.op, valueStr)); this.placeholder.append(handleElem); this.setupDragging(handleElem, model); } else { - handleElem.html(this.getHandleInnerHtml(type, model.op, levelStr)); + handleElem.html(this.getHandleInnerHtml(type, model.op, valueStr)); } - handleElem.toggleClass('alert-handle-wrapper--no-value', levelStr === ''); + handleElem.toggleClass('alert-handle-wrapper--no-value', valueStr === ''); handleElem.css({top: handleTopPos}); } @@ -120,9 +120,10 @@ export class AlertHandleManager { this.placeholder = plot.getPlaceholder(); this.height = plot.height(); - this.renderHandle('critical', this.alert.critical, 10); - this.renderHandle('warn', this.alert.warn, this.height-30); + this.renderHandle('crit', this.thresholds.crit, 10); + this.renderHandle('warn', this.thresholds.warn, this.height-30); } + debugger; } diff --git a/public/sass/base/_grafana_icons.scss b/public/sass/base/_grafana_icons.scss index f3264d409cd..f251427e7c9 100644 --- a/public/sass/base/_grafana_icons.scss +++ b/public/sass/base/_grafana_icons.scss @@ -31,7 +31,7 @@ .icon-gf-raintank_wordmark:before { content: "\e600"; } -.icon-gf-raintank_icn:before { +.micon-gf-raintank_icn:before { content: "\e601"; } .icon-gf-raintank_r-icn:before { @@ -88,6 +88,9 @@ .icon-gf-critical:before { content: "\e610"; } +.icon-gf-crit:before { + content: "\e610"; +} .icon-gf-online:before { content: "\e611"; } diff --git a/public/sass/components/_alerts.scss b/public/sass/components/_alerts.scss index 9f67f84d499..aee80b500fb 100644 --- a/public/sass/components/_alerts.scss +++ b/public/sass/components/_alerts.scss @@ -15,6 +15,7 @@ color: $warn; } +.alert-icon-crit, .alert-icon-critical { color: $critical; } diff --git a/public/sass/components/_panel_graph.scss b/public/sass/components/_panel_graph.scss index 5c85ac4d465..ecf1cb6b82c 100644 --- a/public/sass/components/_panel_graph.scss +++ b/public/sass/components/_panel_graph.scss @@ -363,7 +363,7 @@ } } - &--critical { + &--crit{ right: -105px; width: 123px;