From c762ad8db2185983f2c6d2c362abbb3f3284827d Mon Sep 17 00:00:00 2001 From: Masaori Koshiba Date: Mon, 20 Apr 2015 00:49:16 +0900 Subject: [PATCH] Refactoring KairosDB Plugin --- .../plugins/datasource/kairosdb/datasource.js | 169 ++++++++---------- .../plugins/datasource/kairosdb/queryCtrl.js | 11 +- 2 files changed, 87 insertions(+), 93 deletions(-) diff --git a/public/app/plugins/datasource/kairosdb/datasource.js b/public/app/plugins/datasource/kairosdb/datasource.js index da3f8ca665f..9d25b694891 100644 --- a/public/app/plugins/datasource/kairosdb/datasource.js +++ b/public/app/plugins/datasource/kairosdb/datasource.js @@ -32,18 +32,24 @@ function (angular, _, kbn) { if (typeof target.alias === 'undefined' || target.alias === "") { alias = target.metric; } - return !target.hide - ? {alias: alias, - exouter: target.exOuter} - : null; + + if (!target.hide) { + return { alias: alias, exouter: target.exOuter }; + } + else { + return null; + } })); + var handleKairosDBQueryResponseAlias = _.partial(handleKairosDBQueryResponse, plotParams); + // No valid targets, return the empty result to save a round trip. if (_.isEmpty(queries)) { var d = $q.defer(); d.resolve({ data: [] }); return d.promise; } + return this.performTimeSeriesQuery(queries, start, end).then(handleKairosDBQueryResponseAlias, handleQueryError); }; @@ -53,18 +59,19 @@ function (angular, _, kbn) { KairosDBDatasource.prototype.performTimeSeriesQuery = function(queries, start, end) { var reqBody = { - metrics: queries + metrics: queries, + cache_time: 0 }; - reqBody.cache_time = 0; + convertToKairosTime(start, reqBody, 'start'); convertToKairosTime(end, reqBody, 'end'); + var options = { method: 'POST', - url: '/api/v1/datapoints/query', + url: this.url + '/api/v1/datapoints/query', data: reqBody }; - options.url = this.url + options.url; return $http(options); }; @@ -77,39 +84,41 @@ function (angular, _, kbn) { url : this.url + '/api/v1/metricnames', method : 'GET' }; + return $http(options).then(function(results) { if (!results.data) { return []; } return results.data.results; }); - }; KairosDBDatasource.prototype.performTagSuggestQuery = function(metricname, range, type, keyValue) { if (tagList && (metricname === tagList.metricName) && (range.from === tagList.range.from) && - (range.to === tagList.range.to)) { + (range.to === tagList.range.to)) { return getTagListFromResponse(tagList.results, type, keyValue); } tagList = { - metricName:metricname, - range:range + metricName: metricname, + range: range }; var body = { metrics : [{name : metricname}] }; + convertToKairosTime(range.from, body, 'start'); convertToKairosTime(range.to, body, 'end'); + var options = { url : this.url + '/api/v1/datapoints/query/tags', method : 'POST', data : body }; + return $http(options).then(function(results) { tagList.results = results; return getTagListFromResponse(results, type, keyValue); }); - }; ///////////////////////////////////////////////////////////////////////// @@ -120,13 +129,15 @@ function (angular, _, kbn) { if (!results.data) { return []; } - if (type === "key") { + else if (type === "key") { return _.keys(results.data.queries[0].results[0].tags); } else if (type === "value" && _.has(results.data.queries[0].results[0].tags, keyValue)) { return results.data.queries[0].results[0].tags[keyValue]; } - return []; + else { + return []; + } } /** @@ -151,10 +162,9 @@ function (angular, _, kbn) { var index = 0; _.each(results.data.queries, function(series) { _.each(series.results, function(result) { - - //var target = result.name; var target = plotParams[index].alias; var details = " ( "; + _.each(result.group_by, function(element) { if (element.name === "tag") { _.each(element.group, function(value, key) { @@ -168,10 +178,13 @@ function (angular, _, kbn) { details += 'time_group=' + element.group.group_number + " "; } }); + details += ") "; + if (details !== " ( ) ") { target += details; } + var datapoints = []; for (var i = 0; i < result.values.length; i++) { @@ -184,11 +197,11 @@ function (angular, _, kbn) { } output.push({ target: target, datapoints: datapoints }); }); - index ++; + + index++; }); - var output2 = { data: _.flatten(output) }; - return output2; + return { data: _.flatten(output) }; } function convertTargetToQuery(options, target) { @@ -201,6 +214,7 @@ function (angular, _, kbn) { }; query.aggregators = []; + if (target.downsampling !== '(NONE)') { query.aggregators.push({ name: target.downsampling, @@ -209,31 +223,37 @@ function (angular, _, kbn) { sampling: KairosDBDatasource.prototype.convertToKairosInterval(target.sampling || options.interval) }); } + if (target.horizontalAggregators) { _.each(target.horizontalAggregators, function(chosenAggregator) { var returnedAggregator = { name:chosenAggregator.name }; + if (chosenAggregator.sampling_rate) { returnedAggregator.sampling = KairosDBDatasource.prototype.convertToKairosInterval(chosenAggregator.sampling_rate); returnedAggregator.align_sampling = true; returnedAggregator.align_start_time =true; } + if (chosenAggregator.unit) { returnedAggregator.unit = chosenAggregator.unit + 's'; } + if (chosenAggregator.factor && chosenAggregator.name === 'div') { returnedAggregator.divisor = chosenAggregator.factor; } else if (chosenAggregator.factor && chosenAggregator.name === 'scale') { returnedAggregator.factor = chosenAggregator.factor; } + if (chosenAggregator.percentile) { returnedAggregator.percentile = chosenAggregator.percentile; } query.aggregators.push(returnedAggregator); }); } + if (_.isEmpty(query.aggregators)) { delete query.aggregators; } @@ -244,7 +264,9 @@ function (angular, _, kbn) { if (target.groupByTags || target.nonTagGroupBys) { query.group_by = []; - if (target.groupByTags) {query.group_by.push({name: "tag", tags: angular.copy(target.groupByTags)});} + if (target.groupByTags) { + query.group_by.push({name: "tag", tags: angular.copy(target.groupByTags)}); + } if (target.nonTagGroupBys) { _.each(target.nonTagGroupBys, function(rawGroupBy) { var formattedGroupBy = angular.copy(rawGroupBy); @@ -276,102 +298,46 @@ function (angular, _, kbn) { var value = matches[1]; var unit = matches[2]; if (value%1 !== 0) { - if (unit === 'ms') {throw new Error('Invalid interval value, cannot be smaller than the millisecond');} + if (unit === 'ms') { + throw new Error('Invalid interval value, cannot be smaller than the millisecond'); + } value = Math.round(kbn.intervals_in_seconds[unit] * value * 1000); unit = 'ms'; - - } - switch (unit) { - case 'ms': - unit = 'milliseconds'; - break; - case 's': - unit = 'seconds'; - break; - case 'm': - unit = 'minutes'; - break; - case 'h': - unit = 'hours'; - break; - case 'd': - unit = 'days'; - break; - case 'w': - unit = 'weeks'; - break; - case 'M': - unit = 'months'; - break; - case 'y': - unit = 'years'; - break; - default: - console.log("Unknown interval ", intervalString); - break; } return { - "value": value, - "unit": unit + value: value, + unit: convertToKairosDBTimeUnit(unit) }; - }; function convertToKairosTime(date, response_obj, start_stop_name) { var name; + if (_.isString(date)) { if (date === 'now') { return; } else if (date.indexOf('now-') >= 0) { - - name = start_stop_name + "_relative"; - date = date.substring(4); + name = start_stop_name + "_relative"; var re_date = /(\d+)\s*(\D+)/; var result = re_date.exec(date); + if (result) { var value = result[1]; var unit = result[2]; - switch (unit) { - case 'ms': - unit = 'milliseconds'; - break; - case 's': - unit = 'seconds'; - break; - case 'm': - unit = 'minutes'; - break; - case 'h': - unit = 'hours'; - break; - case 'd': - unit = 'days'; - break; - case 'w': - unit = 'weeks'; - break; - case 'M': - unit = 'months'; - break; - case 'y': - unit = 'years'; - break; - default: - console.log("Unknown date ", date); - break; - } + response_obj[name] = { - "value": value, - "unit": unit + value: value, + unit: convertToKairosDBTimeUnit(unit) }; return; } console.log("Unparseable date", date); return; } + date = kbn.parseDate(date); } @@ -384,6 +350,30 @@ function (angular, _, kbn) { console.log("Date is neither string nor date"); } + function convertToKairosDBTimeUnit(unit) { + switch (unit) { + case 'ms': + return 'milliseconds'; + case 's': + return 'seconds'; + case 'm': + return 'minutes'; + case 'h': + return 'hours'; + case 'd': + return 'days'; + case 'w': + return 'weeks'; + case 'M': + return 'months'; + case 'y': + return 'years'; + default: + console.log("Unknown unit ", unit); + return ''; + } + } + function PeakFilter(dataIn, limit) { var datapoints = dataIn; var arrLength = datapoints.length; @@ -417,7 +407,6 @@ function (angular, _, kbn) { return datapoints; } - //////////////////////////////////////////////////////////////////////// return KairosDBDatasource; }); diff --git a/public/app/plugins/datasource/kairosdb/queryCtrl.js b/public/app/plugins/datasource/kairosdb/queryCtrl.js index 9aad7c41fc9..6370afc7c0e 100644 --- a/public/app/plugins/datasource/kairosdb/queryCtrl.js +++ b/public/app/plugins/datasource/kairosdb/queryCtrl.js @@ -37,6 +37,7 @@ function (angular, _) { $scope.get_data(); } }; + $scope.panelBlur = function() { _.each($scope.panel.targets, function(target) { target.downsampling = $scope.panel.downsampling; @@ -49,6 +50,7 @@ function (angular, _) { var clone = angular.copy($scope.target); $scope.panel.targets.push(clone); }; + $scope.moveMetricQuery = function(fromIndex, toIndex) { _.move($scope.panel.targets, fromIndex, toIndex); }; @@ -140,7 +142,6 @@ function (angular, _) { if (!$scope.target.groupByTags) { $scope.target.groupByTags = []; } - console.log($scope.target.groupBy.tagKey); if (!_.contains($scope.target.groupByTags, $scope.target.groupBy.tagKey)) { $scope.target.groupByTags.push($scope.target.groupBy.tagKey); $scope.targetBlur(); @@ -202,12 +203,14 @@ function (angular, _) { errors.tagKey = 'You must supply a tag name'; } } + if ($scope.isValueGroupBy) { if (!$scope.target.groupBy.valueRange || !isInt($scope.target.groupBy.valueRange)) { errors.valueRange = "Range must be an integer"; $scope.isGroupByValid = false; } } + if ($scope.isTimeGroupBy) { try { $scope.datasource.convertToKairosInterval($scope.target.groupBy.timeInterval); @@ -265,7 +268,6 @@ function (angular, _) { $scope.hasUnit = false; $scope.hasFactor = false; $scope.hasPercentile = false; - }; $scope.removeHorizontalAggregator = function(index) { @@ -279,7 +281,7 @@ function (angular, _) { $scope.changeHorAggregationInput = function() { $scope.hasSamplingRate = _.contains(['avg','dev','max','min','sum','least_squares','count','percentile'], - $scope.target.currentHorizontalAggregatorName); + $scope.target.currentHorizontalAggregatorName); $scope.hasUnit = _.contains(['sampler','rate'], $scope.target.currentHorizontalAggregatorName); $scope.hasFactor = _.contains(['div','scale'], $scope.target.currentHorizontalAggregatorName); $scope.hasPercentile = 'percentile' === $scope.target.currentHorizontalAggregatorName; @@ -290,6 +292,7 @@ function (angular, _) { delete $scope.target.errors.horAggregator; var errors = {}; $scope.isAggregatorValid = true; + if ($scope.hasSamplingRate) { try { $scope.datasource.convertToKairosInterval($scope.target.horAggregator.samplingRate); @@ -298,6 +301,7 @@ function (angular, _) { $scope.isAggregatorValid = false; } } + if ($scope.hasFactor) { if (!$scope.target.horAggregator.factor) { errors.factor = 'You must supply a numeric value for this aggregator'; @@ -308,6 +312,7 @@ function (angular, _) { $scope.isAggregatorValid = false; } } + if ($scope.hasPercentile) { if (!$scope.target.horAggregator.percentile || $scope.target.horAggregator.percentile<=0 ||