From f8b05e0f42f6274a0539b46f8d4531d6ada46784 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Fri, 2 Oct 2015 03:19:25 +0900 Subject: [PATCH 01/56] add prometheus annotation query --- .../datasource/prometheus/datasource.ts | 67 +++++++++++++++++-- .../plugins/datasource/prometheus/module.ts | 7 +- .../partials/annotations.editor.html | 28 ++++++++ .../plugins/datasource/prometheus/plugin.json | 3 +- .../prometheus/specs/datasource_specs.ts | 35 ++++++++++ 5 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 public/app/plugins/datasource/prometheus/partials/annotations.editor.html diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 0a81e04831b..4aff842d38b 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -188,6 +188,58 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS } }; + this.annotationQuery = function(options) { + var annotation = options.annotation; + var expr = annotation.expr || ''; + var tagKeys = annotation.tagKeys || ''; + var titleFormat = annotation.titleFormat || ''; + var textFormat = annotation.textFormat || ''; + + if (!expr) { return $q.when([]); } + + var interpolated; + try { + interpolated = templateSrv.replace(expr); + } + catch (err) { + return $q.reject(err); + } + + var query = { + expr: interpolated, + step: '60s' + }; + var start = getPrometheusTime(options.range.from, false); + var end = getPrometheusTime(options.range.to, true); + return this.performTimeSeriesQuery(query, start, end).then(function(results) { + var eventList = []; + tagKeys = tagKeys.split(','); + + _.each(results.data.data.result, function(series) { + var tags = _.chain(series.metric) + .filter(function(v, k) { + return _.contains(tagKeys, k); + }).value(); + + _.each(series.values, function(value) { + if (value[1] === '1') { + var event = { + annotation: annotation, + time: Math.floor(value[0]) * 1000, + title: renderTemplate(titleFormat, series.metric), + tags: tags, + text: renderTemplate(textFormat, series.metric) + }; + + eventList.push(event); + } + }); + }); + + return eventList; + }); + }; + this.testDatasource = function() { return this.metricFindQuery('metrics(.*)').then(function() { return { status: 'success', message: 'Data source is working', title: 'Success' }; @@ -240,22 +292,25 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS return getOriginalMetricName(labelData); } - var originalSettings = _.templateSettings; + return renderTemplate(options.legendFormat, labelData) || '{}'; + } + + function renderTemplate(format, data) { _.templateSettings = { interpolate: /\{\{(.+?)\}\}/g }; - var template = _.template(templateSrv.replace(options.legendFormat)); - var metricName; + var template = _.template(templateSrv.replace(format)); + var result; try { - metricName = template(labelData); + result = template(data); } catch (e) { - metricName = '{}'; + result = null; } _.templateSettings = originalSettings; - return metricName; + return result; } function getOriginalMetricName(labelData) { diff --git a/public/app/plugins/datasource/prometheus/module.ts b/public/app/plugins/datasource/prometheus/module.ts index 9af37384b4f..0ddba422bcc 100644 --- a/public/app/plugins/datasource/prometheus/module.ts +++ b/public/app/plugins/datasource/prometheus/module.ts @@ -5,8 +5,13 @@ class PrometheusConfigCtrl { static templateUrl = 'public/app/plugins/datasource/prometheus/partials/config.html'; } +class PrometheusAnnotationsQueryCtrl { + static templateUrl = 'public/app/plugins/datasource/prometheus/partials/annotations.editor.html'; +} + export { PrometheusDatasource as Datasource, PrometheusQueryCtrl as QueryCtrl, - PrometheusConfigCtrl as ConfigCtrl + PrometheusConfigCtrl as ConfigCtrl, + PrometheusAnnotationsQueryCtrl as AnnotationsQueryCtrl, }; diff --git a/public/app/plugins/datasource/prometheus/partials/annotations.editor.html b/public/app/plugins/datasource/prometheus/partials/annotations.editor.html new file mode 100644 index 00000000000..d8110b03c52 --- /dev/null +++ b/public/app/plugins/datasource/prometheus/partials/annotations.editor.html @@ -0,0 +1,28 @@ +
+
+
Search expression
+
+ +
+
+
+ +
+
+
Field formats
+
+ + +
+ +
+ + +
+ +
+ + +
+
+
diff --git a/public/app/plugins/datasource/prometheus/plugin.json b/public/app/plugins/datasource/prometheus/plugin.json index 4cd55605816..66dd9145e6a 100644 --- a/public/app/plugins/datasource/prometheus/plugin.json +++ b/public/app/plugins/datasource/prometheus/plugin.json @@ -3,5 +3,6 @@ "name": "Prometheus", "id": "prometheus", - "metrics": true + "metrics": true, + "annotations": true } diff --git a/public/app/plugins/datasource/prometheus/specs/datasource_specs.ts b/public/app/plugins/datasource/prometheus/specs/datasource_specs.ts index fc3d2f489de..043546a9398 100644 --- a/public/app/plugins/datasource/prometheus/specs/datasource_specs.ts +++ b/public/app/plugins/datasource/prometheus/specs/datasource_specs.ts @@ -157,4 +157,39 @@ describe('PrometheusDatasource', function() { expect(results.length).to.be(3); }); }); + describe('When performing annotationQuery', function() { + var results; + var urlExpected = 'proxied/api/v1/query_range?query=' + + encodeURIComponent('ALERTS{alertstate="firing"}') + + '&start=1443438675&end=1443460275&step=60s'; + var annotation = { + expr: 'ALERTS{alertstate="firing"}', + tagKeys: 'job', + titleFormat: '{{alertname}}', + textFormat: '{{instance}}' + }; + var response = { + status: "success", + data: { + resultType: "matrix", + result: [{ + metric: {"__name__": "ALERTS", alertname: "InstanceDown", alertstate: "firing", instance: "testinstance", job: "testjob"}, + values: [[1443454528, "1"]] + }] + } + }; + beforeEach(function() { + ctx.$httpBackend.expect('GET', urlExpected).respond(response); + ctx.ds.annotationQuery(annotation, {from: moment(1443438674760), to: moment(1443460274760)}).then(function(data) { results = data; }); + ctx.$httpBackend.flush(); + }); + it('should return annotation list', function() { + ctx.$rootScope.$apply(); + expect(results.length).to.be(1); + expect(results[0].tags).to.contain('testjob'); + expect(results[0].title).to.be('InstanceDown'); + expect(results[0].text).to.be('testinstance'); + expect(results[0].time).to.be(1443454528 * 1000); + }); + }); }); From ee84d4371b4d78c67b2eb197e8a856561b6ab18d Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Fri, 13 Nov 2015 02:33:21 +0900 Subject: [PATCH 02/56] fix prometheus annotation, reflect API change --- .../prometheus/specs/datasource_specs.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/specs/datasource_specs.ts b/public/app/plugins/datasource/prometheus/specs/datasource_specs.ts index 043546a9398..4a1b4121dba 100644 --- a/public/app/plugins/datasource/prometheus/specs/datasource_specs.ts +++ b/public/app/plugins/datasource/prometheus/specs/datasource_specs.ts @@ -162,11 +162,17 @@ describe('PrometheusDatasource', function() { var urlExpected = 'proxied/api/v1/query_range?query=' + encodeURIComponent('ALERTS{alertstate="firing"}') + '&start=1443438675&end=1443460275&step=60s'; - var annotation = { - expr: 'ALERTS{alertstate="firing"}', - tagKeys: 'job', - titleFormat: '{{alertname}}', - textFormat: '{{instance}}' + var options = { + annotation: { + expr: 'ALERTS{alertstate="firing"}', + tagKeys: 'job', + titleFormat: '{{alertname}}', + textFormat: '{{instance}}' + }, + range: { + from: moment(1443438674760), + to: moment(1443460274760) + } }; var response = { status: "success", @@ -180,7 +186,7 @@ describe('PrometheusDatasource', function() { }; beforeEach(function() { ctx.$httpBackend.expect('GET', urlExpected).respond(response); - ctx.ds.annotationQuery(annotation, {from: moment(1443438674760), to: moment(1443460274760)}).then(function(data) { results = data; }); + ctx.ds.annotationQuery(options).then(function(data) { results = data; }); ctx.$httpBackend.flush(); }); it('should return annotation list', function() { From 7a1326ff142b880c617c0199323202187965eeb6 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Fri, 15 Jan 2016 11:00:09 +0900 Subject: [PATCH 03/56] follow new plugin format --- .../prometheus/partials/annotations.editor.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/partials/annotations.editor.html b/public/app/plugins/datasource/prometheus/partials/annotations.editor.html index d8110b03c52..2612c611849 100644 --- a/public/app/plugins/datasource/prometheus/partials/annotations.editor.html +++ b/public/app/plugins/datasource/prometheus/partials/annotations.editor.html @@ -2,7 +2,7 @@
Search expression
- +
@@ -12,17 +12,17 @@
Field formats
- +
- +
- +
From 7d97f381cf33407f364944c0f175299a8a190bb5 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Thu, 4 Feb 2016 14:09:59 +0900 Subject: [PATCH 04/56] fix tslint error --- public/app/plugins/datasource/prometheus/datasource.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 4aff842d38b..804115e849b 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -200,8 +200,7 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS var interpolated; try { interpolated = templateSrv.replace(expr); - } - catch (err) { + } catch (err) { return $q.reject(err); } From 634699c8e2c0520729234a274858a1d0d8fe21b9 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Thu, 4 Feb 2016 14:10:27 +0900 Subject: [PATCH 05/56] fix prometheus datasource plugin --- public/app/plugins/datasource/prometheus/datasource.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 804115e849b..4cfd174978c 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -295,6 +295,7 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS } function renderTemplate(format, data) { + var originalSettings = _.templateSettings; _.templateSettings = { interpolate: /\{\{(.+?)\}\}/g }; From 20283a46f9bd8fbc4614f3f47a2dd9175f24dad6 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Thu, 4 Feb 2016 14:14:19 +0900 Subject: [PATCH 06/56] fix annotation editor error --- .../prometheus/partials/annotations.editor.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/partials/annotations.editor.html b/public/app/plugins/datasource/prometheus/partials/annotations.editor.html index 2612c611849..ffeb7d6deea 100644 --- a/public/app/plugins/datasource/prometheus/partials/annotations.editor.html +++ b/public/app/plugins/datasource/prometheus/partials/annotations.editor.html @@ -2,7 +2,7 @@
Search expression
- +
@@ -12,17 +12,17 @@
Field formats
- +
- +
- +
From a5d1e9ee438c920e271a7e42bb2d7141b50daca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sun, 7 Feb 2016 18:37:07 +0100 Subject: [PATCH 07/56] fix(singlestat): fix for singlestat background and sparklines, fixes #3955 --- public/app/plugins/panel/singlestat/module.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/public/app/plugins/panel/singlestat/module.ts b/public/app/plugins/panel/singlestat/module.ts index 7eee8524d8c..34ee0b52be7 100644 --- a/public/app/plugins/panel/singlestat/module.ts +++ b/public/app/plugins/panel/singlestat/module.ts @@ -241,7 +241,8 @@ class SingleStatCtrl extends MetricsPanelCtrl { var panel = ctrl.panel; var templateSrv = this.templateSrv; var data, linkInfo; - var $panelContainer = elem.parents('.panel-container'); + var elemHeight; + var $panelContainer = elem.find('.panel-container'); // change elem to singlestat panel elem = elem.find('.singlestat-panel'); hookupDrilldownLinkTooltip(); @@ -253,15 +254,15 @@ class SingleStatCtrl extends MetricsPanelCtrl { function setElementHeight() { try { - var height = scope.height || panel.height || ctrl.row.height; - if (_.isString(height)) { - height = parseInt(height.replace('px', ''), 10); + elemHeight = ctrl.height || panel.height || ctrl.row.height; + if (_.isString(elemHeight)) { + elemHeight = parseInt(elemHeight.replace('px', ''), 10); } - height -= 5; // padding - height -= panel.title ? 24 : 9; // subtract panel title bar + elemHeight -= 5; // padding + elemHeight -= panel.title ? 24 : 9; // subtract panel title bar - elem.css('height', height + 'px'); + elem.css('height', elemHeight + 'px'); return true; } catch (e) { // IE throws errors sometimes @@ -305,7 +306,7 @@ class SingleStatCtrl extends MetricsPanelCtrl { function addSparkline() { var width = elem.width() + 20; - var height = elem.height() || 100; + var height = elemHeight; var plotCanvas = $('
'); var plotCss: any = {}; From 7f83be3d0d4a47f057353f1c9394686097af0dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 8 Feb 2016 09:06:28 +0100 Subject: [PATCH 08/56] ux(): mini fix! --- public/less/sidemenu.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/less/sidemenu.less b/public/less/sidemenu.less index d58f5a654cc..79d79e9750c 100644 --- a/public/less/sidemenu.less +++ b/public/less/sidemenu.less @@ -192,7 +192,7 @@ .sidemenu-org { border-bottom: @sideMenuBorder; - //box-shadow: @sideMenuTopShadow; + border-top: @sideMenuBorder; padding: 17px 10px 15px 21px; box-sizing: border-box; cursor: pointer; From edebdb166eee95903122291fca9ffa1b1b4770cd Mon Sep 17 00:00:00 2001 From: bergquist Date: Mon, 8 Feb 2016 09:20:17 +0100 Subject: [PATCH 09/56] fix(graph): add missing ctrl in variable --- public/app/plugins/panel/graph/axisEditor.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/plugins/panel/graph/axisEditor.html b/public/app/plugins/panel/graph/axisEditor.html index b1d6d9753c0..f7e183a5651 100644 --- a/public/app/plugins/panel/graph/axisEditor.html +++ b/public/app/plugins/panel/graph/axisEditor.html @@ -184,7 +184,7 @@
  • Side width
  • -
  • +
  • From 73bed3880f3232f0eb9805e1ef91d7b3a2c97252 Mon Sep 17 00:00:00 2001 From: bergquist Date: Mon, 8 Feb 2016 09:49:53 +0100 Subject: [PATCH 10/56] feat(graph): sets fixed height for right side legend closes #1277 --- public/app/plugins/panel/graph/legend.js | 8 ++++++++ public/less/panel_graph.less | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/public/app/plugins/panel/graph/legend.js b/public/app/plugins/panel/graph/legend.js index a1777772c98..a09bbbb6cb1 100644 --- a/public/app/plugins/panel/graph/legend.js +++ b/public/app/plugins/panel/graph/legend.js @@ -90,6 +90,14 @@ function (angular, _, $) { } function render() { + if (panel.legend.rightSide) { + var panelheight = scope.ctrl.height || scope.ctrl.panel.height || scope.ctrl.row.height; + $container.css("height", panelheight); + $container.toggleClass('graph-legend-fixed-height', true); + } else { + $container.css("height", ""); + } + if (firstRender) { elem.append($container); $container.on('click', '.graph-legend-icon', openColorSelector); diff --git a/public/less/panel_graph.less b/public/less/panel_graph.less index a0350d5d16c..36e96d67441 100644 --- a/public/less/panel_graph.less +++ b/public/less/panel_graph.less @@ -60,7 +60,6 @@ } .graph-legend-table { - display: table; width: 100%; margin: 0; @@ -272,4 +271,6 @@ font-size: 12px; } - +.graph-legend-fixed-height { + overflow-y: scroll; +} From de90ad8967bf5a94c668a96c25a4cd89bfdca46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 8 Feb 2016 10:31:26 +0100 Subject: [PATCH 11/56] feat(influxdb): escape influxdb tag values, fixes #3950 --- public/app/plugins/datasource/influxdb/influx_query.ts | 4 ++-- .../plugins/datasource/influxdb/specs/influx_query_specs.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/datasource/influxdb/influx_query.ts b/public/app/plugins/datasource/influxdb/influx_query.ts index 6eb2d84aa49..cbdb61bca24 100644 --- a/public/app/plugins/datasource/influxdb/influx_query.ts +++ b/public/app/plugins/datasource/influxdb/influx_query.ts @@ -6,8 +6,8 @@ import queryPart from './query_part'; export default class InfluxQuery { target: any; selectModels: any[]; - groupByParts: any; queryBuilder: any; + groupByParts: any; constructor(target) { this.target = target; @@ -144,7 +144,7 @@ export default class InfluxQuery { // quote value unless regex if (operator !== '=~' && operator !== '!~') { - value = "'" + value + "'"; + value = "'" + value.replace('\\', '\\\\') + "'"; } return str + '"' + tag.key + '" ' + operator + ' ' + value; diff --git a/public/app/plugins/datasource/influxdb/specs/influx_query_specs.ts b/public/app/plugins/datasource/influxdb/specs/influx_query_specs.ts index be7afa16ab1..3893b8fbc2d 100644 --- a/public/app/plugins/datasource/influxdb/specs/influx_query_specs.ts +++ b/public/app/plugins/datasource/influxdb/specs/influx_query_specs.ts @@ -51,12 +51,12 @@ describe('InfluxQuery', function() { var query = new InfluxQuery({ measurement: 'cpu', groupBy: [{type: 'time', params: ['auto']}], - tags: [{key: 'hostname', value: 'server1'}] + tags: [{key: 'hostname', value: 'server\\1'}] }); var queryText = query.render(); - expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' AND $timeFilter' + expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server\\\\1\' AND $timeFilter' + ' GROUP BY time($interval)'); }); From 0f52b4397f6b098f64415cfb978832b5dcc4c092 Mon Sep 17 00:00:00 2001 From: bergquist Date: Mon, 8 Feb 2016 11:18:41 +0100 Subject: [PATCH 12/56] feat(login): minor ux improvements make buttons bigger and introduce the login divider. closes #3698 --- public/app/partials/login.html | 28 ++++++++++++++++------- public/less/login.less | 41 +++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/public/app/partials/login.html b/public/app/partials/login.html index 27983b54114..b17a9e0545b 100644 --- a/public/app/partials/login.html +++ b/public/app/partials/login.html @@ -65,26 +65,38 @@
    + + +
    + - -
    - + +