mirror of
https://github.com/prometheus/prometheus
synced 2024-12-28 09:42:22 +00:00
Merge pull request #13725 from prometheus/beorn7/promql2
promql: Fix limiting of extrapolation to negative values
This commit is contained in:
commit
b0c0961f9d
@ -128,20 +128,6 @@ func extrapolatedRate(vals []parser.Value, args parser.Expressions, enh *EvalNod
|
||||
sampledInterval := float64(lastT-firstT) / 1000
|
||||
averageDurationBetweenSamples := sampledInterval / float64(numSamplesMinusOne)
|
||||
|
||||
// TODO(beorn7): Do this for histograms, too.
|
||||
if isCounter && resultFloat > 0 && len(samples.Floats) > 0 && samples.Floats[0].F >= 0 {
|
||||
// Counters cannot be negative. If we have any slope at all
|
||||
// (i.e. resultFloat went up), we can extrapolate the zero point
|
||||
// of the counter. If the duration to the zero point is shorter
|
||||
// than the durationToStart, we take the zero point as the start
|
||||
// of the series, thereby avoiding extrapolation to negative
|
||||
// counter values.
|
||||
durationToZero := sampledInterval * (samples.Floats[0].F / resultFloat)
|
||||
if durationToZero < durationToStart {
|
||||
durationToStart = durationToZero
|
||||
}
|
||||
}
|
||||
|
||||
// If the first/last samples are close to the boundaries of the range,
|
||||
// extrapolate the result. This is as we expect that another sample
|
||||
// will exist given the spacing between samples we've seen thus far,
|
||||
@ -149,16 +135,29 @@ func extrapolatedRate(vals []parser.Value, args parser.Expressions, enh *EvalNod
|
||||
extrapolationThreshold := averageDurationBetweenSamples * 1.1
|
||||
extrapolateToInterval := sampledInterval
|
||||
|
||||
if durationToStart < extrapolationThreshold {
|
||||
if durationToStart >= extrapolationThreshold {
|
||||
durationToStart = averageDurationBetweenSamples / 2
|
||||
}
|
||||
if isCounter && resultFloat > 0 && len(samples.Floats) > 0 && samples.Floats[0].F >= 0 {
|
||||
// Counters cannot be negative. If we have any slope at all
|
||||
// (i.e. resultFloat went up), we can extrapolate the zero point
|
||||
// of the counter. If the duration to the zero point is shorter
|
||||
// than the durationToStart, we take the zero point as the start
|
||||
// of the series, thereby avoiding extrapolation to negative
|
||||
// counter values.
|
||||
// TODO(beorn7): Do this for histograms, too.
|
||||
durationToZero := sampledInterval * (samples.Floats[0].F / resultFloat)
|
||||
if durationToZero < durationToStart {
|
||||
durationToStart = durationToZero
|
||||
}
|
||||
}
|
||||
extrapolateToInterval += durationToStart
|
||||
} else {
|
||||
extrapolateToInterval += averageDurationBetweenSamples / 2
|
||||
|
||||
if durationToEnd >= extrapolationThreshold {
|
||||
durationToEnd = averageDurationBetweenSamples / 2
|
||||
}
|
||||
if durationToEnd < extrapolationThreshold {
|
||||
extrapolateToInterval += durationToEnd
|
||||
} else {
|
||||
extrapolateToInterval += averageDurationBetweenSamples / 2
|
||||
}
|
||||
|
||||
factor := extrapolateToInterval / sampledInterval
|
||||
if isRate {
|
||||
factor /= ms.Range.Seconds()
|
||||
|
21
promql/testdata/functions.test
vendored
21
promql/testdata/functions.test
vendored
@ -71,15 +71,28 @@ clear
|
||||
load 5m
|
||||
http_requests{path="/foo"} 0+10x10
|
||||
http_requests{path="/bar"} 0+10x5 0+10x5
|
||||
http_requests{path="/dings"} 10+10x10
|
||||
http_requests{path="/bumms"} 1+10x10
|
||||
|
||||
# Tests for increase().
|
||||
eval instant at 50m increase(http_requests[50m])
|
||||
{path="/foo"} 100
|
||||
{path="/bar"} 90
|
||||
{path="/dings"} 100
|
||||
{path="/bumms"} 100
|
||||
|
||||
# "foo" and "bar" are already at value 0 at t=0, so no extrapolation
|
||||
# happens. "dings" has value 10 at t=0 and would reach 0 at t=-5m. The
|
||||
# normal extrapolation by half a sample interval only goes to
|
||||
# t=-2m30s, so that's not yet reaching a negative value and therefore
|
||||
# chosen. However, "bumms" has value 1 at t=0 and would reach 0 at
|
||||
# t=-30s. Here the extrapolation to t=-2m30s would reach a negative
|
||||
# value, and therefore the extrapolation happens only by 30s.
|
||||
eval instant at 50m increase(http_requests[100m])
|
||||
{path="/foo"} 100
|
||||
{path="/bar"} 90
|
||||
{path="/dings"} 105
|
||||
{path="/bumms"} 101
|
||||
|
||||
clear
|
||||
|
||||
@ -133,13 +146,15 @@ load 4m
|
||||
testcounter_zero_cutoff{start="4m"} 240+240x10
|
||||
testcounter_zero_cutoff{start="5m"} 300+240x10
|
||||
|
||||
# Zero cutoff for left-side extrapolation.
|
||||
# Zero cutoff for left-side extrapolation happens until we
|
||||
# reach half a sampling interval (2m). Beyond that, we only
|
||||
# extrapolate by half a sampling interval.
|
||||
eval instant at 10m rate(testcounter_zero_cutoff[20m])
|
||||
{start="0m"} 0.5
|
||||
{start="1m"} 0.55
|
||||
{start="2m"} 0.6
|
||||
{start="3m"} 0.65
|
||||
{start="4m"} 0.7
|
||||
{start="3m"} 0.6
|
||||
{start="4m"} 0.6
|
||||
{start="5m"} 0.6
|
||||
|
||||
# Normal half-interval cutoff for left-side extrapolation.
|
||||
|
Loading…
Reference in New Issue
Block a user