Change prometheus semantics from step to min step (#8073)

Previously `Step` parameter would set a hard value for any zoom level.

Now it's renamed to `Min step` and sets the minimal value of `step` parameter
to Prometheus query. User would usually want to set it to the scraping interval
of the target metric to avoid having shap cliffs on graphs and extra load
on Prometheus. Actual `step` value is calculated as the minimum of automatically
selected step (based on zoom level) and user provided minimal step. If user
did not provide the step, then automatic value is used as is.

Example bahavior for `60s` scrape intervals:

* `5s` automatic interval, no user specified min step:
  * Before: `step=5`
  * After: `step=5`
* `5s` automatic interval, `1m` user specified min step:
  * Before: `step=5`
  * After: `step=60`
* `5m` automatic interval, `1m` user specified min step:
  * Before: `step=60` (not really visible, too dense)
  * After: `step=300` (automatic value is picked)

See:

* https://github.com/grafana/grafana/issues/8065
* https://github.com/prometheus/prometheus/issues/2564
This commit is contained in:
Ivan Babrou 2017-04-14 05:51:22 -07:00 committed by Torkel Ödegaard
parent 3a607f96a3
commit fb163450a5
3 changed files with 11 additions and 6 deletions

View File

@ -13,6 +13,7 @@
## Minor Enchancements ## Minor Enchancements
* **Prometheus**: Make Prometheus query field a textarea [#7663](https://github.com/grafana/grafana/issues/7663), thx [@hagen1778](https://github.com/hagen1778) * **Prometheus**: Make Prometheus query field a textarea [#7663](https://github.com/grafana/grafana/issues/7663), thx [@hagen1778](https://github.com/hagen1778)
* **Prometheus**: Step parameter changed semantics to min step to reduce the load on Prometheus and rendering in browser [#8073](https://github.com/grafana/grafana/pull/8073), thx [@bobrik](https://github.com/bobrik)
* **Templating**: Should not be possible to create self-referencing (recursive) template variable definitions [#7614](https://github.com/grafana/grafana/issues/7614) thx [@thuck](https://github.com/thuck) * **Templating**: Should not be possible to create self-referencing (recursive) template variable definitions [#7614](https://github.com/grafana/grafana/issues/7614) thx [@thuck](https://github.com/thuck)
* **Cloudwatch**: Correctly obtain IAM roles within ECS container tasks [#7892](https://github.com/grafana/grafana/issues/7892) thx [@gomlgs](https://github.com/gomlgs) * **Cloudwatch**: Correctly obtain IAM roles within ECS container tasks [#7892](https://github.com/grafana/grafana/issues/7892) thx [@gomlgs](https://github.com/gomlgs)
* **Units**: New number format: Scientific notation [#7781](https://github.com/grafana/grafana/issues/7781) thx [@cadnce](https://github.com/cadnce) * **Units**: New number format: Scientific notation [#7781](https://github.com/grafana/grafana/issues/7781) thx [@cadnce](https://github.com/cadnce)

View File

@ -89,7 +89,7 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
var intervalFactor = target.intervalFactor || 1; var intervalFactor = target.intervalFactor || 1;
target.step = query.step = this.calculateInterval(interval, intervalFactor); target.step = query.step = this.calculateInterval(interval, intervalFactor);
var range = Math.ceil(end - start); var range = Math.ceil(end - start);
target.step = query.step = this.adjustStep(query.step, range); target.step = query.step = this.adjustStep(query.step, this.intervalSeconds(options.interval), range);
queries.push(query); queries.push(query);
}); });
@ -122,13 +122,13 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
}); });
}; };
this.adjustStep = function(step, range) { this.adjustStep = function(step, autoStep, range) {
// Prometheus drop query if range/step > 11000 // Prometheus drop query if range/step > 11000
// calibrate step if it is too big // calibrate step if it is too big
if (step !== 0 && range / step > 11000) { if (step !== 0 && range / step > 11000) {
return Math.ceil(range / 11000); return Math.ceil(range / 11000);
} }
return step; return Math.max(step, autoStep);
}; };
this.performTimeSeriesQuery = function(query, start, end) { this.performTimeSeriesQuery = function(query, start, end) {
@ -189,7 +189,7 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
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), Math.ceil(end - start)) + 's' step: this.adjustStep(kbn.interval_to_seconds(step), 0, Math.ceil(end - start)) + 's'
}; };
var self = this; var self = this;
@ -229,6 +229,10 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
}; };
this.calculateInterval = function(interval, intervalFactor) { this.calculateInterval = function(interval, intervalFactor) {
return Math.ceil(this.intervalSeconds(interval) * intervalFactor);
};
this.intervalSeconds = function(interval) {
var m = interval.match(durationSplitRegexp); var m = interval.match(durationSplitRegexp);
var dur = moment.duration(parseInt(m[1]), m[2]); var dur = moment.duration(parseInt(m[1]), m[2]);
var sec = dur.asSeconds(); var sec = dur.asSeconds();
@ -236,7 +240,7 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
sec = 1; sec = 1;
} }
return Math.ceil(sec * intervalFactor); return sec;
}; };
this.transformMetricData = function(md, options, start, end) { this.transformMetricData = function(md, options, start, end) {

View File

@ -14,7 +14,7 @@
</input> </input>
</div> </div>
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label width-5">Step</label> <label class="gf-form-label">Min step</label>
<input type="text" class="gf-form-input max-width-5" ng-model="ctrl.target.interval" <input type="text" class="gf-form-input max-width-5" ng-model="ctrl.target.interval"
data-placement="right" data-placement="right"
spellcheck='false' spellcheck='false'