diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ff1f10a8b4..c5729e24f96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # 2.5.1 (unreleased) ### Enhancements -* **cloudwatch**: Support for multiple AWS Credentials, closes [#3053](https://github.com/grafana/grafana/issues/3053), [#3080](https://github.com/grafana/grafana/issues/3080) +* **CloudWatch**: Support for multiple AWS Credentials, closes [#3053](https://github.com/grafana/grafana/issues/3053), [#3080](https://github.com/grafana/grafana/issues/3080) +* **Elasticsearch**: Support for dynamic daily indices for annotations, closes [#3061](https://github.com/grafana/grafana/issues/3061) ### Bug Fixes * **dashboard**: fix for collapse row by clicking on row title, fixes [#3065](https://github.com/grafana/grafana/issues/3065) diff --git a/public/app/features/annotations/annotationsSrv.js b/public/app/features/annotations/annotationsSrv.js index 89c9b72ec1f..f131ad28393 100644 --- a/public/app/features/annotations/annotationsSrv.js +++ b/public/app/features/annotations/annotationsSrv.js @@ -7,14 +7,14 @@ define([ var module = angular.module('grafana.services'); - module.service('annotationsSrv', function(datasourceSrv, $q, alertSrv, $rootScope) { + module.service('annotationsSrv', function($rootScope, $q, datasourceSrv, alertSrv, timeSrv) { var promiseCached; var list = []; var self = this; this.init = function() { $rootScope.onAppEvent('refresh', this.clearCache, $rootScope); - $rootScope.onAppEvent('setup-dashboard', this.clearCache, $rootScope); + $rootScope.onAppEvent('dashboard-loaded', this.clearCache, $rootScope); }; this.clearCache = function() { @@ -22,7 +22,7 @@ define([ list = []; }; - this.getAnnotations = function(rangeUnparsed, dashboard) { + this.getAnnotations = function(dashboard) { if (dashboard.annotations.list.length === 0) { return $q.when(null); } @@ -34,9 +34,13 @@ define([ self.dashboard = dashboard; var annotations = _.where(dashboard.annotations.list, {enable: true}); + var range = timeSrv.timeRange(); + var rangeRaw = timeSrv.timeRange(false); + var promises = _.map(annotations, function(annotation) { return datasourceSrv.get(annotation.datasource).then(function(datasource) { - return datasource.annotationQuery(annotation, rangeUnparsed) + var query = {range: range, rangeRaw: rangeRaw, annotation: annotation}; + return datasource.annotationQuery(query) .then(self.receiveAnnotationResults) .then(null, errorHandler); }, this); diff --git a/public/app/panels/graph/module.js b/public/app/panels/graph/module.js index 5cdeab799de..1cbd59f8a18 100644 --- a/public/app/panels/graph/module.js +++ b/public/app/panels/graph/module.js @@ -129,7 +129,7 @@ function (angular, $, _, kbn, moment, TimeSeries, PanelMeta) { $scope.refreshData = function(datasource) { panelHelper.updateTimeRange($scope); - $scope.annotationsPromise = annotationsSrv.getAnnotations($scope.rangeRaw, $scope.dashboard); + $scope.annotationsPromise = annotationsSrv.getAnnotations($scope.dashboard); return panelHelper.issueMetricQuery($scope, datasource) .then($scope.dataHandler, function(err) { diff --git a/public/app/plugins/PLUGIN_CHANGES.md b/public/app/plugins/PLUGIN_CHANGES.md index 5627af4a706..b79a0b65948 100644 --- a/public/app/plugins/PLUGIN_CHANGES.md +++ b/public/app/plugins/PLUGIN_CHANGES.md @@ -2,6 +2,12 @@ ## Changelog +2.5.1 +datasource annotationQuery changed. now single options parameter with: +- range +- rangeRaw +- annotation + 2.5 changed the `range` parameter in the `datasource.query` function's options parameter. This parameter now holds a parsed range with `moment` dates `form` and `to`. To get millisecond epoc from a `moment` you the function `valueOf`. The raw date range as represented diff --git a/public/app/plugins/datasource/elasticsearch/datasource.js b/public/app/plugins/datasource/elasticsearch/datasource.js index 374fc9da90d..6c216713368 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.js +++ b/public/app/plugins/datasource/elasticsearch/datasource.js @@ -60,17 +60,18 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes }); }; - ElasticDatasource.prototype.annotationQuery = function(annotation, rangeUnparsed) { - var range = {}; + ElasticDatasource.prototype.annotationQuery = function(options) { + var annotation = options.annotation; var timeField = annotation.timeField || '@timestamp'; var queryString = annotation.query || '*'; var tagsField = annotation.tagsField || 'tags'; var titleField = annotation.titleField || 'desc'; var textField = annotation.textField || null; + var range = {}; range[timeField]= { - from: rangeUnparsed.from, - to: rangeUnparsed.to, + from: options.range.from.valueOf(), + to: options.range.to.valueOf(), }; var queryInterpolated = templateSrv.replace(queryString); @@ -82,9 +83,20 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes "size": 10000 }; - return this._request('POST', annotation.index + '/_search', data).then(function(results) { + var header = {search_type: "query_then_fetch", "ignore_unavailable": true}; + + // old elastic annotations had index specified on them + if (annotation.index) { + header.index = annotation.index; + } else { + header.index = this.indexPattern.getIndexList(options.range.from, options.range.to); + } + + var payload = angular.toJson(header) + '\n' + angular.toJson(data) + '\n'; + + return this._post('/_msearch', payload).then(function(res) { var list = []; - var hits = results.data.hits.hits; + var hits = res.responses[0].hits.hits; var getFieldFromSource = function(source, fieldName) { if (!fieldName) { return; } diff --git a/public/app/plugins/datasource/elasticsearch/partials/annotations.editor.html b/public/app/plugins/datasource/elasticsearch/partials/annotations.editor.html index dae7d2bdeba..637ae78ada7 100644 --- a/public/app/plugins/datasource/elasticsearch/partials/annotations.editor.html +++ b/public/app/plugins/datasource/elasticsearch/partials/annotations.editor.html @@ -1,5 +1,5 @@
-
+
Index name
diff --git a/public/app/plugins/datasource/graphite/datasource.js b/public/app/plugins/datasource/graphite/datasource.js index f9e747fb984..8362412fd55 100644 --- a/public/app/plugins/datasource/graphite/datasource.js +++ b/public/app/plugins/datasource/graphite/datasource.js @@ -70,12 +70,12 @@ function (angular, _, $, config, dateMath) { return result; }; - GraphiteDatasource.prototype.annotationQuery = function(annotation, rangeUnparsed) { + GraphiteDatasource.prototype.annotationQuery = function(options) { // Graphite metric as annotation - if (annotation.target) { - var target = templateSrv.replace(annotation.target); + if (options.annotation.target) { + var target = templateSrv.replace(options.annotation.target); var graphiteQuery = { - rangeRaw: rangeUnparsed, + rangeRaw: options.rangeRaw, targets: [{ target: target }], format: 'json', maxDataPoints: 100 @@ -93,7 +93,7 @@ function (angular, _, $, config, dateMath) { if (!datapoint[0]) { continue; } list.push({ - annotation: annotation, + annotation: options.annotation, time: datapoint[1], title: target.target }); @@ -105,15 +105,15 @@ function (angular, _, $, config, dateMath) { } // Graphite event as annotation else { - var tags = templateSrv.replace(annotation.tags); - return this.events({ range: rangeUnparsed, tags: tags }) + var tags = templateSrv.replace(options.annotation.tags); + return this.events({range: options.rangeRaw, tags: tags}) .then(function(results) { var list = []; for (var i = 0; i < results.data.length; i++) { var e = results.data[i]; list.push({ - annotation: annotation, + annotation: options.annotation, time: e.when * 1000, title: e.what, tags: e.tags, diff --git a/public/app/plugins/datasource/influxdb/datasource.js b/public/app/plugins/datasource/influxdb/datasource.js index b8ee9b15d49..8460a0c1d0d 100644 --- a/public/app/plugins/datasource/influxdb/datasource.js +++ b/public/app/plugins/datasource/influxdb/datasource.js @@ -77,16 +77,16 @@ function (angular, _, dateMath, InfluxSeries, InfluxQueryBuilder) { }); }; - InfluxDatasource.prototype.annotationQuery = function(annotation, rangeUnparsed) { - var timeFilter = getTimeFilter({ rangeRaw: rangeUnparsed }); - var query = annotation.query.replace('$timeFilter', timeFilter); + InfluxDatasource.prototype.annotationQuery = function(options) { + var timeFilter = getTimeFilter({rangeRaw: options.rangeRaw}); + var query = options.annotation.query.replace('$timeFilter', timeFilter); query = templateSrv.replace(query); return this._seriesQuery(query).then(function(data) { if (!data || !data.results || !data.results[0]) { throw { message: 'No results in response from InfluxDB' }; } - return new InfluxSeries({ series: data.results[0].series, annotation: annotation }).getAnnotations(); + return new InfluxSeries({series: data.results[0].series, annotation: options.annotation}).getAnnotations(); }); }; diff --git a/public/app/plugins/datasource/influxdb_08/datasource.js b/public/app/plugins/datasource/influxdb_08/datasource.js index a5058db3eb6..3ed12ac2d08 100644 --- a/public/app/plugins/datasource/influxdb_08/datasource.js +++ b/public/app/plugins/datasource/influxdb_08/datasource.js @@ -57,13 +57,13 @@ function (angular, _, dateMath, InfluxSeries, InfluxQueryBuilder) { }); }; - InfluxDatasource.prototype.annotationQuery = function(annotation, rangeUnparsed) { - var timeFilter = getTimeFilter({ rangeRaw: rangeUnparsed }); - var query = annotation.query.replace('$timeFilter', timeFilter); + InfluxDatasource.prototype.annotationQuery = function(options) { + var timeFilter = getTimeFilter({rangeRaw: options.rangeRaw}); + var query = options.annotation.query.replace('$timeFilter', timeFilter); query = templateSrv.replace(query); return this._seriesQuery(query).then(function(results) { - return new InfluxSeries({ seriesList: results, annotation: annotation }).getAnnotations(); + return new InfluxSeries({seriesList: results, annotation: options.annotation}).getAnnotations(); }); }; diff --git a/public/app/plugins/datasource/influxdb_08/specs/datasource-specs.ts b/public/app/plugins/datasource/influxdb_08/specs/datasource-specs.ts index c4ea81759e8..46459939828 100644 --- a/public/app/plugins/datasource/influxdb_08/specs/datasource-specs.ts +++ b/public/app/plugins/datasource/influxdb_08/specs/datasource-specs.ts @@ -84,7 +84,7 @@ describe('InfluxDatasource', function() { return str.replace('$server', 'backend_01'); }; ctx.$httpBackend.expect('GET', urlExpected).respond(response); - ctx.ds.annotationQuery(annotation, range).then(function(data) { results = data; }); + ctx.ds.annotationQuery({annotation: annotation, rangeRaw: range}).then(function(data) { results = data; }); ctx.$httpBackend.flush(); });