mirror of https://github.com/grafana/grafana
parent
dea2234b14
commit
2cce057df1
@ -0,0 +1,2 @@ |
||||
declare var test: any; |
||||
export default test; |
@ -0,0 +1,125 @@ |
||||
define([ |
||||
'lodash', |
||||
'moment', |
||||
], |
||||
function (_, moment) { |
||||
'use strict'; |
||||
|
||||
function PrometheusMetricFindQuery(datasource, query) { |
||||
this.datasource = datasource; |
||||
this.query = query; |
||||
} |
||||
|
||||
PrometheusMetricFindQuery.prototype.process = function() { |
||||
var label_values_regex = /^label_values\(([^,]+)(?:,\s*(.+))?\)$/; |
||||
var metric_names_regex = /^metrics\((.+)\)$/; |
||||
var query_result_regex = /^query_result\((.+)\)$/; |
||||
|
||||
var label_values_query = this.query.match(label_values_regex); |
||||
if (label_values_query) { |
||||
if (label_values_query[2]) { |
||||
return this.labelValuesQuery(label_values_query[2], label_values_query[1]); |
||||
} else { |
||||
return this.labelValuesQuery(label_values_query[1], null); |
||||
} |
||||
} |
||||
|
||||
var metric_names_query = this.query.match(metric_names_regex); |
||||
if (metric_names_query) { |
||||
return this.metricNameQuery(metric_names_query[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
|
||||
return this.metricNameAndLabelsQuery(this.query); |
||||
}; |
||||
|
||||
PrometheusMetricFindQuery.prototype.labelValuesQuery = function(label, metric) { |
||||
var url; |
||||
|
||||
if (!metric) { |
||||
// return label values globally
|
||||
url = '/api/v1/label/' + label + '/values'; |
||||
|
||||
return this.datasource._request('GET', url).then(function(result) { |
||||
return _.map(result.data.data, function(value) { |
||||
return {text: value}; |
||||
}); |
||||
}); |
||||
} else { |
||||
url = '/api/v1/series?match[]=' + encodeURIComponent(metric); |
||||
|
||||
return this.datasource._request('GET', url) |
||||
.then(function(result) { |
||||
return _.map(result.data.data, function(metric) { |
||||
return { |
||||
text: metric[label], |
||||
expandable: true |
||||
}; |
||||
}); |
||||
}); |
||||
} |
||||
}; |
||||
|
||||
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(); |
||||
}); |
||||
}; |
||||
|
||||
PrometheusMetricFindQuery.prototype.queryResultQuery = function(query) { |
||||
var url = '/api/v1/query?query=' + encodeURIComponent(query) + '&time=' + (moment().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; |
||||
|
||||
return { |
||||
text: text, |
||||
expandable: true |
||||
}; |
||||
}); |
||||
}); |
||||
}; |
||||
|
||||
PrometheusMetricFindQuery.prototype.metricNameAndLabelsQuery = function(query) { |
||||
var url = '/api/v1/series?match[]=' + encodeURIComponent(query); |
||||
|
||||
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 |
||||
}; |
||||
}); |
||||
}); |
||||
}; |
||||
|
||||
return PrometheusMetricFindQuery; |
||||
}); |
@ -0,0 +1,83 @@ |
||||
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common'; |
||||
import moment from 'moment'; |
||||
import helpers from 'test/specs/helpers'; |
||||
import {PrometheusDatasource} from '../datasource'; |
||||
import PrometheusMetricFindQuery from '../metric_find_query'; |
||||
|
||||
describe('PrometheusMetricFindQuery', function() { |
||||
|
||||
var ctx = new helpers.ServiceTestContext(); |
||||
var instanceSettings = {url: 'proxied', directUrl: 'direct', user: 'test', password: 'mupp' }; |
||||
beforeEach(angularMocks.module('grafana.core')); |
||||
beforeEach(angularMocks.module('grafana.services')); |
||||
beforeEach(angularMocks.inject(function($q, $rootScope, $httpBackend, $injector) { |
||||
ctx.$q = $q; |
||||
ctx.$httpBackend = $httpBackend; |
||||
ctx.$rootScope = $rootScope; |
||||
ctx.ds = $injector.instantiate(PrometheusDatasource, {instanceSettings: instanceSettings}); |
||||
})); |
||||
|
||||
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)'); |
||||
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", |
||||
data: [ |
||||
{__name__: "metric", resource: "value1"}, |
||||
{__name__: "metric", resource: "value2"}, |
||||
{__name__: "metric", resource: "value3"} |
||||
] |
||||
}; |
||||
ctx.$httpBackend.expect('GET', 'proxied/api/v1/series?match[]=metric').respond(response); |
||||
var pm = new PrometheusMetricFindQuery(ctx.ds, 'label_values(metric, resource)'); |
||||
pm.process().then(function(data) { results = data; }); |
||||
ctx.$httpBackend.flush(); |
||||
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.*)'); |
||||
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", |
||||
data: { |
||||
resultType: "vector", |
||||
result: [{ |
||||
metric: {"__name__": "metric", job: "testjob"}, |
||||
value: [1443454528.000, "3846"] |
||||
}] |
||||
} |
||||
}; |
||||
ctx.$httpBackend.expect('GET', /proxied\/api\/v1\/query\?query=metric&time=.*/).respond(response); |
||||
var pm = new PrometheusMetricFindQuery(ctx.ds, 'query_result(metric)'); |
||||
pm.process().then(function(data) { results = data; }); |
||||
ctx.$httpBackend.flush(); |
||||
ctx.$rootScope.$apply(); |
||||
expect(results.length).to.be(1); |
||||
expect(results[0].text).to.be('metric{job="testjob"} 3846 1443454528000'); |
||||
}); |
||||
}); |
||||
}); |
Loading…
Reference in new issue