From b8aa8b307997dde9f11c28401436cc841f087726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 9 Jun 2016 10:37:33 +0200 Subject: [PATCH] feat(prometheus): restore old prometheus query editor, revert this commit in prometheus query editor v2 branch --- .../datasource/prometheus/datasource.ts | 25 ++-- .../prometheus/metric_find_query.js | 128 +++++++----------- .../prometheus/partials/query.editor.html | 39 ++---- .../datasource/prometheus/prom_query.ts | 119 ---------------- .../datasource/prometheus/query_ctrl.ts | 102 +++----------- .../specs/metric_find_query_specs.ts | 37 ----- .../prometheus/specs/query_specs.ts | 38 ------ 7 files changed, 87 insertions(+), 401 deletions(-) delete mode 100644 public/app/plugins/datasource/prometheus/prom_query.ts delete mode 100644 public/app/plugins/datasource/prometheus/specs/query_specs.ts diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index f1c58f6a61d..cbd7b1ba24b 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -256,23 +256,14 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS return this.renderTemplate(options.legendFormat, labelData) || '{}'; }; - this.renderTemplate = function(format, data) { - var originalSettings = _.templateSettings; - _.templateSettings = { - interpolate: /\{\{(.+?)\}\}/g - }; - - var template = _.template(templateSrv.replace(format)); - var result; - try { - result = template(data); - } catch (e) { - result = null; - } - - _.templateSettings = originalSettings; - - return result; + this.renderTemplate = function(aliasPattern, aliasData) { + var aliasRegex = /\{\{\s*(.+?)\s*\}\}/g; + return aliasPattern.replace(aliasRegex, function(match, g1) { + if (aliasData[g1]) { + return aliasData[g1]; + } + return g1; + }); }; this.getOriginalMetricName = function(labelData) { diff --git a/public/app/plugins/datasource/prometheus/metric_find_query.js b/public/app/plugins/datasource/prometheus/metric_find_query.js index d3d5376bc19..f449978be81 100644 --- a/public/app/plugins/datasource/prometheus/metric_find_query.js +++ b/public/app/plugins/datasource/prometheus/metric_find_query.js @@ -11,33 +11,27 @@ function (_) { } PrometheusMetricFindQuery.prototype.process = function() { - var labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]+)\)$/; - var metricNamesRegex = /^metrics\((.+)\)$/; - var labelsRegex = /^labels\((.+)\)$/; - var queryResultRegex = /^query_result\((.+)\)$/; + var label_values_regex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]+)\)$/; + var metric_names_regex = /^metrics\((.+)\)$/; + var query_result_regex = /^query_result\((.+)\)$/; - var labelsQuery = this.query.match(labelsRegex); - if (labelsQuery) { - return this.labelsQuery(labelsQuery[1]); - } - - var labelValuesQuery = this.query.match(labelValuesRegex); - if (labelValuesQuery) { - if (labelValuesQuery[1]) { - return this.labelValuesQuery(labelValuesQuery[2], labelValuesQuery[1]); + var label_values_query = this.query.match(label_values_regex); + if (label_values_query) { + if (label_values_query[1]) { + return this.labelValuesQuery(label_values_query[2], label_values_query[1]); } else { - return this.labelValuesQuery(labelValuesQuery[2], null); + return this.labelValuesQuery(label_values_query[2], null); } } - var metricNamesQuery = this.query.match(metricNamesRegex); - if (metricNamesQuery) { - return this.metricNameQuery(metricNamesQuery[1]); + var metric_names_query = this.query.match(metric_names_regex); + if (metric_names_query) { + return this.metricNameQuery(metric_names_query[1]); } - var queryResultQuery = this.query.match(queryResultRegex); - if (queryResultQuery) { - return this.queryResultQuery(queryResultQuery[1]); + var query_result_query = this.query.match(query_result_regex); + if (query_result_query) { + return this.queryResultQuery(query_result_query[1]); } // if query contains full metric name, return metric name and label list @@ -73,71 +67,45 @@ function (_) { } }; - PrometheusMetricFindQuery.prototype.labelsQuery = function(metric) { - var url; - - url = '/api/v1/series?match[]=' + encodeURIComponent(metric) - + '&start=' + (this.range.from.valueOf() / 1000) - + '&end=' + (this.range.to.valueOf() / 1000); - - return this.datasource._request('GET', url) - .then(function(result) { - var tags = {}; - _.each(result.data.data, function(metric) { - _.each(metric, function(value, key) { - if (key === "__name__") { - return; - } - - tags[key] = key; - }); - }); - - return _.map(tags, function(value) { - return {text: value, value: value}; - }); - }); - }; - PrometheusMetricFindQuery.prototype.metricNameQuery = function(metricFilterPattern) { var url = '/api/v1/label/__name__/values'; return this.datasource._request('GET', url) - .then(function(result) { - return _.chain(result.data.data) - .filter(function(metricName) { - var r = new RegExp(metricFilterPattern); - return r.test(metricName); - }) - .map(function(matchedMetricName) { - return { - text: matchedMetricName, - expandable: true - }; - }) - .value(); - }); + .then(function(result) { + return _.chain(result.data.data) + .filter(function(metricName) { + var r = new RegExp(metricFilterPattern); + return r.test(metricName); + }) + .map(function(matchedMetricName) { + return { + text: matchedMetricName, + expandable: true + }; + }) + .value(); + }); }; PrometheusMetricFindQuery.prototype.queryResultQuery = function(query) { var url = '/api/v1/query?query=' + encodeURIComponent(query) + '&time=' + (this.range.to.valueOf() / 1000); return this.datasource._request('GET', url) - .then(function(result) { - return _.map(result.data.data.result, function(metricData) { - var text = metricData.metric.__name__ || ''; - delete metricData.metric.__name__; - text += '{' + - _.map(metricData.metric, function(v, k) { return k + '="' + v + '"'; }).join(',') + - '}'; - text += ' ' + metricData.value[1] + ' ' + metricData.value[0] * 1000; + .then(function(result) { + return _.map(result.data.data.result, function(metricData) { + var text = metricData.metric.__name__ || ''; + delete metricData.metric.__name__; + text += '{' + + _.map(metricData.metric, function(v, k) { return k + '="' + v + '"'; }).join(',') + + '}'; + text += ' ' + metricData.value[1] + ' ' + metricData.value[0] * 1000; - return { - text: text, - expandable: true - }; - }); + return { + text: text, + expandable: true + }; }); + }); }; PrometheusMetricFindQuery.prototype.metricNameAndLabelsQuery = function(query) { @@ -147,14 +115,14 @@ function (_) { var self = this; return this.datasource._request('GET', url) - .then(function(result) { - return _.map(result.data.data, function(metric) { - return { - text: self.datasource.getOriginalMetricName(metric), - expandable: true - }; - }); + .then(function(result) { + return _.map(result.data.data, function(metric) { + return { + text: self.datasource.getOriginalMetricName(metric), + expandable: true + }; }); + }); }; return PrometheusMetricFindQuery; diff --git a/public/app/plugins/datasource/prometheus/partials/query.editor.html b/public/app/plugins/datasource/prometheus/partials/query.editor.html index 359c366cb0f..37c27ace58a 100644 --- a/public/app/plugins/datasource/prometheus/partials/query.editor.html +++ b/public/app/plugins/datasource/prometheus/partials/query.editor.html @@ -1,39 +1,18 @@ - - -
- -
- -
-
- - -
- -
- - -
- -
- -
- + +
-
+ + +
+
+ +
- + diff --git a/public/app/plugins/datasource/prometheus/prom_query.ts b/public/app/plugins/datasource/prometheus/prom_query.ts deleted file mode 100644 index d73a8b1cbcf..00000000000 --- a/public/app/plugins/datasource/prometheus/prom_query.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { - QueryPartDef, - QueryPart, - functionRenderer, - identityRenderer, - quotedIdentityRenderer, -} from 'app/core/components/query_part/query_part'; - -import _ from 'lodash'; - -var index = []; -var categories = { - Functions: [], - GroupBy: [], -}; - -export class PromQuery { - target: any; - metric: string; - range: string; - filters: any[]; - functions: any[]; - templateSrv: any; - scopedVars: any; - - constructor(target, templateSrv?, scopedVars?) { - this.target = target; - - this.target.expr = this.target.expr || ''; - this.target.intervalFactor = this.target.intervalFactor || 2; - this.target.functions = this.target.functions || []; - this.target.editorMode = this.target.editorMode || true; - - this.templateSrv = templateSrv; - this.scopedVars = scopedVars; - - this.updateProjection(); - } - - updateProjection() { - this.functions = _.map(this.target.functions, function(func: any) { - return createPart(func); - }); - } - - render() { - var query = this.target.metric; - if (this.target.range) { - query += '[' + this.target.range + ']'; - } - - for (let func of this.functions) { - query = func.render(query); - } - - return query; - } - - addQueryPart(category, item) { - var partModel = createPart({type: item.text}); - partModel.def.addStrategy(this, partModel); - } -} - -export function createPart(part): any { - var def = index[part.type]; - if (!def) { - throw {message: 'Could not find query part ' + part.type}; - } - - return new QueryPart(part, def); -} - -function register(options: any) { - index[options.type] = new QueryPartDef(options); - options.category.push(index[options.type]); -} - -function addFunctionStrategy(model, partModel) { - model.functions.push(partModel); - model.target.functions.push(partModel.part); -} - -function groupByLabelRenderer(part, innerExpr) { - return innerExpr + ' by(' + part.params.join(',') + ')'; -} - -register({ - type: 'rate', - addStrategy: addFunctionStrategy, - category: categories.Functions, - params: [], - defaultParams: [], - renderer: functionRenderer, -}); - -register({ - type: 'sum', - addStrategy: addFunctionStrategy, - category: categories.Functions, - params: [], - defaultParams: [], - renderer: functionRenderer, -}); - -register({ - type: 'by', - addStrategy: addFunctionStrategy, - category: categories.Functions, - params: [ - {name: "label", type: "string", dynamicLookup: true} - ], - defaultParams: [], - renderer: groupByLabelRenderer, -}); - -export function getQueryPartCategories() { - return categories; -} diff --git a/public/app/plugins/datasource/prometheus/query_ctrl.ts b/public/app/plugins/datasource/prometheus/query_ctrl.ts index 680b1294df6..92cec328d87 100644 --- a/public/app/plugins/datasource/prometheus/query_ctrl.ts +++ b/public/app/plugins/datasource/prometheus/query_ctrl.ts @@ -6,108 +6,46 @@ import moment from 'moment'; import * as dateMath from 'app/core/utils/datemath'; import {QueryCtrl} from 'app/plugins/sdk'; -import {PromQuery, getQueryPartCategories} from './prom_query'; class PrometheusQueryCtrl extends QueryCtrl { static templateUrl = 'partials/query.editor.html'; - query: any; - metricSegment: any; - addQueryPartMenu: any[]; + metric: any; resolutions: any; oldTarget: any; suggestMetrics: any; linkToPrometheus: any; /** @ngInject */ - constructor($scope, $injector, private templateSrv, private uiSegmentSrv, private $rootScope) { + constructor($scope, $injector, private templateSrv) { super($scope, $injector); - this.query = new PromQuery(this.target, templateSrv); - - if (this.target.metric) { - this.metricSegment = uiSegmentSrv.newSegment(this.target.metric); - } else { - this.metricSegment = uiSegmentSrv.newSegment({value: 'select metric', fake: true}); - } + var target = this.target; + target.expr = target.expr || ''; + target.intervalFactor = target.intervalFactor || 2; + this.metric = ''; this.resolutions = _.map([1,2,3,4,5,10], function(f) { return {factor: f, label: '1/' + f}; }); - this.updateLink(); - this.buildQueryPartMenu(); - } + $scope.$on('typeahead-updated', () => { + this.$scope.$apply(() => { - buildQueryPartMenu() { - var categories = getQueryPartCategories(); - this.addQueryPartMenu = _.reduce(categories, function(memo, cat, key) { - var menu = { - text: key, - submenu: cat.map(item => { - return {text: item.type, value: item.type}; - }), - }; - memo.push(menu); - return memo; - }, []); - } - - addQueryPart(item, subItem) { - this.query.addQueryPart(item, subItem); - this.panelCtrl.refresh(); - } - - getPartOptions(part) { - if (part.def.type === 'by') { - return this.datasource.metricFindQuery('labels(' + this.target.metric + ')') - .then(this.transformToSegments(true)) - .catch(this.handleQueryError.bind(true)); - } - } - - partUpdated(part) { - this.target.expr = this.query.render(); - this.panelCtrl.refresh(); - } - - handleQueryError(err) { - this.$rootScope.appEvent('alert-error', ['Query failed', err.message]); - } - - transformToSegments(addTemplateVars) { - return (results) => { - var segments = _.map(results, segment => { - return this.uiSegmentSrv.newSegment({ value: segment.text, expandable: segment.expandable }); - }); - - if (addTemplateVars) { - for (let variable of this.templateSrv.variables) { - segments.unshift(this.uiSegmentSrv.newSegment({ type: 'template', value: '/^$' + variable.name + '$/', expandable: true })); - } - } - - return segments; - }; - } - - getMetricOptions() { - return this.datasource.performSuggestQuery('').then(res => { - return _.map(res, metric => { - return this.uiSegmentSrv.newSegment(metric); + this.target.expr += this.target.metric; + this.metric = ''; + this.refreshMetricData(); }); }); - } - queryChanged() { - this.target.metric = this.metricSegment.value; - this.target.expr = this.query.render(); - this.refresh(); - } + // called from typeahead so need this + // here in order to ensure this ref + this.suggestMetrics = (query, callback) => { + console.log(this); + this.datasource.performSuggestQuery(query).then(callback); + }; - toggleEditorMode() { - this.target.expr = this.query.render(false); - this.target.editorMode = !this.target.editorMode; + this.updateLink(); } refreshMetricData() { @@ -120,6 +58,10 @@ class PrometheusQueryCtrl extends QueryCtrl { updateLink() { var range = this.panelCtrl.range; + if (!range) { + return; + } + var rangeDiff = Math.ceil((range.to.valueOf() - range.from.valueOf()) / 1000); var endTime = range.to.utc().format('YYYY-MM-DD HH:mm'); var expr = { diff --git a/public/app/plugins/datasource/prometheus/specs/metric_find_query_specs.ts b/public/app/plugins/datasource/prometheus/specs/metric_find_query_specs.ts index b393f36402c..38b50d2ce79 100644 --- a/public/app/plugins/datasource/prometheus/specs/metric_find_query_specs.ts +++ b/public/app/plugins/datasource/prometheus/specs/metric_find_query_specs.ts @@ -22,22 +22,18 @@ describe('PrometheusMetricFindQuery', function() { describe('When performing metricFindQuery', function() { var results; var response; - it('label_values(resource) should generate label search query', function() { response = { status: "success", data: ["value1", "value2", "value3"] }; - ctx.$httpBackend.expect('GET', 'proxied/api/v1/label/resource/values').respond(response); var pm = new PrometheusMetricFindQuery(ctx.ds, 'label_values(resource)', ctx.timeSrv); pm.process().then(function(data) { results = data; }); ctx.$httpBackend.flush(); ctx.$rootScope.$apply(); - expect(results.length).to.be(3); }); - it('label_values(metric, resource) should generate series query', function() { response = { status: "success", @@ -47,16 +43,13 @@ describe('PrometheusMetricFindQuery', function() { {__name__: "metric", resource: "value3"} ] }; - ctx.$httpBackend.expect('GET', /proxied\/api\/v1\/series\?match\[\]=metric&start=.*&end=.*/).respond(response); var pm = new PrometheusMetricFindQuery(ctx.ds, 'label_values(metric, resource)', ctx.timeSrv); pm.process().then(function(data) { results = data; }); ctx.$httpBackend.flush(); ctx.$rootScope.$apply(); - expect(results.length).to.be(3); }); - it('label_values(metric, resource) should pass correct time', function() { ctx.timeSrv.setTime({ from: moment.utc('2011-01-01'), to: moment.utc('2015-01-01') }); ctx.$httpBackend.expect('GET', @@ -66,7 +59,6 @@ describe('PrometheusMetricFindQuery', function() { ctx.$httpBackend.flush(); ctx.$rootScope.$apply(); }); - it('label_values(metric{label1="foo", label2="bar", label3="baz"}, resource) should generate series query', function() { response = { status: "success", @@ -76,7 +68,6 @@ describe('PrometheusMetricFindQuery', function() { {__name__: "metric", resource: "value3"} ] }; - ctx.$httpBackend.expect('GET', /proxied\/api\/v1\/series\?match\[\]=metric&start=.*&end=.*/).respond(response); var pm = new PrometheusMetricFindQuery(ctx.ds, 'label_values(metric, resource)', ctx.timeSrv); pm.process().then(function(data) { results = data; }); @@ -84,22 +75,18 @@ describe('PrometheusMetricFindQuery', function() { ctx.$rootScope.$apply(); expect(results.length).to.be(3); }); - it('metrics(metric.*) should generate metric name query', function() { response = { status: "success", data: ["metric1","metric2","metric3","nomatch"] }; - ctx.$httpBackend.expect('GET', 'proxied/api/v1/label/__name__/values').respond(response); var pm = new PrometheusMetricFindQuery(ctx.ds, 'metrics(metric.*)', ctx.timeSrv); pm.process().then(function(data) { results = data; }); ctx.$httpBackend.flush(); ctx.$rootScope.$apply(); - expect(results.length).to.be(3); }); - it('query_result(metric) should generate metric name query', function() { response = { status: "success", @@ -111,7 +98,6 @@ describe('PrometheusMetricFindQuery', function() { }] } }; - ctx.$httpBackend.expect('GET', /proxied\/api\/v1\/query\?query=metric&time=.*/).respond(response); var pm = new PrometheusMetricFindQuery(ctx.ds, 'query_result(metric)', ctx.timeSrv); pm.process().then(function(data) { results = data; }); @@ -120,28 +106,5 @@ describe('PrometheusMetricFindQuery', function() { expect(results.length).to.be(1); expect(results[0].text).to.be('metric{job="testjob"} 3846 1443454528000'); }); - - it('labels(metric) should generate series query', function() { - response = { - status: "success", - data: [ - {__name__: "metric", resource: "value1", app: "app1"}, - {__name__: "metric", resource: "value2", app: "app2"}, - {__name__: "metric", resource: "value3", server: "server1"} - ] - }; - - ctx.$httpBackend.expect('GET', /proxied\/api\/v1\/series\?match\[\]=metric&start=.*&end=.*/).respond(response); - var pm = new PrometheusMetricFindQuery(ctx.ds, 'labels(metric)', ctx.timeSrv); - pm.process().then(function(data) { results = data; }); - ctx.$httpBackend.flush(); - ctx.$rootScope.$apply(); - - expect(results.length).to.be(3); - expect(results[0].text).to.be('resource'); - expect(results[1].text).to.be('app'); - expect(results[2].text).to.be('server'); - }); - }); }); diff --git a/public/app/plugins/datasource/prometheus/specs/query_specs.ts b/public/app/plugins/datasource/prometheus/specs/query_specs.ts deleted file mode 100644 index d58e0834f89..00000000000 --- a/public/app/plugins/datasource/prometheus/specs/query_specs.ts +++ /dev/null @@ -1,38 +0,0 @@ -import {describe, beforeEach, it, sinon, expect} from 'test/lib/common'; - -import {PromQuery} from '../prom_query'; - -describe('PromQuery', function() { - var templateSrv = {replace: val => val}; - - describe('render series with mesurement only', function() { - it('should generate correct query', function() { - var query = new PromQuery({ - metric: 'cpu', - range: '5m', - functions: [ - {type: 'rate', params: []} - ] - }, templateSrv, {}); - - var queryText = query.render(); - expect(queryText).to.be('rate(cpu[5m])'); - }); - }); - - describe('render series with group by label', function() { - it('should generate correct query', function() { - var query = new PromQuery({ - metric: 'cpu', - functions: [ - {type: 'sum', params: []}, - {type: 'by', params: ['app']}, - ] - }, templateSrv, {}); - - var queryText = query.render(); - expect(queryText).to.be('sum(cpu) by(app)'); - }); - }); - -});