Commit e31a3a64 by Torkel Ödegaard

OpenTSDB: Alias patterns (reference tag values), syntax is: or [[tag_tagname]],…

OpenTSDB: Alias patterns (reference tag values), syntax is:  or [[tag_tagname]], Closes #1344, match opentsdb response to query, Fixes #1601
parent da833cbc
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
- [Issue #599](https://github.com/grafana/grafana/issues/599). Graph: Added right y axis label setting and graph support - [Issue #599](https://github.com/grafana/grafana/issues/599). Graph: Added right y axis label setting and graph support
- [Issue #1253](https://github.com/grafana/grafana/issues/1253). Graph & Singlestat: Users can now set decimal precision for legend and tooltips (override auto precision) - [Issue #1253](https://github.com/grafana/grafana/issues/1253). Graph & Singlestat: Users can now set decimal precision for legend and tooltips (override auto precision)
- [Issue #1255](https://github.com/grafana/grafana/issues/1255). Templating: Dashboard will now wait to load until all template variables that have refresh on load set or are initialized via url to be fully loaded and so all variables are in valid state before panels start issuing metric requests. - [Issue #1255](https://github.com/grafana/grafana/issues/1255). Templating: Dashboard will now wait to load until all template variables that have refresh on load set or are initialized via url to be fully loaded and so all variables are in valid state before panels start issuing metric requests.
- [Issue #1344](https://github.com/grafana/grafana/issues/1344). OpenTSDB: Alias patterns (reference tag values), syntax is: $tag_tagname or [[tag_tagname]]
**Fixes** **Fixes**
- [Issue #1298](https://github.com/grafana/grafana/issues/1298). InfluxDB: Fix handling of empty array in templating variable query - [Issue #1298](https://github.com/grafana/grafana/issues/1298). InfluxDB: Fix handling of empty array in templating variable query
......
...@@ -63,13 +63,18 @@ function (angular, _) { ...@@ -63,13 +63,18 @@ function (angular, _) {
}); });
}; };
this.replace = function(target) { this.replace = function(target, scopedVars) {
if (!target) { return; } if (!target) { return; }
var value; var value;
this._regex.lastIndex = 0; this._regex.lastIndex = 0;
return target.replace(this._regex, function(match, g1, g2) { return target.replace(this._regex, function(match, g1, g2) {
if (scopedVars) {
value = scopedVars[g1 || g2];
if (value) { return value.value; }
}
value = self._values[g1 || g2]; value = self._values[g1 || g2];
if (!value) { return match; } if (!value) { return match; }
...@@ -77,7 +82,7 @@ function (angular, _) { ...@@ -77,7 +82,7 @@ function (angular, _) {
}); });
}; };
this.replaceWithText = function(target) { this.replaceWithText = function(target, scopedVars) {
if (!target) { return; } if (!target) { return; }
var value; var value;
...@@ -85,6 +90,11 @@ function (angular, _) { ...@@ -85,6 +90,11 @@ function (angular, _) {
this._regex.lastIndex = 0; this._regex.lastIndex = 0;
return target.replace(this._regex, function(match, g1, g2) { return target.replace(this._regex, function(match, g1, g2) {
if (scopedVars) {
var option = scopedVars[g1 || g2];
if (option) { return option.text; }
}
value = self._values[g1 || g2]; value = self._values[g1 || g2];
text = self._texts[g1 || g2]; text = self._texts[g1 || g2];
if (!value) { return match; } if (!value) { return match; }
......
...@@ -46,13 +46,14 @@ function (angular, _, kbn) { ...@@ -46,13 +46,14 @@ function (angular, _, kbn) {
}); });
}); });
return this.performTimeSeriesQuery(queries, start, end) return this.performTimeSeriesQuery(queries, start, end).then(function(response) {
.then(_.bind(function(response) { var metricToTargetMapping = mapMetricsToTargets(response.data, options.targets);
var result = _.map(response.data, _.bind(function(metricData, index) { var result = _.map(response.data, function(metricData, index) {
return transformMetricData(metricData, groupByTags, this.targets[index]); index = metricToTargetMapping[index];
}, this)); return transformMetricData(metricData, groupByTags, options.targets[index]);
return { data: result }; });
}, options)); return { data: result };
});
}; };
OpenTSDBDatasource.prototype.performTimeSeriesQuery = function(queries, start, end) { OpenTSDBDatasource.prototype.performTimeSeriesQuery = function(queries, start, end) {
...@@ -90,19 +91,8 @@ function (angular, _, kbn) { ...@@ -90,19 +91,8 @@ function (angular, _, kbn) {
}; };
function transformMetricData(md, groupByTags, options) { function transformMetricData(md, groupByTags, options) {
var dps = [], var metricLabel = createMetricLabel(md, options, groupByTags);
tagData = [], var dps = [];
metricLabel = null;
if (!_.isEmpty(md.tags)) {
_.each(_.pairs(md.tags), function(tag) {
if (_.has(groupByTags, tag[0])) {
tagData.push(tag[0] + "=" + tag[1]);
}
});
}
metricLabel = createMetricLabel(md.metric, tagData, options);
// TSDB returns datapoints has a hash of ts => value. // TSDB returns datapoints has a hash of ts => value.
// Can't use _.pairs(invert()) because it stringifies keys/values // Can't use _.pairs(invert()) because it stringifies keys/values
...@@ -113,16 +103,31 @@ function (angular, _, kbn) { ...@@ -113,16 +103,31 @@ function (angular, _, kbn) {
return { target: metricLabel, datapoints: dps }; return { target: metricLabel, datapoints: dps };
} }
function createMetricLabel(metric, tagData, options) { function createMetricLabel(md, options, groupByTags) {
if (!_.isUndefined(options) && options.alias) { if (!_.isUndefined(options) && options.alias) {
return options.alias; var scopedVars = {};
_.each(md.tags, function(value, key) {
scopedVars['tag_' + key] = {value: value};
});
return templateSrv.replace(options.alias, scopedVars);
}
var label = md.metric;
var tagData = [];
if (!_.isEmpty(md.tags)) {
_.each(_.pairs(md.tags), function(tag) {
if (_.has(groupByTags, tag[0])) {
tagData.push(tag[0] + "=" + tag[1]);
}
});
} }
if (!_.isEmpty(tagData)) { if (!_.isEmpty(tagData)) {
metric += "{" + tagData.join(", ") + "}"; label += "{" + tagData.join(", ") + "}";
} }
return metric; return label;
} }
function convertTargetToQuery(target, interval) { function convertTargetToQuery(target, interval) {
...@@ -174,6 +179,15 @@ function (angular, _, kbn) { ...@@ -174,6 +179,15 @@ function (angular, _, kbn) {
return query; return query;
} }
function mapMetricsToTargets(metrics, targets) {
return _.map(metrics, function(metricData) {
return _.findIndex(targets, function(target) {
return target.metric === metricData.metric &&
_.all(target.tags, function(tagV, tagK) { return metricData.tags[tagK] !== void 0; });
});
});
}
function convertToTSDBTime(date) { function convertToTSDBTime(date) {
if (date === 'now') { if (date === 'now') {
return null; return null;
......
...@@ -81,10 +81,11 @@ ...@@ -81,10 +81,11 @@
<li class="tight-form-item"> <li class="tight-form-item">
Alias: Alias:
<tip>Use patterns like $tag_tagname to replace part of the alias for a tag value</tip>
</li> </li>
<li> <li>
<input type="text" <input type="text"
class="tight-form-input input-medium" class="tight-form-input input-large"
ng-model="target.alias" ng-model="target.alias"
spellcheck='false' spellcheck='false'
placeholder="series alias" placeholder="series alias"
......
...@@ -29,6 +29,22 @@ define([ ...@@ -29,6 +29,22 @@ define([
}); });
}); });
describe('replace can pass scoped vars', function() {
beforeEach(function() {
_templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]);
});
it('should replace $test with scoped value', function() {
var target = _templateSrv.replace('this.$test.filters', {'test': {value: 'mupp', text: 'asd'}});
expect(target).to.be('this.mupp.filters');
});
it('should replace $test with scoped text', function() {
var target = _templateSrv.replaceWithText('this.$test.filters', {'test': {value: 'mupp', text: 'asd'}});
expect(target).to.be('this.asd.filters');
});
});
describe('can check if variable exists', function() { describe('can check if variable exists', function() {
beforeEach(function() { beforeEach(function() {
_templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]); _templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment