Fix handling of negative deltas for non-counter values.
This commit is contained in:
parent
a8468a2e5e
commit
138334fb31
|
@ -72,14 +72,14 @@ func timeImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
|
||||||
// === delta(matrix MatrixNode, isCounter ScalarNode) Vector ===
|
// === delta(matrix MatrixNode, isCounter ScalarNode) Vector ===
|
||||||
func deltaImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
|
func deltaImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
|
||||||
matrixNode := args[0].(MatrixNode)
|
matrixNode := args[0].(MatrixNode)
|
||||||
isCounter := int(args[1].(ScalarNode).Eval(timestamp, view))
|
isCounter := args[1].(ScalarNode).Eval(timestamp, view) > 0
|
||||||
resultVector := Vector{}
|
resultVector := Vector{}
|
||||||
|
|
||||||
// If we treat these metrics as counters, we need to fetch all values
|
// If we treat these metrics as counters, we need to fetch all values
|
||||||
// in the interval to find breaks in the timeseries' monotonicity.
|
// in the interval to find breaks in the timeseries' monotonicity.
|
||||||
// I.e. if a counter resets, we want to ignore that reset.
|
// I.e. if a counter resets, we want to ignore that reset.
|
||||||
var matrixValue Matrix
|
var matrixValue Matrix
|
||||||
if isCounter > 0 {
|
if isCounter {
|
||||||
matrixValue = matrixNode.Eval(timestamp, view)
|
matrixValue = matrixNode.Eval(timestamp, view)
|
||||||
} else {
|
} else {
|
||||||
matrixValue = matrixNode.EvalBoundaries(timestamp, view)
|
matrixValue = matrixNode.EvalBoundaries(timestamp, view)
|
||||||
|
@ -95,7 +95,7 @@ func deltaImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{}
|
||||||
lastValue := model.SampleValue(0)
|
lastValue := model.SampleValue(0)
|
||||||
for _, sample := range samples.Values {
|
for _, sample := range samples.Values {
|
||||||
currentValue := sample.Value
|
currentValue := sample.Value
|
||||||
if currentValue < lastValue {
|
if isCounter && currentValue < lastValue {
|
||||||
counterCorrection += lastValue - currentValue
|
counterCorrection += lastValue - currentValue
|
||||||
}
|
}
|
||||||
lastValue = currentValue
|
lastValue = currentValue
|
||||||
|
|
|
@ -145,13 +145,20 @@ var testMatrix = ast.Matrix{
|
||||||
},
|
},
|
||||||
Values: getTestValueStream(0, 100, 10, testStartTime),
|
Values: getTestValueStream(0, 100, 10, testStartTime),
|
||||||
},
|
},
|
||||||
// Counter resets.
|
// Counter reset in the middle of range.
|
||||||
{
|
{
|
||||||
Metric: model.Metric{
|
Metric: model.Metric{
|
||||||
model.MetricNameLabel: "testcounter",
|
model.MetricNameLabel: "testcounter_reset_middle",
|
||||||
},
|
},
|
||||||
Values: append(getTestValueStream(0, 40, 10, testStartTime), getTestValueStream(0, 50, 10, testStartTime.Add(testSampleInterval*5))...),
|
Values: append(getTestValueStream(0, 40, 10, testStartTime), getTestValueStream(0, 50, 10, testStartTime.Add(testSampleInterval*5))...),
|
||||||
},
|
},
|
||||||
|
// Counter reset at the end of range.
|
||||||
|
{
|
||||||
|
Metric: model.Metric{
|
||||||
|
model.MetricNameLabel: "testcounter_reset_end",
|
||||||
|
},
|
||||||
|
Values: append(getTestValueStream(0, 90, 10, testStartTime), getTestValueStream(0, 0, 10, testStartTime.Add(testSampleInterval*10))...),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var testVector = getTestVectorFromTestMatrix(testMatrix)
|
var testVector = getTestVectorFromTestMatrix(testMatrix)
|
||||||
|
|
|
@ -319,15 +319,27 @@ func TestExpressions(t *testing.T) {
|
||||||
fullRanges: 1,
|
fullRanges: 1,
|
||||||
intervalRanges: 0,
|
intervalRanges: 0,
|
||||||
}, {
|
}, {
|
||||||
// Counter resets are ignored by delta() if counter == 1.
|
// Counter resets in middle of range are ignored by delta() if counter == 1.
|
||||||
expr: "delta(testcounter[50m], 1)",
|
expr: "delta(testcounter_reset_middle[50m], 1)",
|
||||||
output: []string{"testcounter{} => 90 @[%v]"},
|
output: []string{"testcounter_reset_middle{} => 90 @[%v]"},
|
||||||
fullRanges: 1,
|
fullRanges: 1,
|
||||||
intervalRanges: 0,
|
intervalRanges: 0,
|
||||||
}, {
|
}, {
|
||||||
// Counter resets are not ignored by delta() if counter == 0.
|
// Counter resets in middle of range are not ignored by delta() if counter == 0.
|
||||||
expr: "delta(testcounter[50m], 0)",
|
expr: "delta(testcounter_reset_middle[50m], 0)",
|
||||||
output: []string{"testcounter{} => 50 @[%v]"},
|
output: []string{"testcounter_reset_middle{} => 50 @[%v]"},
|
||||||
|
fullRanges: 1,
|
||||||
|
intervalRanges: 0,
|
||||||
|
}, {
|
||||||
|
// Counter resets at end of range are ignored by delta() if counter == 1.
|
||||||
|
expr: "delta(testcounter_reset_end[5m], 1)",
|
||||||
|
output: []string{"testcounter_reset_end{} => 0 @[%v]"},
|
||||||
|
fullRanges: 1,
|
||||||
|
intervalRanges: 0,
|
||||||
|
}, {
|
||||||
|
// Counter resets at end of range are not ignored by delta() if counter == 0.
|
||||||
|
expr: "delta(testcounter_reset_end[5m], 0)",
|
||||||
|
output: []string{"testcounter_reset_end{} => -90 @[%v]"},
|
||||||
fullRanges: 1,
|
fullRanges: 1,
|
||||||
intervalRanges: 0,
|
intervalRanges: 0,
|
||||||
}, {
|
}, {
|
||||||
|
|
Loading…
Reference in New Issue