support specifying tag_values("<tag>") as graphite template query

This commit is contained in:
Dan Cech
2017-12-27 15:32:15 -05:00
parent 7c1be021ac
commit 80a6e0d8d1
2 changed files with 67 additions and 12 deletions

View File

@@ -16,12 +16,12 @@
Add variable Add variable
</a> </a>
<div class="grafana-info-box"> <div class="grafana-info-box">
<h5>What does variables do?</h5> <h5>What do variables do?</h5>
<p>Variables enables more interactive and dynamic dashboards. Instead of hard-coding things like server or sensor names <p>Variables enable more interactive and dynamic dashboards. Instead of hard-coding things like server or sensor names
in your metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of in your metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of
the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard. the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard.
Checkout the Check out the
<a class="external-link" href="http://docs.grafana.org/reference/templating/" target="_blank"> <a class="external-link" href="http://docs.grafana.org/reference/templating/" target="_blank">
Templating documentation Templating documentation
</a> for more information. </a> for more information.
@@ -93,7 +93,7 @@
</div> </div>
<div class="gf-form" ng-show="ctrl.form.name.$error.pattern"> <div class="gf-form" ng-show="ctrl.form.name.$error.pattern">
<span class="gf-form-label gf-form-label--error">Template names cannot begin with '__' that's reserved for Grafanas global variables</span> <span class="gf-form-label gf-form-label--error">Template names cannot begin with '__', that's reserved for Grafana's global variables</span>
</div> </div>
<div class="gf-form-inline"> <div class="gf-form-inline">

View File

@@ -202,6 +202,35 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
let options = optionalOptions || {}; let options = optionalOptions || {};
let interpolatedQuery = templateSrv.replace(query); let interpolatedQuery = templateSrv.replace(query);
// special handling for tag_values(<tag>[,<expression>]*), this is used for template variables
let matches = interpolatedQuery.match(/^tag_values\(([^,]+)((, *[^,]+)*)\)$/);
if (matches) {
const expressions = [];
const exprRegex = /, *([^,]+)/g;
let match;
while ((match = exprRegex.exec(matches[2])) !== null) {
expressions.push(match[1]);
}
options.limit = 10000;
return this.getTagValuesAutoComplete(expressions, matches[1], undefined, options);
}
// special handling for tags(<expression>[,<expression>]*), this is used for template variables
matches = interpolatedQuery.match(/^tags\(([^,]*)((, *[^,]+)*)\)$/);
if (matches) {
const expressions = [];
if (matches[1]) {
expressions.push(matches[1]);
const exprRegex = /, *([^,]+)/g;
let match;
while ((match = exprRegex.exec(matches[2])) !== null) {
expressions.push(match[1]);
}
}
options.limit = 10000;
return this.getTagsAutoComplete(expressions, undefined, options);
}
let httpOptions: any = { let httpOptions: any = {
method: 'GET', method: 'GET',
url: '/metrics/find', url: '/metrics/find',
@@ -212,7 +241,7 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
requestId: options.requestId, requestId: options.requestId,
}; };
if (options && options.range) { if (options.range) {
httpOptions.params.from = this.translateTime(options.range.from, false); httpOptions.params.from = this.translateTime(options.range.from, false);
httpOptions.params.until = this.translateTime(options.range.to, true); httpOptions.params.until = this.translateTime(options.range.to, true);
} }
@@ -237,7 +266,7 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
requestId: options.requestId, requestId: options.requestId,
}; };
if (options && options.range) { if (options.range) {
httpOptions.params.from = this.translateTime(options.range.from, false); httpOptions.params.from = this.translateTime(options.range.from, false);
httpOptions.params.until = this.translateTime(options.range.to, true); httpOptions.params.until = this.translateTime(options.range.to, true);
} }
@@ -262,7 +291,7 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
requestId: options.requestId, requestId: options.requestId,
}; };
if (options && options.range) { if (options.range) {
httpOptions.params.from = this.translateTime(options.range.from, false); httpOptions.params.from = this.translateTime(options.range.from, false);
httpOptions.params.until = this.translateTime(options.range.to, true); httpOptions.params.until = this.translateTime(options.range.to, true);
} }
@@ -281,18 +310,29 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
}); });
}; };
this.getTagsAutoComplete = (expression, tagPrefix) => { this.getTagsAutoComplete = (expressions, tagPrefix, optionalOptions) => {
let options = optionalOptions || {};
let httpOptions: any = { let httpOptions: any = {
method: 'GET', method: 'GET',
url: '/tags/autoComplete/tags', url: '/tags/autoComplete/tags',
params: { params: {
expr: expression, expr: expressions,
}, },
// for cancellations
requestId: options.requestId,
}; };
if (tagPrefix) { if (tagPrefix) {
httpOptions.params.tagPrefix = tagPrefix; httpOptions.params.tagPrefix = tagPrefix;
} }
if (options.limit) {
httpOptions.params.limit = options.limit;
}
if (options.range) {
httpOptions.params.from = this.translateTime(options.range.from, false);
httpOptions.params.until = this.translateTime(options.range.to, true);
}
return this.doGraphiteRequest(httpOptions).then(results => { return this.doGraphiteRequest(httpOptions).then(results => {
if (results.data) { if (results.data) {
@@ -305,19 +345,30 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
}); });
}; };
this.getTagValuesAutoComplete = (expression, tag, valuePrefix) => { this.getTagValuesAutoComplete = (expressions, tag, valuePrefix, limit, optionalOptions) => {
let options = optionalOptions || {};
let httpOptions: any = { let httpOptions: any = {
method: 'GET', method: 'GET',
url: '/tags/autoComplete/values', url: '/tags/autoComplete/values',
params: { params: {
expr: expression, expr: expressions,
tag: tag, tag: tag,
}, },
// for cancellations
requestId: options.requestId,
}; };
if (valuePrefix) { if (valuePrefix) {
httpOptions.params.valuePrefix = valuePrefix; httpOptions.params.valuePrefix = valuePrefix;
} }
if (options.limit) {
httpOptions.params.limit = options.limit;
}
if (options.range) {
httpOptions.params.from = this.translateTime(options.range.from, false);
httpOptions.params.until = this.translateTime(options.range.to, true);
}
return this.doGraphiteRequest(httpOptions).then(results => { return this.doGraphiteRequest(httpOptions).then(results => {
if (results.data) { if (results.data) {
@@ -330,10 +381,14 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
}); });
}; };
this.getVersion = function() { this.getVersion = function(optionalOptions) {
let options = optionalOptions || {};
let httpOptions = { let httpOptions = {
method: 'GET', method: 'GET',
url: '/version/_', // Prevent last / trimming url: '/version/_', // Prevent last / trimming
// for cancellations
requestId: options.requestId,
}; };
return this.doGraphiteRequest(httpOptions) return this.doGraphiteRequest(httpOptions)