Commit 32342926 by Carl Bergquist Committed by GitHub

Merge pull request #9226 from alin-amana/adjust_interval_variable_with_min_step

Prometheus: Rework interval and step computation
parents 273c17f3 9cf7a2d2
///<reference path="../../../headers/common.d.ts" /> ///<reference path="../../../headers/common.d.ts" />
import _ from 'lodash'; import _ from 'lodash';
import moment from 'moment';
import kbn from 'app/core/utils/kbn'; import kbn from 'app/core/utils/kbn';
import * as dateMath from 'app/core/utils/datemath'; import * as dateMath from 'app/core/utils/datemath';
import PrometheusMetricFindQuery from './metric_find_query'; import PrometheusMetricFindQuery from './metric_find_query';
import TableModel from 'app/core/table_model'; import TableModel from 'app/core/table_model';
var durationSplitRegexp = /(\d+)(ms|s|m|h|d|w|M|y)/;
function prometheusSpecialRegexEscape(value) { function prometheusSpecialRegexEscape(value) {
return value.replace(/[\\^$*+?.()|[\]{}]/g, '\\\\$&'); return value.replace(/[\\^$*+?.()|[\]{}]/g, '\\\\$&');
} }
...@@ -83,6 +80,7 @@ export class PrometheusDatasource { ...@@ -83,6 +80,7 @@ export class PrometheusDatasource {
var self = this; var self = this;
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 = [];
...@@ -95,18 +93,7 @@ export class PrometheusDatasource { ...@@ -95,18 +93,7 @@ export class PrometheusDatasource {
} }
activeTargets.push(target); activeTargets.push(target);
queries.push(this.createQuery(target, options, range));
var query: any = {};
query.expr = this.templateSrv.replace(target.expr, options.scopedVars, self.interpolateQueryExpr);
query.requestId = options.panelId + target.refId;
query.instant = target.instant;
var interval = this.templateSrv.replace(target.interval, options.scopedVars) || options.interval;
var intervalFactor = target.intervalFactor || 1;
target.step = query.step = this.calculateInterval(interval, intervalFactor);
var range = Math.ceil(end - start);
target.step = query.step = this.adjustStep(query.step, this.intervalSeconds(options.interval), range);
queries.push(query);
} }
// No valid targets, return the empty result to save a round trip. // No valid targets, return the empty result to save a round trip.
...@@ -147,13 +134,41 @@ export class PrometheusDatasource { ...@@ -147,13 +134,41 @@ export class PrometheusDatasource {
}); });
} }
adjustStep(step, autoStep, range) { createQuery(target, options, range) {
// Prometheus drop query if range/step > 11000 var query: any = {};
// calibrate step if it is too big query.instant = target.instant;
if (step !== 0 && range / step > 11000) {
step = Math.ceil(range / 11000); var interval = kbn.interval_to_seconds(options.interval);
// Minimum interval ("Min step"), if specified for the query. or same as interval otherwise
var minInterval = kbn.interval_to_seconds(this.templateSrv.replace(target.interval, options.scopedVars) || options.interval);
var intervalFactor = target.intervalFactor || 1;
// Adjust the interval to take into account any specified minimum and interval factor plus Prometheus limits
var adjustedInterval = this.adjustInterval(interval, minInterval, range, intervalFactor);
var scopedVars = options.scopedVars;
// If the interval was adjusted, make a shallow copy of scopedVars with updated interval vars
if (interval !== adjustedInterval) {
interval = adjustedInterval;
scopedVars = Object.assign({}, options.scopedVars, {
"__interval": {text: interval + "s", value: interval + "s"},
"__interval_ms": {text: interval * 1000, value: interval * 1000},
});
}
target.step = query.step = interval;
// Only replace vars in expression after having (possibly) updated interval vars
query.expr = this.templateSrv.replace(target.expr, scopedVars, this.interpolateQueryExpr);
query.requestId = options.panelId + target.refId;
return query;
}
adjustInterval(interval, minInterval, range, intervalFactor) {
// Prometheus will drop queries that might return more than 11000 data points.
// Calibrate interval if it is too small.
if (interval !== 0 && range / intervalFactor / interval > 11000) {
interval = Math.ceil(range / intervalFactor / 11000);
} }
return Math.max(step, autoStep); return Math.max(interval * intervalFactor, minInterval);
} }
performTimeSeriesQuery(query, start, end) { performTimeSeriesQuery(query, start, end) {
...@@ -218,7 +233,7 @@ export class PrometheusDatasource { ...@@ -218,7 +233,7 @@ export class PrometheusDatasource {
var end = this.getPrometheusTime(options.range.to, true); var end = this.getPrometheusTime(options.range.to, true);
var query = { var query = {
expr: interpolated, expr: interpolated,
step: this.adjustStep(kbn.interval_to_seconds(step), 0, Math.ceil(end - start)) + 's' step: this.adjustInterval(kbn.interval_to_seconds(step), 0, Math.ceil(end - start), 1) + 's'
}; };
var self = this; var self = this;
...@@ -257,21 +272,6 @@ export class PrometheusDatasource { ...@@ -257,21 +272,6 @@ export class PrometheusDatasource {
}); });
} }
calculateInterval(interval, intervalFactor) {
return Math.ceil(this.intervalSeconds(interval) * intervalFactor);
}
intervalSeconds(interval) {
var m = interval.match(durationSplitRegexp);
var dur = moment.duration(parseInt(m[1]), m[2]);
var sec = dur.asSeconds();
if (sec < 1) {
sec = 1;
}
return sec;
}
transformMetricData(md, options, start, end) { transformMetricData(md, options, start, end) {
var dps = [], var dps = [],
metricLabel = null; metricLabel = null;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment