Elasticsearch: Adds support for region annotations (#17602)

It is now possible to specify a field containing time-end in 
Elasticsearch annotations.
Any annotations with a time-end will become a region between 
time and time-end. Any annotations without the time-end field 
will remain a single-point annotation.

Ref #10589
pull/19825/head
Morten Fangel 6 years ago committed by Marcus Efraimsson
parent 16fa712b59
commit 66c6547e7c
  1. 1
      docs/sources/features/datasources/elasticsearch.md
  2. 39
      public/app/plugins/datasource/elasticsearch/datasource.ts
  3. 4
      public/app/plugins/datasource/elasticsearch/partials/annotations.editor.html

@ -180,6 +180,7 @@ Name | Description
------------ | -------------
Query | You can leave the search query blank or specify a lucene query
Time | The name of the time field, needs to be date field.
Time End | Optional name of the time end field, needs to be date field. If set, then annotations will be marked as a regions between time and time-end.
Text | Event description field.
Tags | Optional field name to use for event tags (can be an array or a CSV string).

@ -119,22 +119,40 @@ export class ElasticDatasource extends DataSourceApi<ElasticsearchQuery, Elastic
annotationQuery(options: any) {
const annotation = options.annotation;
const timeField = annotation.timeField || '@timestamp';
const timeEndField = annotation.timeEndField || null;
const queryString = annotation.query || '*';
const tagsField = annotation.tagsField || 'tags';
const textField = annotation.textField || null;
const range: any = {};
range[timeField] = {
const dateRanges = [];
const rangeStart: any = {};
rangeStart[timeField] = {
from: options.range.from.valueOf(),
to: options.range.to.valueOf(),
format: 'epoch_millis',
};
dateRanges.push({ range: rangeStart });
if (timeEndField) {
const rangeEnd: any = {};
rangeEnd[timeEndField] = {
from: options.range.from.valueOf(),
to: options.range.to.valueOf(),
format: 'epoch_millis',
};
dateRanges.push({ range: rangeEnd });
}
const queryInterpolated = this.templateSrv.replace(queryString, {}, 'lucene');
const query = {
bool: {
filter: [
{ range: range },
{
bool: {
should: dateRanges,
minimum_should_match: 1,
},
},
{
query_string: {
query: queryInterpolated,
@ -201,13 +219,26 @@ export class ElasticDatasource extends DataSourceApi<ElasticsearchQuery, Elastic
}
}
const event = {
const event: {
annotation: any;
time: number;
timeEnd?: number;
text: string;
tags: string | string[];
} = {
annotation: annotation,
time: toUtc(time).valueOf(),
text: getFieldFromSource(source, textField),
tags: getFieldFromSource(source, tagsField),
};
if (timeEndField) {
const timeEnd = getFieldFromSource(source, timeEndField);
if (timeEnd) {
event.timeEnd = toUtc(timeEnd).valueOf();
}
}
// legacy support for title tield
if (annotation.titleField) {
const title = getFieldFromSource(source, annotation.titleField);

@ -18,6 +18,10 @@
<span class="gf-form-label">Time</span>
<input type="text" class="gf-form-input max-width-14" ng-model='ctrl.annotation.timeField' placeholder="@timestamp"></input>
</div>
<div class="gf-form">
<span class="gf-form-label">Time End</span>
<input type="text" class="gf-form-input max-width-14" ng-model='ctrl.annotation.timeEndField' placeholder=""></input>
</div>
<div class="gf-form">
<span class="gf-form-label">Text</span>
<input type="text" class="gf-form-input max-width-14" ng-model='ctrl.annotation.textField' placeholder=""></input>

Loading…
Cancel
Save