diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cd518f11eb..d4f292a2205 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ### Breaking changes -**InfluxDB 0.8.x** The data source for the old version of influxdb (0.8.x) is no longer included in default builds. Can easily be installed via plugin system, closes #3523 +**InfluxDB 0.8.x** The data source for the old version of influxdb (0.8.x) is no longer included in default builds. Can easily be installed via improved plugin system, closes #3523 +**KairosDB** The data source is no longer included in default builds. Can easily be installed via improved plugin system, closes #3524 # 2.6.1 (unrelased, 2.6.x branch) diff --git a/public/app/plugins/datasource/kairosdb/datasource.js b/public/app/plugins/datasource/kairosdb/datasource.js deleted file mode 100644 index 287b5ce7292..00000000000 --- a/public/app/plugins/datasource/kairosdb/datasource.js +++ /dev/null @@ -1,489 +0,0 @@ -define([ - 'angular', - 'lodash', - 'app/core/utils/datemath', - 'app/core/utils/kbn', - './queryCtrl', - './directives', -], -function (angular, _, dateMath, kbn) { - 'use strict'; - - var module = angular.module('grafana.services'); - - module.factory('KairosDBDatasource', function($q, backendSrv, templateSrv) { - - function KairosDBDatasource(datasource) { - this.type = datasource.type; - this.url = datasource.url; - this.name = datasource.name; - this.supportMetrics = true; - } - - // Called once per panel (graph) - KairosDBDatasource.prototype.query = function(options) { - var start = options.rangeRaw.from; - var end = options.rangeRaw.to; - - var queries = _.compact(_.map(options.targets, _.partial(convertTargetToQuery, options))); - var plotParams = _.compact(_.map(options.targets, function(target) { - var alias = target.alias; - if (typeof target.alias === 'undefined' || target.alias === "") { - alias = target.metric; - } - - 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); - }; - - KairosDBDatasource.prototype.performTimeSeriesQuery = function(queries, start, end) { - var reqBody = { - metrics: queries, - cache_time: 0 - }; - - convertToKairosTime(start, reqBody, 'start'); - convertToKairosTime(end, reqBody, 'end'); - - var options = { - method: 'POST', - url: this.url + '/api/v1/datapoints/query', - data: reqBody - }; - - return backendSrv.datasourceRequest(options); - }; - - /** - * Gets the list of metrics - * @returns {*|Promise} - */ - KairosDBDatasource.prototype._performMetricSuggestQuery = function(metric) { - var options = { - url: this.url + '/api/v1/metricnames', - method: 'GET' - }; - - return backendSrv.datasourceRequest(options).then(function(response) { - if (!response.data) { - return $q.when([]); - } - var metrics = []; - _.each(response.data.results, function(r) { - if (r.indexOf(metric) >= 0) { - metrics.push(r); - } - }); - return metrics; - }); - }; - - KairosDBDatasource.prototype._performMetricKeyLookup = function(metric) { - if(!metric) { return $q.when([]); } - - var options = { - method: 'POST', - url: this.url + '/api/v1/datapoints/query/tags', - data: { - metrics: [{ name: metric }], - cache_time: 0, - start_absolute: 0 - } - }; - - return backendSrv.datasourceRequest(options).then(function(result) { - if (!result.data) { - return $q.when([]); - } - var tagks = []; - _.each(result.data.queries[0].results[0].tags, function(tagv, tagk) { - if(tagks.indexOf(tagk) === -1) { - tagks.push(tagk); - } - }); - return tagks; - }); - }; - - KairosDBDatasource.prototype._performMetricKeyValueLookup = function(metric, key) { - if(!metric || !key) { - return $q.when([]); - } - - var options = { - method: 'POST', - url: this.url + '/api/v1/datapoints/query/tags', - data: { - metrics: [{ name: metric }], - cache_time: 0, - start_absolute: 0 - } - }; - - return backendSrv.datasourceRequest(options).then(function(result) { - if (!result.data) { - return $q.when([]); - } - return result.data.queries[0].results[0].tags[key]; - }); - }; - - KairosDBDatasource.prototype.performTagSuggestQuery = function(metric) { - var options = { - url: this.url + '/api/v1/datapoints/query/tags', - method: 'POST', - data: { - metrics: [{ name: metric }], - cache_time: 0, - start_absolute: 0 - } - }; - - return backendSrv.datasourceRequest(options).then(function(response) { - if (!response.data) { - return []; - } - else { - return response.data.queries[0].results[0]; - } - }); - }; - - KairosDBDatasource.prototype.metricFindQuery = function(query) { - if (!query) { return $q.when([]); } - - var interpolated; - try { - interpolated = templateSrv.replace(query); - } - catch (err) { - return $q.reject(err); - } - - var responseTransform = function(result) { - return _.map(result, function(value) { - return {text: value}; - }); - }; - - var metrics_regex = /metrics\((.*)\)/; - var tag_names_regex = /tag_names\((.*)\)/; - var tag_values_regex = /tag_values\((.*),\s?(.*?)\)/; - - var metrics_query = interpolated.match(metrics_regex); - if (metrics_query) { - return this._performMetricSuggestQuery(metrics_query[1]).then(responseTransform); - } - - var tag_names_query = interpolated.match(tag_names_regex); - if (tag_names_query) { - return this._performMetricKeyLookup(tag_names_query[1]).then(responseTransform); - } - - var tag_values_query = interpolated.match(tag_values_regex); - if (tag_values_query) { - return this._performMetricKeyValueLookup(tag_values_query[1], tag_values_query[2]).then(responseTransform); - } - - return $q.when([]); - }; - - ///////////////////////////////////////////////////////////////////////// - /// Formatting methods - //////////////////////////////////////////////////////////////////////// - - /** - * Requires a verion of KairosDB with every CORS defects fixed - * @param results - * @returns {*} - */ - function handleQueryError(results) { - if (results.data.errors && !_.isEmpty(results.data.errors)) { - var errors = { - message: results.data.errors[0] - }; - return $q.reject(errors); - } - else { - return $q.reject(results); - } - } - - function handleKairosDBQueryResponse(plotParams, results) { - var output = []; - var index = 0; - _.each(results.data.queries, function(series) { - _.each(series.results, function(result) { - var target = plotParams[index].alias; - var details = " ( "; - - _.each(result.group_by, function(element) { - if (element.name === "tag") { - _.each(element.group, function(value, key) { - details += key + "=" + value + " "; - }); - } - else if (element.name === "value") { - details += 'value_group=' + element.group.group_number + " "; - } - else if (element.name === "time") { - details += 'time_group=' + element.group.group_number + " "; - } - }); - - details += ") "; - - if (details !== " ( ) ") { - target += details; - } - - var datapoints = []; - - for (var i = 0; i < result.values.length; i++) { - var t = Math.floor(result.values[i][0]); - var v = result.values[i][1]; - datapoints[i] = [v, t]; - } - if (plotParams[index].exouter) { - datapoints = new PeakFilter(datapoints, 10); - } - output.push({ target: target, datapoints: datapoints }); - }); - - index++; - }); - - return { data: _.flatten(output) }; - } - - function convertTargetToQuery(options, target) { - if (!target.metric || target.hide) { - return null; - } - - var query = { - name: templateSrv.replace(target.metric) - }; - - query.aggregators = []; - - if (target.downsampling !== '(NONE)') { - if (target.downsampling === undefined) { - target.downsampling = 'avg'; - target.sampling = '10s'; - } - query.aggregators.push({ - name: target.downsampling, - align_sampling: true, - align_start_time: true, - 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; - } - - if (target.tags) { - query.tags = angular.copy(target.tags); - _.forOwn(query.tags, function(value, key) { - query.tags[key] = _.map(value, function(tag) { return templateSrv.replace(tag); }); - }); - } - - if (target.groupByTags || target.nonTagGroupBys) { - query.group_by = []; - if (target.groupByTags) { - query.group_by.push({ - name: "tag", - tags: _.map(angular.copy(target.groupByTags), function(tag) { return templateSrv.replace(tag); }) - }); - } - - if (target.nonTagGroupBys) { - _.each(target.nonTagGroupBys, function(rawGroupBy) { - var formattedGroupBy = angular.copy(rawGroupBy); - if (formattedGroupBy.name === 'time') { - formattedGroupBy.range_size = KairosDBDatasource.prototype.convertToKairosInterval(formattedGroupBy.range_size); - } - query.group_by.push(formattedGroupBy); - }); - } - } - return query; - } - - /////////////////////////////////////////////////////////////////////// - /// Time conversion functions specifics to KairosDB - ////////////////////////////////////////////////////////////////////// - - KairosDBDatasource.prototype.convertToKairosInterval = function(intervalString) { - intervalString = templateSrv.replace(intervalString); - - var interval_regex = /(\d+(?:\.\d+)?)([Mwdhmsy])/; - var interval_regex_ms = /(\d+(?:\.\d+)?)(ms)/; - var matches = intervalString.match(interval_regex_ms); - if (!matches) { - matches = intervalString.match(interval_regex); - } - if (!matches) { - throw new Error('Invalid interval string, expecting a number followed by one of "y M w d h m s ms"'); - } - - 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'); - } - value = Math.round(kbn.intervals_in_seconds[unit] * value * 1000); - unit = 'ms'; - } - - return { - 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 && date.indexOf('/') === -1) { - 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]; - - response_obj[name] = { - value: value, - unit: convertToKairosDBTimeUnit(unit) - }; - return; - } - console.log("Unparseable date", date); - return; - } - - date = dateMath.parse(date, start_stop_name === 'end'); - } - - name = start_stop_name + "_absolute"; - response_obj[name] = date.valueOf(); - } - - 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; - if (arrLength <= 3) { - return datapoints; - } - var LastIndx = arrLength - 1; - - // Check first point - var prvDelta = Math.abs((datapoints[1][0] - datapoints[0][0]) / datapoints[0][0]); - var nxtDelta = Math.abs((datapoints[1][0] - datapoints[2][0]) / datapoints[2][0]); - if (prvDelta >= limit && nxtDelta < limit) { - datapoints[0][0] = datapoints[1][0]; - } - - // Check last point - prvDelta = Math.abs((datapoints[LastIndx - 1][0] - datapoints[LastIndx - 2][0]) / datapoints[LastIndx - 2][0]); - nxtDelta = Math.abs((datapoints[LastIndx - 1][0] - datapoints[LastIndx][0]) / datapoints[LastIndx][0]); - if (prvDelta >= limit && nxtDelta < limit) { - datapoints[LastIndx][0] = datapoints[LastIndx - 1][0]; - } - - for (var i = 1; i < arrLength - 1; i++) { - prvDelta = Math.abs((datapoints[i][0] - datapoints[i - 1][0]) / datapoints[i - 1][0]); - nxtDelta = Math.abs((datapoints[i][0] - datapoints[i + 1][0]) / datapoints[i + 1][0]); - if (prvDelta >= limit && nxtDelta >= limit) { - datapoints[i][0] = (datapoints[i - 1][0] + datapoints[i + 1][0]) / 2; - } - } - - return datapoints; - } - - return KairosDBDatasource; - }); - -}); diff --git a/public/app/plugins/datasource/kairosdb/directives.js b/public/app/plugins/datasource/kairosdb/directives.js deleted file mode 100644 index 6a24ff1f787..00000000000 --- a/public/app/plugins/datasource/kairosdb/directives.js +++ /dev/null @@ -1,17 +0,0 @@ -define([ - 'angular', -], -function (angular) { - 'use strict'; - - var module = angular.module('grafana.directives'); - - module.directive('metricQueryEditorKairosdb', function() { - return {controller: 'KairosDBQueryCtrl', templateUrl: 'app/plugins/datasource/kairosdb/partials/query.editor.html'}; - }); - - module.directive('metricQueryOptionsKairosdb', function() { - return {templateUrl: 'app/plugins/datasource/kairosdb/partials/query.options.html'}; - }); - -}); diff --git a/public/app/plugins/datasource/kairosdb/partials/config.html b/public/app/plugins/datasource/kairosdb/partials/config.html deleted file mode 100644 index 384edeaeafe..00000000000 --- a/public/app/plugins/datasource/kairosdb/partials/config.html +++ /dev/null @@ -1 +0,0 @@ -
diff --git a/public/app/plugins/datasource/kairosdb/partials/query.editor.html b/public/app/plugins/datasource/kairosdb/partials/query.editor.html deleted file mode 100644 index 2fa6880abd9..00000000000 --- a/public/app/plugins/datasource/kairosdb/partials/query.editor.html +++ /dev/null @@ -1,331 +0,0 @@ -