mirror of
https://github.com/grafana/grafana.git
synced 2024-12-28 18:01:40 -06:00
OpenTSDB: Alias patterns (reference tag values), syntax is: or [[tag_tagname]], Closes #1344, match opentsdb response to query, Fixes #1601
This commit is contained in:
parent
da833cbc58
commit
e31a3a64e1
@ -20,6 +20,7 @@
|
||||
- [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 #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**
|
||||
- [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, _) {
|
||||
});
|
||||
};
|
||||
|
||||
this.replace = function(target) {
|
||||
this.replace = function(target, scopedVars) {
|
||||
if (!target) { return; }
|
||||
|
||||
var value;
|
||||
this._regex.lastIndex = 0;
|
||||
|
||||
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];
|
||||
if (!value) { return match; }
|
||||
|
||||
@ -77,7 +82,7 @@ function (angular, _) {
|
||||
});
|
||||
};
|
||||
|
||||
this.replaceWithText = function(target) {
|
||||
this.replaceWithText = function(target, scopedVars) {
|
||||
if (!target) { return; }
|
||||
|
||||
var value;
|
||||
@ -85,6 +90,11 @@ function (angular, _) {
|
||||
this._regex.lastIndex = 0;
|
||||
|
||||
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];
|
||||
text = self._texts[g1 || g2];
|
||||
if (!value) { return match; }
|
||||
|
@ -46,13 +46,14 @@ function (angular, _, kbn) {
|
||||
});
|
||||
});
|
||||
|
||||
return this.performTimeSeriesQuery(queries, start, end)
|
||||
.then(_.bind(function(response) {
|
||||
var result = _.map(response.data, _.bind(function(metricData, index) {
|
||||
return transformMetricData(metricData, groupByTags, this.targets[index]);
|
||||
}, this));
|
||||
return { data: result };
|
||||
}, options));
|
||||
return this.performTimeSeriesQuery(queries, start, end).then(function(response) {
|
||||
var metricToTargetMapping = mapMetricsToTargets(response.data, options.targets);
|
||||
var result = _.map(response.data, function(metricData, index) {
|
||||
index = metricToTargetMapping[index];
|
||||
return transformMetricData(metricData, groupByTags, options.targets[index]);
|
||||
});
|
||||
return { data: result };
|
||||
});
|
||||
};
|
||||
|
||||
OpenTSDBDatasource.prototype.performTimeSeriesQuery = function(queries, start, end) {
|
||||
@ -90,19 +91,8 @@ function (angular, _, kbn) {
|
||||
};
|
||||
|
||||
function transformMetricData(md, groupByTags, options) {
|
||||
var dps = [],
|
||||
tagData = [],
|
||||
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);
|
||||
var metricLabel = createMetricLabel(md, options, groupByTags);
|
||||
var dps = [];
|
||||
|
||||
// TSDB returns datapoints has a hash of ts => value.
|
||||
// Can't use _.pairs(invert()) because it stringifies keys/values
|
||||
@ -113,16 +103,31 @@ function (angular, _, kbn) {
|
||||
return { target: metricLabel, datapoints: dps };
|
||||
}
|
||||
|
||||
function createMetricLabel(metric, tagData, options) {
|
||||
function createMetricLabel(md, options, groupByTags) {
|
||||
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)) {
|
||||
metric += "{" + tagData.join(", ") + "}";
|
||||
label += "{" + tagData.join(", ") + "}";
|
||||
}
|
||||
|
||||
return metric;
|
||||
return label;
|
||||
}
|
||||
|
||||
function convertTargetToQuery(target, interval) {
|
||||
@ -174,6 +179,15 @@ function (angular, _, kbn) {
|
||||
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) {
|
||||
if (date === 'now') {
|
||||
return null;
|
||||
|
@ -81,10 +81,11 @@
|
||||
|
||||
<li class="tight-form-item">
|
||||
Alias:
|
||||
<tip>Use patterns like $tag_tagname to replace part of the alias for a tag value</tip>
|
||||
</li>
|
||||
<li>
|
||||
<input type="text"
|
||||
class="tight-form-input input-medium"
|
||||
class="tight-form-input input-large"
|
||||
ng-model="target.alias"
|
||||
spellcheck='false'
|
||||
placeholder="series alias"
|
||||
|
@ -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() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]);
|
||||
|
Loading…
Reference in New Issue
Block a user