mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #10434 from craig-miskell-fluxfederation/prometheus_align_queries
Align queries to prometheus with the step
This commit is contained in:
commit
65f9970a3e
@ -107,10 +107,18 @@ export class PrometheusDatasource {
|
|||||||
return this.templateSrv.variableExists(target.expr);
|
return this.templateSrv.variableExists(target.expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clampRange(start, end, step) {
|
||||||
|
const clampedEnd = Math.ceil(end / step) * step;
|
||||||
|
const clampedRange = Math.floor((end - start) / step) * step;
|
||||||
|
return {
|
||||||
|
end: clampedEnd,
|
||||||
|
start: clampedEnd - clampedRange,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
query(options) {
|
query(options) {
|
||||||
var start = this.getPrometheusTime(options.range.from, false);
|
var start = this.getPrometheusTime(options.range.from, false);
|
||||||
var end = this.getPrometheusTime(options.range.to, true);
|
var end = this.getPrometheusTime(options.range.to, true);
|
||||||
var range = Math.ceil(end - start);
|
|
||||||
|
|
||||||
var queries = [];
|
var queries = [];
|
||||||
var activeTargets = [];
|
var activeTargets = [];
|
||||||
@ -123,7 +131,7 @@ export class PrometheusDatasource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
activeTargets.push(target);
|
activeTargets.push(target);
|
||||||
queries.push(this.createQuery(target, options, range));
|
queries.push(this.createQuery(target, options, start, end));
|
||||||
}
|
}
|
||||||
|
|
||||||
// No valid targets, return the empty result to save a round trip.
|
// No valid targets, return the empty result to save a round trip.
|
||||||
@ -133,7 +141,7 @@ export class PrometheusDatasource {
|
|||||||
|
|
||||||
var allQueryPromise = _.map(queries, query => {
|
var allQueryPromise = _.map(queries, query => {
|
||||||
if (!query.instant) {
|
if (!query.instant) {
|
||||||
return this.performTimeSeriesQuery(query, start, end);
|
return this.performTimeSeriesQuery(query, query.start, query.end);
|
||||||
} else {
|
} else {
|
||||||
return this.performInstantQuery(query, end);
|
return this.performInstantQuery(query, end);
|
||||||
}
|
}
|
||||||
@ -147,7 +155,8 @@ export class PrometheusDatasource {
|
|||||||
throw response.error;
|
throw response.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
let transformerOptions = {
|
// Keeping original start/end for transformers
|
||||||
|
const transformerOptions = {
|
||||||
format: activeTargets[index].format,
|
format: activeTargets[index].format,
|
||||||
step: queries[index].step,
|
step: queries[index].step,
|
||||||
legendFormat: activeTargets[index].legendFormat,
|
legendFormat: activeTargets[index].legendFormat,
|
||||||
@ -165,9 +174,10 @@ export class PrometheusDatasource {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createQuery(target, options, range) {
|
createQuery(target, options, start, end) {
|
||||||
var query: any = {};
|
var query: any = {};
|
||||||
query.instant = target.instant;
|
query.instant = target.instant;
|
||||||
|
var range = Math.ceil(end - start);
|
||||||
|
|
||||||
var interval = kbn.interval_to_seconds(options.interval);
|
var interval = kbn.interval_to_seconds(options.interval);
|
||||||
// Minimum interval ("Min step"), if specified for the query. or same as interval otherwise
|
// Minimum interval ("Min step"), if specified for the query. or same as interval otherwise
|
||||||
@ -191,6 +201,12 @@ export class PrometheusDatasource {
|
|||||||
// Only replace vars in expression after having (possibly) updated interval vars
|
// Only replace vars in expression after having (possibly) updated interval vars
|
||||||
query.expr = this.templateSrv.replace(target.expr, scopedVars, this.interpolateQueryExpr);
|
query.expr = this.templateSrv.replace(target.expr, scopedVars, this.interpolateQueryExpr);
|
||||||
query.requestId = options.panelId + target.refId;
|
query.requestId = options.panelId + target.refId;
|
||||||
|
|
||||||
|
// Align query interval with step
|
||||||
|
const adjusted = this.clampRange(start, end, query.step);
|
||||||
|
query.start = adjusted.start;
|
||||||
|
query.end = adjusted.end;
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,22 +286,18 @@ export class PrometheusDatasource {
|
|||||||
return this.$q.when([]);
|
return this.$q.when([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var interpolated = this.templateSrv.replace(expr, {}, this.interpolateQueryExpr);
|
var step = annotation.step || '60s';
|
||||||
|
|
||||||
var step = '60s';
|
|
||||||
if (annotation.step) {
|
|
||||||
step = this.templateSrv.replace(annotation.step);
|
|
||||||
}
|
|
||||||
|
|
||||||
var start = this.getPrometheusTime(options.range.from, false);
|
var start = this.getPrometheusTime(options.range.from, false);
|
||||||
var end = this.getPrometheusTime(options.range.to, true);
|
var end = this.getPrometheusTime(options.range.to, true);
|
||||||
var query = {
|
// Unsetting min interval
|
||||||
expr: interpolated,
|
const queryOptions = {
|
||||||
step: this.adjustInterval(kbn.interval_to_seconds(step), 0, Math.ceil(end - start), 1) + 's',
|
...options,
|
||||||
|
interval: '0s',
|
||||||
};
|
};
|
||||||
|
const query = this.createQuery({ expr, interval: step }, queryOptions, start, end);
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return this.performTimeSeriesQuery(query, start, end).then(function(results) {
|
return this.performTimeSeriesQuery(query, query.start, query.end).then(function(results) {
|
||||||
var eventList = [];
|
var eventList = [];
|
||||||
tagKeys = tagKeys.split(',');
|
tagKeys = tagKeys.split(',');
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
data-min-length=0 data-items=1000 ng-model-onblur ng-change="ctrl.refreshMetricData()">
|
data-min-length=0 data-items=1000 ng-model-onblur ng-change="ctrl.refreshMetricData()">
|
||||||
</input>
|
</input>
|
||||||
<info-popover mode="right-absolute">
|
<info-popover mode="right-absolute">
|
||||||
Controls the name of the time series, using name or pattern. For example <span ng-non-bindable>{{hostname}}</span> will be replaced with label value for
|
Controls the name of the time series, using name or pattern. For example
|
||||||
the label hostname.
|
<span ng-non-bindable>{{hostname}}</span> will be replaced with label value for the label hostname.
|
||||||
</info-popover>
|
</info-popover>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -25,7 +25,8 @@
|
|||||||
placeholder="{{ctrl.panelCtrl.interval}}" data-min-length=0 data-items=100 ng-model-onblur ng-change="ctrl.refreshMetricData()"
|
placeholder="{{ctrl.panelCtrl.interval}}" data-min-length=0 data-items=100 ng-model-onblur ng-change="ctrl.refreshMetricData()"
|
||||||
/>
|
/>
|
||||||
<info-popover mode="right-absolute">
|
<info-popover mode="right-absolute">
|
||||||
Leave blank for auto handling based on time range and panel width
|
Leave blank for auto handling based on time range and panel width. Note that the actual dates used in the query will be adjusted
|
||||||
|
to a multiple of the interval step.
|
||||||
</info-popover>
|
</info-popover>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -4,6 +4,12 @@ import $ from 'jquery';
|
|||||||
import helpers from 'test/specs/helpers';
|
import helpers from 'test/specs/helpers';
|
||||||
import { PrometheusDatasource } from '../datasource';
|
import { PrometheusDatasource } from '../datasource';
|
||||||
|
|
||||||
|
const SECOND = 1000;
|
||||||
|
const MINUTE = 60 * SECOND;
|
||||||
|
const HOUR = 60 * MINUTE;
|
||||||
|
|
||||||
|
const time = ({ hours = 0, seconds = 0, minutes = 0 }) => moment(hours * HOUR + minutes * MINUTE + seconds * SECOND);
|
||||||
|
|
||||||
describe('PrometheusDatasource', function() {
|
describe('PrometheusDatasource', function() {
|
||||||
var ctx = new helpers.ServiceTestContext();
|
var ctx = new helpers.ServiceTestContext();
|
||||||
var instanceSettings = {
|
var instanceSettings = {
|
||||||
@ -29,18 +35,16 @@ describe('PrometheusDatasource', function() {
|
|||||||
$httpBackend.when('GET', /\.html$/).respond('');
|
$httpBackend.when('GET', /\.html$/).respond('');
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
describe('When querying prometheus with one target using query editor target spec', function() {
|
describe('When querying prometheus with one target using query editor target spec', function() {
|
||||||
var results;
|
var results;
|
||||||
var urlExpected =
|
|
||||||
'proxied/api/v1/query_range?query=' +
|
|
||||||
encodeURIComponent('test{job="testjob"}') +
|
|
||||||
'&start=1443438675&end=1443460275&step=60';
|
|
||||||
var query = {
|
var query = {
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ seconds: 63 }), to: time({ seconds: 183 }) },
|
||||||
targets: [{ expr: 'test{job="testjob"}', format: 'time_series' }],
|
targets: [{ expr: 'test{job="testjob"}', format: 'time_series' }],
|
||||||
interval: '60s',
|
interval: '60s',
|
||||||
};
|
};
|
||||||
|
// Interval alignment with step
|
||||||
|
var urlExpected =
|
||||||
|
'proxied/api/v1/query_range?query=' + encodeURIComponent('test{job="testjob"}') + '&start=120&end=240&step=60';
|
||||||
var response = {
|
var response = {
|
||||||
status: 'success',
|
status: 'success',
|
||||||
data: {
|
data: {
|
||||||
@ -48,7 +52,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
result: [
|
result: [
|
||||||
{
|
{
|
||||||
metric: { __name__: 'test', job: 'testjob' },
|
metric: { __name__: 'test', job: 'testjob' },
|
||||||
values: [[1443454528, '3846']],
|
values: [[60, '3846']],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -70,8 +74,8 @@ describe('PrometheusDatasource', function() {
|
|||||||
});
|
});
|
||||||
describe('When querying prometheus with one target which return multiple series', function() {
|
describe('When querying prometheus with one target which return multiple series', function() {
|
||||||
var results;
|
var results;
|
||||||
var start = 1443438675;
|
var start = 60;
|
||||||
var end = 1443460275;
|
var end = 360;
|
||||||
var step = 60;
|
var step = 60;
|
||||||
var urlExpected =
|
var urlExpected =
|
||||||
'proxied/api/v1/query_range?query=' +
|
'proxied/api/v1/query_range?query=' +
|
||||||
@ -83,7 +87,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
'&step=' +
|
'&step=' +
|
||||||
step;
|
step;
|
||||||
var query = {
|
var query = {
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ seconds: start }), to: time({ seconds: end }) },
|
||||||
targets: [{ expr: 'test{job="testjob"}', format: 'time_series' }],
|
targets: [{ expr: 'test{job="testjob"}', format: 'time_series' }],
|
||||||
interval: '60s',
|
interval: '60s',
|
||||||
};
|
};
|
||||||
@ -139,9 +143,9 @@ describe('PrometheusDatasource', function() {
|
|||||||
});
|
});
|
||||||
describe('When querying prometheus with one target and instant = true', function() {
|
describe('When querying prometheus with one target and instant = true', function() {
|
||||||
var results;
|
var results;
|
||||||
var urlExpected = 'proxied/api/v1/query?query=' + encodeURIComponent('test{job="testjob"}') + '&time=1443460275';
|
var urlExpected = 'proxied/api/v1/query?query=' + encodeURIComponent('test{job="testjob"}') + '&time=123';
|
||||||
var query = {
|
var query = {
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ seconds: 63 }), to: time({ seconds: 123 }) },
|
||||||
targets: [{ expr: 'test{job="testjob"}', format: 'time_series', instant: true }],
|
targets: [{ expr: 'test{job="testjob"}', format: 'time_series', instant: true }],
|
||||||
interval: '60s',
|
interval: '60s',
|
||||||
};
|
};
|
||||||
@ -152,7 +156,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
result: [
|
result: [
|
||||||
{
|
{
|
||||||
metric: { __name__: 'test', job: 'testjob' },
|
metric: { __name__: 'test', job: 'testjob' },
|
||||||
value: [1443454528, '3846'],
|
value: [123, '3846'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -177,7 +181,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
var urlExpected =
|
var urlExpected =
|
||||||
'proxied/api/v1/query_range?query=' +
|
'proxied/api/v1/query_range?query=' +
|
||||||
encodeURIComponent('ALERTS{alertstate="firing"}') +
|
encodeURIComponent('ALERTS{alertstate="firing"}') +
|
||||||
'&start=1443438675&end=1443460275&step=60s';
|
'&start=120&end=180&step=60';
|
||||||
var options = {
|
var options = {
|
||||||
annotation: {
|
annotation: {
|
||||||
expr: 'ALERTS{alertstate="firing"}',
|
expr: 'ALERTS{alertstate="firing"}',
|
||||||
@ -186,8 +190,8 @@ describe('PrometheusDatasource', function() {
|
|||||||
textFormat: '{{instance}}',
|
textFormat: '{{instance}}',
|
||||||
},
|
},
|
||||||
range: {
|
range: {
|
||||||
from: moment(1443438674760),
|
from: time({ seconds: 63 }),
|
||||||
to: moment(1443460274760),
|
to: time({ seconds: 123 }),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
var response = {
|
var response = {
|
||||||
@ -203,7 +207,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
instance: 'testinstance',
|
instance: 'testinstance',
|
||||||
job: 'testjob',
|
job: 'testjob',
|
||||||
},
|
},
|
||||||
values: [[1443454528, '1']],
|
values: [[123, '1']],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -221,15 +225,15 @@ describe('PrometheusDatasource', function() {
|
|||||||
expect(results[0].tags).to.contain('testjob');
|
expect(results[0].tags).to.contain('testjob');
|
||||||
expect(results[0].title).to.be('InstanceDown');
|
expect(results[0].title).to.be('InstanceDown');
|
||||||
expect(results[0].text).to.be('testinstance');
|
expect(results[0].text).to.be('testinstance');
|
||||||
expect(results[0].time).to.be(1443454528 * 1000);
|
expect(results[0].time).to.be(123 * 1000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('When resultFormat is table and instant = true', function() {
|
describe('When resultFormat is table and instant = true', function() {
|
||||||
var results;
|
var results;
|
||||||
var urlExpected = 'proxied/api/v1/query?query=' + encodeURIComponent('test{job="testjob"}') + '&time=1443460275';
|
var urlExpected = 'proxied/api/v1/query?query=' + encodeURIComponent('test{job="testjob"}') + '&time=123';
|
||||||
var query = {
|
var query = {
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ seconds: 63 }), to: time({ seconds: 123 }) },
|
||||||
targets: [{ expr: 'test{job="testjob"}', format: 'time_series', instant: true }],
|
targets: [{ expr: 'test{job="testjob"}', format: 'time_series', instant: true }],
|
||||||
interval: '60s',
|
interval: '60s',
|
||||||
};
|
};
|
||||||
@ -240,7 +244,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
result: [
|
result: [
|
||||||
{
|
{
|
||||||
metric: { __name__: 'test', job: 'testjob' },
|
metric: { __name__: 'test', job: 'testjob' },
|
||||||
value: [1443454528, '3846'],
|
value: [123, '3846'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -270,8 +274,8 @@ describe('PrometheusDatasource', function() {
|
|||||||
|
|
||||||
it('should be min interval when greater than auto interval', function() {
|
it('should be min interval when greater than auto interval', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 minute range
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'test',
|
expr: 'test',
|
||||||
@ -280,7 +284,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
],
|
],
|
||||||
interval: '5s',
|
interval: '5s',
|
||||||
};
|
};
|
||||||
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=1443438675&end=1443460275&step=10';
|
var urlExpected = 'proxied/api/v1/query_range?query=test&start=60&end=420&step=10';
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
@ -288,12 +292,12 @@ describe('PrometheusDatasource', function() {
|
|||||||
|
|
||||||
it('step should never go below 1', function() {
|
it('step should never go below 1', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 minute range
|
||||||
range: { from: moment(1508318768202), to: moment(1508318770118) },
|
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
|
||||||
targets: [{ expr: 'test' }],
|
targets: [{ expr: 'test' }],
|
||||||
interval: '100ms',
|
interval: '100ms',
|
||||||
};
|
};
|
||||||
var urlExpected = 'proxied/api/v1/query_range?query=test&start=1508318769&end=1508318771&step=1';
|
var urlExpected = 'proxied/api/v1/query_range?query=test&start=60&end=420&step=1';
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
@ -301,8 +305,8 @@ describe('PrometheusDatasource', function() {
|
|||||||
|
|
||||||
it('should be auto interval when greater than min interval', function() {
|
it('should be auto interval when greater than min interval', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 minute range
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'test',
|
expr: 'test',
|
||||||
@ -311,7 +315,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
],
|
],
|
||||||
interval: '10s',
|
interval: '10s',
|
||||||
};
|
};
|
||||||
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=1443438675&end=1443460275&step=10';
|
var urlExpected = 'proxied/api/v1/query_range?query=test&start=60&end=420&step=10';
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
@ -319,19 +323,21 @@ describe('PrometheusDatasource', function() {
|
|||||||
it('should result in querying fewer than 11000 data points', function() {
|
it('should result in querying fewer than 11000 data points', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 hour range
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ hours: 1 }), to: time({ hours: 7 }) },
|
||||||
targets: [{ expr: 'test' }],
|
targets: [{ expr: 'test' }],
|
||||||
interval: '1s',
|
interval: '1s',
|
||||||
};
|
};
|
||||||
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=1443438675&end=1443460275&step=2';
|
var end = 7 * 60 * 60;
|
||||||
|
var start = 60 * 60;
|
||||||
|
var urlExpected = 'proxied/api/v1/query_range?query=test&start=' + start + '&end=' + end + '&step=2';
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
});
|
});
|
||||||
it('should not apply min interval when interval * intervalFactor greater', function() {
|
it('should not apply min interval when interval * intervalFactor greater', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 minute range
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'test',
|
expr: 'test',
|
||||||
@ -341,15 +347,16 @@ describe('PrometheusDatasource', function() {
|
|||||||
],
|
],
|
||||||
interval: '5s',
|
interval: '5s',
|
||||||
};
|
};
|
||||||
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=1443438675&end=1443460275&step=50';
|
// times get rounded up to interval
|
||||||
|
var urlExpected = 'proxied/api/v1/query_range?query=test&start=100&end=450&step=50';
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
});
|
});
|
||||||
it('should apply min interval when interval * intervalFactor smaller', function() {
|
it('should apply min interval when interval * intervalFactor smaller', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 minute range
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'test',
|
expr: 'test',
|
||||||
@ -359,15 +366,15 @@ describe('PrometheusDatasource', function() {
|
|||||||
],
|
],
|
||||||
interval: '5s',
|
interval: '5s',
|
||||||
};
|
};
|
||||||
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=1443438675&end=1443460275&step=15';
|
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=60&end=420&step=15';
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
});
|
});
|
||||||
it('should apply intervalFactor to auto interval when greater', function() {
|
it('should apply intervalFactor to auto interval when greater', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 minute range
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'test',
|
expr: 'test',
|
||||||
@ -377,7 +384,8 @@ describe('PrometheusDatasource', function() {
|
|||||||
],
|
],
|
||||||
interval: '10s',
|
interval: '10s',
|
||||||
};
|
};
|
||||||
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=1443438675&end=1443460275&step=100';
|
// times get rounded up to interval
|
||||||
|
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=200&end=500&step=100';
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
@ -385,7 +393,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
it('should not not be affected by the 11000 data points limit when large enough', function() {
|
it('should not not be affected by the 11000 data points limit when large enough', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 1 week range
|
// 1 week range
|
||||||
range: { from: moment(1443438674760), to: moment(1444043474760) },
|
range: { from: time({}), to: time({ hours: 7 * 24 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'test',
|
expr: 'test',
|
||||||
@ -394,7 +402,9 @@ describe('PrometheusDatasource', function() {
|
|||||||
],
|
],
|
||||||
interval: '10s',
|
interval: '10s',
|
||||||
};
|
};
|
||||||
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=1443438675&end=1444043475&step=100';
|
var end = 7 * 24 * 60 * 60;
|
||||||
|
var start = 0;
|
||||||
|
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=' + start + '&end=' + end + '&step=100';
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
@ -402,7 +412,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
it('should be determined by the 11000 data points limit when too small', function() {
|
it('should be determined by the 11000 data points limit when too small', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 1 week range
|
// 1 week range
|
||||||
range: { from: moment(1443438674760), to: moment(1444043474760) },
|
range: { from: time({}), to: time({ hours: 7 * 24 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'test',
|
expr: 'test',
|
||||||
@ -411,12 +421,15 @@ describe('PrometheusDatasource', function() {
|
|||||||
],
|
],
|
||||||
interval: '5s',
|
interval: '5s',
|
||||||
};
|
};
|
||||||
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=1443438675&end=1444043475&step=60';
|
var end = 7 * 24 * 60 * 60;
|
||||||
|
var start = 0;
|
||||||
|
var urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=' + start + '&end=' + end + '&step=60';
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('The __interval and __interval_ms template variables', function() {
|
describe('The __interval and __interval_ms template variables', function() {
|
||||||
var response = {
|
var response = {
|
||||||
status: 'success',
|
status: 'success',
|
||||||
@ -428,8 +441,8 @@ describe('PrometheusDatasource', function() {
|
|||||||
|
|
||||||
it('should be unchanged when auto interval is greater than min interval', function() {
|
it('should be unchanged when auto interval is greater than min interval', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 minute range
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'rate(test[$__interval])',
|
expr: 'rate(test[$__interval])',
|
||||||
@ -443,9 +456,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
var urlExpected =
|
var urlExpected =
|
||||||
'proxied/api/v1/query_range?query=' +
|
'proxied/api/v1/query_range?query=' + encodeURIComponent('rate(test[10s])') + '&start=60&end=420&step=10';
|
||||||
encodeURIComponent('rate(test[10s])') +
|
|
||||||
'&start=1443438675&end=1443460275&step=10';
|
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
@ -457,8 +468,8 @@ describe('PrometheusDatasource', function() {
|
|||||||
});
|
});
|
||||||
it('should be min interval when it is greater than auto interval', function() {
|
it('should be min interval when it is greater than auto interval', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 minute range
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'rate(test[$__interval])',
|
expr: 'rate(test[$__interval])',
|
||||||
@ -472,9 +483,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
var urlExpected =
|
var urlExpected =
|
||||||
'proxied/api/v1/query_range?query=' +
|
'proxied/api/v1/query_range?query=' + encodeURIComponent('rate(test[10s])') + '&start=60&end=420&step=10';
|
||||||
encodeURIComponent('rate(test[10s])') +
|
|
||||||
'&start=1443438675&end=1443460275&step=10';
|
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
@ -486,8 +495,8 @@ describe('PrometheusDatasource', function() {
|
|||||||
});
|
});
|
||||||
it('should account for intervalFactor', function() {
|
it('should account for intervalFactor', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 minute range
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'rate(test[$__interval])',
|
expr: 'rate(test[$__interval])',
|
||||||
@ -502,9 +511,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
var urlExpected =
|
var urlExpected =
|
||||||
'proxied/api/v1/query_range?query=' +
|
'proxied/api/v1/query_range?query=' + encodeURIComponent('rate(test[100s])') + '&start=200&end=500&step=100';
|
||||||
encodeURIComponent('rate(test[100s])') +
|
|
||||||
'&start=1443438675&end=1443460275&step=100';
|
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
@ -516,8 +523,8 @@ describe('PrometheusDatasource', function() {
|
|||||||
});
|
});
|
||||||
it('should be interval * intervalFactor when greater than min interval', function() {
|
it('should be interval * intervalFactor when greater than min interval', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 minute range
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'rate(test[$__interval])',
|
expr: 'rate(test[$__interval])',
|
||||||
@ -532,9 +539,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
var urlExpected =
|
var urlExpected =
|
||||||
'proxied/api/v1/query_range?query=' +
|
'proxied/api/v1/query_range?query=' + encodeURIComponent('rate(test[50s])') + '&start=100&end=450&step=50';
|
||||||
encodeURIComponent('rate(test[50s])') +
|
|
||||||
'&start=1443438675&end=1443460275&step=50';
|
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
@ -546,8 +551,8 @@ describe('PrometheusDatasource', function() {
|
|||||||
});
|
});
|
||||||
it('should be min interval when greater than interval * intervalFactor', function() {
|
it('should be min interval when greater than interval * intervalFactor', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 6 hour range
|
// 6 minute range
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'rate(test[$__interval])',
|
expr: 'rate(test[$__interval])',
|
||||||
@ -562,9 +567,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
var urlExpected =
|
var urlExpected =
|
||||||
'proxied/api/v1/query_range?query=' +
|
'proxied/api/v1/query_range?query=' + encodeURIComponent('rate(test[15s])') + '&start=60&end=420&step=15';
|
||||||
encodeURIComponent('rate(test[15s])') +
|
|
||||||
'&start=1443438675&end=1443460275&step=15';
|
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
@ -577,7 +580,7 @@ describe('PrometheusDatasource', function() {
|
|||||||
it('should be determined by the 11000 data points limit, accounting for intervalFactor', function() {
|
it('should be determined by the 11000 data points limit, accounting for intervalFactor', function() {
|
||||||
var query = {
|
var query = {
|
||||||
// 1 week range
|
// 1 week range
|
||||||
range: { from: moment(1443438674760), to: moment(1444043474760) },
|
range: { from: time({}), to: time({ hours: 7 * 24 }) },
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
expr: 'rate(test[$__interval])',
|
expr: 'rate(test[$__interval])',
|
||||||
@ -590,10 +593,16 @@ describe('PrometheusDatasource', function() {
|
|||||||
__interval_ms: { text: 5 * 1000, value: 5 * 1000 },
|
__interval_ms: { text: 5 * 1000, value: 5 * 1000 },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
var end = 7 * 24 * 60 * 60;
|
||||||
|
var start = 0;
|
||||||
var urlExpected =
|
var urlExpected =
|
||||||
'proxied/api/v1/query_range?query=' +
|
'proxied/api/v1/query_range?query=' +
|
||||||
encodeURIComponent('rate(test[60s])') +
|
encodeURIComponent('rate(test[60s])') +
|
||||||
'&start=1443438675&end=1444043475&step=60';
|
'&start=' +
|
||||||
|
start +
|
||||||
|
'&end=' +
|
||||||
|
end +
|
||||||
|
'&step=60';
|
||||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||||
ctx.ds.query(query);
|
ctx.ds.query(query);
|
||||||
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
ctx.$httpBackend.verifyNoOutstandingExpectation();
|
||||||
@ -604,6 +613,29 @@ describe('PrometheusDatasource', function() {
|
|||||||
expect(query.scopedVars.__interval_ms.value).to.be(5 * 1000);
|
expect(query.scopedVars.__interval_ms.value).to.be(5 * 1000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Step alignment of intervals', function() {
|
||||||
|
it('does not modify already aligned intervals with perfect step', function() {
|
||||||
|
const range = ctx.ds.clampRange(0, 3, 3);
|
||||||
|
expect(range.start).to.be(0);
|
||||||
|
expect(range.end).to.be(3);
|
||||||
|
});
|
||||||
|
it('does modify end-aligned intervals to reflect number of steps possible', function() {
|
||||||
|
const range = ctx.ds.clampRange(1, 6, 3);
|
||||||
|
expect(range.start).to.be(3);
|
||||||
|
expect(range.end).to.be(6);
|
||||||
|
});
|
||||||
|
it('does align intervals that are a multiple of steps', function() {
|
||||||
|
const range = ctx.ds.clampRange(1, 4, 3);
|
||||||
|
expect(range.start).to.be(3);
|
||||||
|
expect(range.end).to.be(6);
|
||||||
|
});
|
||||||
|
it('does align intervals that are not a multiple of steps', function() {
|
||||||
|
const range = ctx.ds.clampRange(1, 5, 3);
|
||||||
|
expect(range.start).to.be(3);
|
||||||
|
expect(range.end).to.be(6);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PrometheusDatasource for POST', function() {
|
describe('PrometheusDatasource for POST', function() {
|
||||||
@ -635,12 +667,12 @@ describe('PrometheusDatasource for POST', function() {
|
|||||||
var urlExpected = 'proxied/api/v1/query_range';
|
var urlExpected = 'proxied/api/v1/query_range';
|
||||||
var dataExpected = $.param({
|
var dataExpected = $.param({
|
||||||
query: 'test{job="testjob"}',
|
query: 'test{job="testjob"}',
|
||||||
start: 1443438675,
|
start: 2 * 60,
|
||||||
end: 1443460275,
|
end: 3 * 60,
|
||||||
step: 60,
|
step: 60,
|
||||||
});
|
});
|
||||||
var query = {
|
var query = {
|
||||||
range: { from: moment(1443438674760), to: moment(1443460274760) },
|
range: { from: time({ minutes: 1, seconds: 3 }), to: time({ minutes: 2, seconds: 3 }) },
|
||||||
targets: [{ expr: 'test{job="testjob"}', format: 'time_series' }],
|
targets: [{ expr: 'test{job="testjob"}', format: 'time_series' }],
|
||||||
interval: '60s',
|
interval: '60s',
|
||||||
};
|
};
|
||||||
@ -651,7 +683,7 @@ describe('PrometheusDatasource for POST', function() {
|
|||||||
result: [
|
result: [
|
||||||
{
|
{
|
||||||
metric: { __name__: 'test', job: 'testjob' },
|
metric: { __name__: 'test', job: 'testjob' },
|
||||||
values: [[1443454528, '3846']],
|
values: [[2 * 60, '3846']],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user