From 2926725bab128b7bced9ce4f03b8ae368107423c Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Tue, 1 May 2018 12:49:18 +0900 Subject: [PATCH 1/3] add annotation option to treat series value as timestamp --- .../datasource/prometheus/datasource.ts | 10 ++++- .../partials/annotations.editor.html | 11 +++++- .../prometheus/specs/datasource.test.ts | 39 +++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 9332a73caca..a60882e0470 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -487,15 +487,21 @@ export class PrometheusDatasource { .value(); for (const value of series.values) { - if (value[1] === '1') { + const valueIsTrue = value[1] === '1'; // e.g. ALERTS + if (valueIsTrue || annotation.useValueForTime) { const event = { annotation: annotation, - time: Math.floor(parseFloat(value[0])) * 1000, title: self.resultTransformer.renderTemplate(titleFormat, series.metric), tags: tags, text: self.resultTransformer.renderTemplate(textFormat, series.metric), }; + if (annotation.useValueForTime) { + event['time'] = Math.floor(parseFloat(value[1])); + } else { + event['time'] = Math.floor(parseFloat(value[0])) * 1000; + } + eventList.push(event); } } diff --git a/public/app/plugins/datasource/prometheus/partials/annotations.editor.html b/public/app/plugins/datasource/prometheus/partials/annotations.editor.html index 09ee52bda45..6e5982123fd 100644 --- a/public/app/plugins/datasource/prometheus/partials/annotations.editor.html +++ b/public/app/plugins/datasource/prometheus/partials/annotations.editor.html @@ -10,7 +10,7 @@
-
Field formats
+
Field formats
Title @@ -27,4 +27,13 @@
+ +
Other options
+
+
+ + +
+
diff --git a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts index ae91e6647e0..980574624ad 100644 --- a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts @@ -630,6 +630,45 @@ describe('PrometheusDatasource', () => { expect(results[0].text).toBe('testinstance'); expect(results[0].time).toBe(123 * 1000); }); + + it('should return annotation list with seriesValueAsTiemstamp', () => { + const options = { + annotation: { + expr: 'timestamp_seconds', + tagKeys: 'job', + titleFormat: '{{job}}', + textFormat: '{{instance}}', + useValueForTime: true, + }, + range: { + from: new Date('2014-04-10T05:20:10Z'), + to: new Date('2014-05-20T03:10:22Z'), + }, + }; + ctx.backendSrvMock.datasourceRequest.mockReturnValue( + Promise.resolve({ + status: 'success', + data: { + resultType: 'matrix', + result: [ + { + metric: { + __name__: 'timestamp_milliseconds', + instance: 'testinstance', + job: 'testjob', + }, + values: [[1443454528, '1500000000000']], + }, + ], + }, + }) + ); + ctx.ds = new PrometheusDatasource(instanceSettings, q, ctx.backendSrvMock, ctx.templateSrvMock, ctx.timeSrvMock); + ctx.ds.annotationQuery(options).then(function (results) { + expect(results[0].time).toEqual(1500000000000); + ctx.backendSrvMock.datasourceRequest.mockReset(); + }); + }); }); describe('When resultFormat is table and instant = true', () => { From 3031c2e6fc1f907c0baa54756fe3aa8fa6935991 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Tue, 28 Aug 2018 01:58:53 +0900 Subject: [PATCH 2/3] fix test --- .../prometheus/specs/datasource.test.ts | 113 ++++++++---------- 1 file changed, 47 insertions(+), 66 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts index 980574624ad..1fa96d03fe7 100644 --- a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts @@ -581,7 +581,7 @@ describe('PrometheusDatasource', () => { describe('When performing annotationQuery', () => { let results; - const options = { + const options: any = { annotation: { expr: 'ALERTS{alertstate="firing"}', tagKeys: 'job', @@ -594,79 +594,60 @@ describe('PrometheusDatasource', () => { }, }; - beforeEach(async () => { - const response = { - status: 'success', + const response = { + status: 'success', + data: { data: { - data: { - resultType: 'matrix', - result: [ - { - metric: { - __name__: 'ALERTS', - alertname: 'InstanceDown', - alertstate: 'firing', - instance: 'testinstance', - job: 'testjob', - }, - values: [[123, '1']], + resultType: 'matrix', + result: [ + { + metric: { + __name__: 'ALERTS', + alertname: 'InstanceDown', + alertstate: 'firing', + instance: 'testinstance', + job: 'testjob', }, - ], - }, + values: [[123, '1']], + }, + ], }, - }; + }, + }; - backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); - ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv); + describe('not use useValueForTime', () => { + beforeEach(async () => { + options.annotation.useValueForTime = false; + backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); + ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv, templateSrv, timeSrv); - await ctx.ds.annotationQuery(options).then(data => { - results = data; + await ctx.ds.annotationQuery(options).then(function (data) { + results = data; + }); + }); + + it('should return annotation list', () => { + expect(results.length).toBe(1); + expect(results[0].tags).toContain('testjob'); + expect(results[0].title).toBe('InstanceDown'); + expect(results[0].text).toBe('testinstance'); + expect(results[0].time).toBe(123 * 1000); }); }); - it('should return annotation list', () => { - expect(results.length).toBe(1); - expect(results[0].tags).toContain('testjob'); - expect(results[0].title).toBe('InstanceDown'); - expect(results[0].text).toBe('testinstance'); - expect(results[0].time).toBe(123 * 1000); - }); - it('should return annotation list with seriesValueAsTiemstamp', () => { - const options = { - annotation: { - expr: 'timestamp_seconds', - tagKeys: 'job', - titleFormat: '{{job}}', - textFormat: '{{instance}}', - useValueForTime: true, - }, - range: { - from: new Date('2014-04-10T05:20:10Z'), - to: new Date('2014-05-20T03:10:22Z'), - }, - }; - ctx.backendSrvMock.datasourceRequest.mockReturnValue( - Promise.resolve({ - status: 'success', - data: { - resultType: 'matrix', - result: [ - { - metric: { - __name__: 'timestamp_milliseconds', - instance: 'testinstance', - job: 'testjob', - }, - values: [[1443454528, '1500000000000']], - }, - ], - }, - }) - ); - ctx.ds = new PrometheusDatasource(instanceSettings, q, ctx.backendSrvMock, ctx.templateSrvMock, ctx.timeSrvMock); - ctx.ds.annotationQuery(options).then(function (results) { - expect(results[0].time).toEqual(1500000000000); - ctx.backendSrvMock.datasourceRequest.mockReset(); + describe('use useValueForTime', () => { + beforeEach(async () => { + options.annotation.useValueForTime = true; + backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); + ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv, templateSrv, timeSrv); + + await ctx.ds.annotationQuery(options).then(function (data) { + results = data; + }); + }); + + it('should return annotation list', () => { + expect(results[0].time).toEqual(1); }); }); }); From dc08093f6c8077735fb78d24ca3791aa382ede28 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Thu, 13 Sep 2018 20:15:33 +0900 Subject: [PATCH 3/3] minor fix --- public/app/plugins/datasource/prometheus/datasource.ts | 2 +- .../datasource/prometheus/specs/datasource.test.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index a60882e0470..ca80b3760a7 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -585,7 +585,7 @@ export class PrometheusDatasource { } getTimeRange(): { start: number; end: number } { - let range = this.timeSrv.timeRange(); + const range = this.timeSrv.timeRange(); return { start: this.getPrometheusTime(range.from, false), end: this.getPrometheusTime(range.to, true), diff --git a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts index 1fa96d03fe7..eef2bbd56b6 100644 --- a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts @@ -619,9 +619,9 @@ describe('PrometheusDatasource', () => { beforeEach(async () => { options.annotation.useValueForTime = false; backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); - ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv, templateSrv, timeSrv); + ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv); - await ctx.ds.annotationQuery(options).then(function (data) { + await ctx.ds.annotationQuery(options).then(data => { results = data; }); }); @@ -639,9 +639,9 @@ describe('PrometheusDatasource', () => { beforeEach(async () => { options.annotation.useValueForTime = true; backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response)); - ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv, templateSrv, timeSrv); + ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv, timeSrv); - await ctx.ds.annotationQuery(options).then(function (data) { + await ctx.ds.annotationQuery(options).then(data => { results = data; }); });