diff --git a/public/app/plugins/datasource/influxdb-ifql/README.md b/public/app/plugins/datasource/influxdb-ifql/README.md
index ce3917c1be2..5acb563b453 100644
--- a/public/app/plugins/datasource/influxdb-ifql/README.md
+++ b/public/app/plugins/datasource/influxdb-ifql/README.md
@@ -25,6 +25,5 @@ Read more about InfluxDB here:
- Syntax highlighting
- Tab completion (functions, values)
-- Annotations support
- Alerting integration
- Explore UI integration
diff --git a/public/app/plugins/datasource/influxdb-ifql/datasource.ts b/public/app/plugins/datasource/influxdb-ifql/datasource.ts
index ab9886baaca..c71b48ad96b 100644
--- a/public/app/plugins/datasource/influxdb-ifql/datasource.ts
+++ b/public/app/plugins/datasource/influxdb-ifql/datasource.ts
@@ -2,7 +2,13 @@ import _ from 'lodash';
import * as dateMath from 'app/core/utils/datemath';
-import { getTableModelFromResult, getTimeSeriesFromResult, getValuesFromResult, parseResults } from './response_parser';
+import {
+ getAnnotationsFromResult,
+ getTableModelFromResult,
+ getTimeSeriesFromResult,
+ getValuesFromResult,
+ parseResults,
+} from './response_parser';
import expandMacros from './metric_find_query';
function serializeParams(params) {
@@ -101,11 +107,22 @@ export default class InfluxDatasource {
});
}
- var timeFilter = this.getTimeFilter({ rangeRaw: options.rangeRaw });
- var query = options.annotation.query.replace('$timeFilter', timeFilter);
- query = this.templateSrv.replace(query, null, 'regex');
+ const { query } = options.annotation;
+ const queryOptions = {
+ scopedVars: {},
+ ...options,
+ silent: true,
+ };
+ const target = this.prepareQueryTarget({ query }, queryOptions);
- return {};
+ return this._seriesQuery(target.query, queryOptions).then(response => {
+ const results = parseResults(response.data);
+ if (results.length === 0) {
+ throw { message: 'No results in response from InfluxDB' };
+ }
+ const annotations = _.flatten(results.map(result => getAnnotationsFromResult(result, options.annotation)));
+ return annotations;
+ });
}
metricFindQuery(query: string, options?: any) {
diff --git a/public/app/plugins/datasource/influxdb-ifql/partials/annotations.editor.html b/public/app/plugins/datasource/influxdb-ifql/partials/annotations.editor.html
index 48991426c1e..53407f2a3f2 100644
--- a/public/app/plugins/datasource/influxdb-ifql/partials/annotations.editor.html
+++ b/public/app/plugins/datasource/influxdb-ifql/partials/annotations.editor.html
@@ -1,11 +1,13 @@
-
-Field mappings If your influxdb query returns more than one field you need to specify the column names below. An annotation event is composed of a title, tags, and an additional text field.
+Field mappings
+ If your influxdb query returns more than one field you need to specify the column names below. An annotation event is composed
+ of a title, tags, and an additional text field.
+
+
\ No newline at end of file
diff --git a/public/app/plugins/datasource/influxdb-ifql/plugin.json b/public/app/plugins/datasource/influxdb-ifql/plugin.json
index b4eb764d556..f87e1c33275 100644
--- a/public/app/plugins/datasource/influxdb-ifql/plugin.json
+++ b/public/app/plugins/datasource/influxdb-ifql/plugin.json
@@ -4,7 +4,7 @@
"id": "influxdb-ifql",
"defaultMatchFormat": "regex values",
"metrics": true,
- "annotations": false,
+ "annotations": true,
"alerting": false,
"queryOptions": {
"minInterval": true
diff --git a/public/app/plugins/datasource/influxdb-ifql/response_parser.ts b/public/app/plugins/datasource/influxdb-ifql/response_parser.ts
index 5481b197726..dace2cf63d2 100644
--- a/public/app/plugins/datasource/influxdb-ifql/response_parser.ts
+++ b/public/app/plugins/datasource/influxdb-ifql/response_parser.ts
@@ -1,4 +1,5 @@
import Papa from 'papaparse';
+import flatten from 'lodash/flatten';
import groupBy from 'lodash/groupBy';
import TableModel from 'app/core/table_model';
@@ -6,17 +7,25 @@ import TableModel from 'app/core/table_model';
const filterColumnKeys = key => key && key[0] !== '_' && key !== 'result' && key !== 'table';
const IGNORE_FIELDS_FOR_NAME = ['result', '', 'table'];
+
+export const getTagsFromRecord = record =>
+ Object.keys(record)
+ .filter(key => key[0] !== '_')
+ .filter(key => IGNORE_FIELDS_FOR_NAME.indexOf(key) === -1)
+ .reduce((tags, key) => {
+ tags[key] = record[key];
+ return tags;
+ }, {});
+
export const getNameFromRecord = record => {
// Measurement and field
const metric = [record._measurement, record._field];
// Add tags
- const tags = Object.keys(record)
- .filter(key => key[0] !== '_')
- .filter(key => IGNORE_FIELDS_FOR_NAME.indexOf(key) === -1)
- .map(key => `${key}=${record[key]}`);
+ const tags = getTagsFromRecord(record);
+ const tagValues = Object.keys(tags).map(key => `${key}=${tags[key]}`);
- return [...metric, ...tags].join(' ');
+ return [...metric, ...tagValues].join(' ');
};
const parseCSV = (input: string) =>
@@ -36,6 +45,33 @@ export function parseResults(response: string): any[] {
return response.trim().split(/\n\s*\s/);
}
+export function getAnnotationsFromResult(result: string, options: any) {
+ const data = parseCSV(result);
+ if (data.length === 0) {
+ return [];
+ }
+
+ const annotations = [];
+ const textSelector = options.textCol || '_value';
+ const tagsSelector = options.tagsCol || '';
+ const tagSelection = tagsSelector.split(',').map(t => t.trim());
+
+ data.forEach(record => {
+ // Remove empty values, then split in different tags for comma separated values
+ const tags = getTagsFromRecord(record);
+ const tagValues = flatten(tagSelection.filter(tag => tags[tag]).map(tag => tags[tag].split(',')));
+
+ annotations.push({
+ annotation: options,
+ time: parseTime(record._time),
+ tags: tagValues,
+ text: record[textSelector],
+ });
+ });
+
+ return annotations;
+}
+
export function getTableModelFromResult(result: string) {
const data = parseCSV(result);
diff --git a/public/app/plugins/datasource/influxdb-ifql/specs/response_parser.jest.ts b/public/app/plugins/datasource/influxdb-ifql/specs/response_parser.jest.ts
index cfd88729fa0..9a322499463 100644
--- a/public/app/plugins/datasource/influxdb-ifql/specs/response_parser.jest.ts
+++ b/public/app/plugins/datasource/influxdb-ifql/specs/response_parser.jest.ts
@@ -1,4 +1,5 @@
import {
+ getAnnotationsFromResult,
getNameFromRecord,
getTableModelFromResult,
getTimeSeriesFromResult,
@@ -16,6 +17,17 @@ describe('influxdb ifql response parser', () => {
});
});
+ describe('getAnnotationsFromResult()', () => {
+ it('expects a list of annotations', () => {
+ const results = parseResults(response);
+ const annotations = getAnnotationsFromResult(results[0], { tagsCol: 'cpu' });
+ expect(annotations.length).toBe(300);
+ expect(annotations[0].tags.length).toBe(1);
+ expect(annotations[0].tags[0]).toBe('cpu-total');
+ expect(annotations[0].text).toBe('0');
+ });
+ });
+
describe('getTableModelFromResult()', () => {
it('expects a table model', () => {
const results = parseResults(response);