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 @@