From efa869bb89dc806d52133d5ef3d44b7220288e21 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Wed, 21 Feb 2018 15:26:45 +0300 Subject: [PATCH] prometheus: initial heatmap support --- .../datasource/prometheus/datasource.ts | 66 ++++++++++++++++++- .../datasource/prometheus/query_ctrl.ts | 9 ++- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 122fe9601a1..ba3dcda390e 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -106,17 +106,29 @@ export class PrometheusDatasource { }); return this.$q.all(allQueryPromise).then(responseList => { - var result = []; + let result = []; _.each(responseList, (response, index) => { if (response.status === 'error') { throw response.error; } + let prometheusResult = response.data.data.result; + if (activeTargets[index].format === 'table') { - result.push(self.transformMetricDataToTable(response.data.data.result, responseList.length, index)); + result.push(self.transformMetricDataToTable(prometheusResult, responseList.length, index)); + } else if (activeTargets[index].format === 'heatmap') { + let seriesList = []; + prometheusResult.sort(sortSeriesByLabel); + for (let metricData of prometheusResult) { + seriesList.push( + self.transformMetricData(metricData, activeTargets[index], start, end, queries[index].step) + ); + } + seriesList = self.transformToHistogramOverTime(seriesList); + result.push(...seriesList); } else { - for (let metricData of response.data.data.result) { + for (let metricData of prometheusResult) { if (response.data.data.resultType === 'matrix') { result.push(self.transformMetricData(metricData, activeTargets[index], start, end, queries[index].step)); } else if (response.data.data.resultType === 'vector') { @@ -378,6 +390,24 @@ export class PrometheusDatasource { return { target: metricLabel, datapoints: dps }; } + transformToHistogramOverTime(seriesList, options?) { + /* t1 = timestamp1, t2 = timestamp2 etc. + t1 t2 t3 t1 t2 t3 + le10 10 10 0 => 10 10 0 + le20 20 10 30 => 10 0 30 + le30 30 10 35 => 10 0 5 + */ + for (let i = seriesList.length - 1; i > 0; i--) { + let topSeries = seriesList[i].datapoints; + let bottomSeries = seriesList[i - 1].datapoints; + for (let j = 0; j < topSeries.length; j++) { + topSeries[j][0] -= bottomSeries[j][0]; + } + } + + return seriesList; + } + createMetricLabel(labelData, options) { if (_.isUndefined(options) || _.isEmpty(options.legendFormat)) { return this.getOriginalMetricName(labelData); @@ -412,3 +442,33 @@ export class PrometheusDatasource { return Math.ceil(date.valueOf() / 1000); } } + +function sortSeriesByLabel(s1, s2) { + let le1, le2; + + try { + // fail if not integer. might happen with bad queries + le1 = parseHistogramLabel(s1.metric.le); + le2 = parseHistogramLabel(s2.metric.le); + } catch (err) { + console.log(err); + return 0; + } + + if (le1 > le2) { + return 1; + } + + if (le1 < le2) { + return -1; + } + + return 0; +} + +function parseHistogramLabel(le: string): number { + if (le === '+Inf') { + return +Infinity; + } + return parseInt(le); +} diff --git a/public/app/plugins/datasource/prometheus/query_ctrl.ts b/public/app/plugins/datasource/prometheus/query_ctrl.ts index 2674fc55af4..ea5588b253a 100644 --- a/public/app/plugins/datasource/prometheus/query_ctrl.ts +++ b/public/app/plugins/datasource/prometheus/query_ctrl.ts @@ -31,7 +31,11 @@ class PrometheusQueryCtrl extends QueryCtrl { return { factor: f, label: '1/' + f }; }); - this.formats = [{ text: 'Time series', value: 'time_series' }, { text: 'Table', value: 'table' }]; + this.formats = [ + { text: 'Time series', value: 'time_series' }, + { text: 'Table', value: 'table' }, + { text: 'Heatmap', value: 'heatmap' }, + ]; this.instant = false; @@ -45,7 +49,10 @@ class PrometheusQueryCtrl extends QueryCtrl { getDefaultFormat() { if (this.panelCtrl.panel.type === 'table') { return 'table'; + } else if (this.panelCtrl.panel.type === 'heatmap') { + return 'heatmap'; } + return 'time_series'; }