From 80a6e0d8d13804c51bc73338e5abb29c445d1b5f Mon Sep 17 00:00:00 2001 From: Dan Cech Date: Wed, 27 Dec 2017 15:32:15 -0500 Subject: [PATCH] support specifying tag_values("") as graphite template query --- .../features/templating/partials/editor.html | 8 +-- .../plugins/datasource/graphite/datasource.ts | 71 ++++++++++++++++--- 2 files changed, 67 insertions(+), 12 deletions(-) diff --git a/public/app/features/templating/partials/editor.html b/public/app/features/templating/partials/editor.html index 2fb80a6ac50..d904aeb4789 100644 --- a/public/app/features/templating/partials/editor.html +++ b/public/app/features/templating/partials/editor.html @@ -16,12 +16,12 @@ Add variable
-
What does variables do?
-

Variables enables more interactive and dynamic dashboards. Instead of hard-coding things like server or sensor names +

What do variables do?
+

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 the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard. - Checkout the + Check out the Templating documentation for more information. @@ -93,7 +93,7 @@

- Template names cannot begin with '__' that's reserved for Grafanas global variables + Template names cannot begin with '__', that's reserved for Grafana's global variables
diff --git a/public/app/plugins/datasource/graphite/datasource.ts b/public/app/plugins/datasource/graphite/datasource.ts index 8733a167da4..49b5be1dfbc 100644 --- a/public/app/plugins/datasource/graphite/datasource.ts +++ b/public/app/plugins/datasource/graphite/datasource.ts @@ -202,6 +202,35 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv let options = optionalOptions || {}; let interpolatedQuery = templateSrv.replace(query); + // special handling for tag_values([,]*), 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([,]*), 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 = { method: 'GET', url: '/metrics/find', @@ -212,7 +241,7 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv requestId: options.requestId, }; - if (options && options.range) { + if (options.range) { httpOptions.params.from = this.translateTime(options.range.from, false); httpOptions.params.until = this.translateTime(options.range.to, true); } @@ -237,7 +266,7 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv requestId: options.requestId, }; - if (options && options.range) { + if (options.range) { httpOptions.params.from = this.translateTime(options.range.from, false); httpOptions.params.until = this.translateTime(options.range.to, true); } @@ -262,7 +291,7 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv requestId: options.requestId, }; - if (options && options.range) { + if (options.range) { httpOptions.params.from = this.translateTime(options.range.from, false); 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 = { method: 'GET', url: '/tags/autoComplete/tags', params: { - expr: expression, + expr: expressions, }, + // for cancellations + requestId: options.requestId, }; if (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 => { 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 = { method: 'GET', url: '/tags/autoComplete/values', params: { - expr: expression, + expr: expressions, tag: tag, }, + // for cancellations + requestId: options.requestId, }; if (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 => { 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 = { method: 'GET', url: '/version/_', // Prevent last / trimming + // for cancellations + requestId: options.requestId, }; return this.doGraphiteRequest(httpOptions)