diff --git a/CHANGELOG.md b/CHANGELOG.md index eb1cb5c55ab..1ad8f717d8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * **Scripts**: Use restart instead of start for deb package script, closes [#5282](https://github.com/grafana/grafana/pull/5282) * **Logging**: Moved to structured logging lib, and moved to component specific level filters via config file, closes [#4590](https://github.com/grafana/grafana/issues/4590) * **Search**: Add search limit query parameter, closes [#5292](https://github.com/grafana/grafana/pull/5292) +* **OpenTSDB**: Support nested template variables in tag_values function, closes [4398](https://github.com/grafana/grafana/issues/4398) ## Breaking changes * **Logging** : Changed default logging output format (now structured into message, and key value pairs, with logger key acting as component). You can also no change in config to json log ouput. diff --git a/docs/sources/datasources/opentsdb.md b/docs/sources/datasources/opentsdb.md index 6ef930c0cc0..9294b6b68ee 100644 --- a/docs/sources/datasources/opentsdb.md +++ b/docs/sources/datasources/opentsdb.md @@ -51,6 +51,13 @@ When using OpenTSDB with a template variable of `query` type you can use followi If you do not see template variables being populated in `Preview of values` section, you need to enable `tsd.core.meta.enable_realtime_ts` in the OpenTSDB server settings. Also, to populate metadata of the existing time series data in OpenTSDB, you need to run `tsdb uid metasync` on the OpenTSDB server. +### Nested Templating + +One template variable can be used to filter tag values for another template varible. Very importantly, the order of the parameters matter in tag_values function. First parameter is the metric name, second parameter is the tag key for which you need to find tag values, and after that all other dependent template variables. Some examples are mentioned below to make nested template queries work successfully. + + tag_values(cpu, hostname, env=$env) // return tag values for cpu metric, selected env tag value and tag key hostname + tag_values(cpu, hostanme, env=$env, region=$region) // return tag values for cpu metric, selected env tag value, selected region tag value and tag key hostname + > Note: This is required for the OpenTSDB `lookup` api to work. For details on opentsdb metric queries checkout the official [OpenTSDB documentation](http://opentsdb.net/docs/build/html/index.html) diff --git a/public/app/plugins/datasource/opentsdb/datasource.js b/public/app/plugins/datasource/opentsdb/datasource.js index 1d3db75658c..e80c811a2a6 100644 --- a/public/app/plugins/datasource/opentsdb/datasource.js +++ b/public/app/plugins/datasource/opentsdb/datasource.js @@ -162,12 +162,23 @@ function (angular, _, dateMath) { }); }; - this._performMetricKeyValueLookup = function(metric, key) { - if(!metric || !key) { + this._performMetricKeyValueLookup = function(metric, keys) { + + if(!metric || !keys) { return $q.when([]); } - var m = metric + "{" + key + "=*}"; + var keysArray = keys.split(",").map(function(key) { + return key.trim(); + }); + var key = keysArray[0]; + var keysQuery = key + "=*"; + + if (keysArray.length > 1) { + keysQuery += "," + keysArray.splice(1).join(","); + } + + var m = metric + "{" + keysQuery + "}"; return this._get('/api/search/lookup', {m: m, limit: 3000}).then(function(result) { result = result.data.results; @@ -225,7 +236,7 @@ function (angular, _, dateMath) { var metrics_regex = /metrics\((.*)\)/; var tag_names_regex = /tag_names\((.*)\)/; - var tag_values_regex = /tag_values\((.*),\s?(.*)\)/; + var tag_values_regex = /tag_values\((.*?),\s?(.*)\)/; var tag_names_suggest_regex = /suggest_tagk\((.*)\)/; var tag_values_suggest_regex = /suggest_tagv\((.*)\)/; diff --git a/public/app/plugins/datasource/opentsdb/specs/datasource-specs.ts b/public/app/plugins/datasource/opentsdb/specs/datasource-specs.ts index a1dc9baada9..1f63dc88667 100644 --- a/public/app/plugins/datasource/opentsdb/specs/datasource-specs.ts +++ b/public/app/plugins/datasource/opentsdb/specs/datasource-specs.ts @@ -51,6 +51,20 @@ describe('opentsdb', function() { expect(requestOptions.params.m).to.be('cpu{hostname=*}'); }); + it('tag_values(cpu, test) should generate lookup query', function() { + ctx.ds.metricFindQuery('tag_values(cpu, hostname, env=$env)').then(function(data) { results = data; }); + ctx.$rootScope.$apply(); + expect(requestOptions.url).to.be('/api/search/lookup'); + expect(requestOptions.params.m).to.be('cpu{hostname=*,env=$env}'); + }); + + it('tag_values(cpu, test) should generate lookup query', function() { + ctx.ds.metricFindQuery('tag_values(cpu, hostname, env=$env, region=$region)').then(function(data) { results = data; }); + ctx.$rootScope.$apply(); + expect(requestOptions.url).to.be('/api/search/lookup'); + expect(requestOptions.params.m).to.be('cpu{hostname=*,env=$env,region=$region}'); + }); + it('suggest_tagk() should generate api suggest query', function() { ctx.ds.metricFindQuery('suggest_tagk(foo)').then(function(data) { results = data; }); ctx.$rootScope.$apply();