Merge pull request #276 from prometheus/fix/delta-noncounter-resets

Fix handling of negative deltas for non-counter values.
This commit is contained in:
juliusv 2013-05-29 02:26:20 -07:00
commit d828b9c835
3 changed files with 30 additions and 11 deletions

View file

@ -72,14 +72,14 @@ func timeImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
// === delta(matrix MatrixNode, isCounter ScalarNode) Vector ===
func deltaImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
matrixNode := args[0].(MatrixNode)
isCounter := int(args[1].(ScalarNode).Eval(timestamp, view))
isCounter := args[1].(ScalarNode).Eval(timestamp, view) > 0
resultVector := Vector{}
// If we treat these metrics as counters, we need to fetch all values
// in the interval to find breaks in the timeseries' monotonicity.
// I.e. if a counter resets, we want to ignore that reset.
var matrixValue Matrix
if isCounter > 0 {
if isCounter {
matrixValue = matrixNode.Eval(timestamp, view)
} else {
matrixValue = matrixNode.EvalBoundaries(timestamp, view)
@ -95,7 +95,7 @@ func deltaImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{}
lastValue := model.SampleValue(0)
for _, sample := range samples.Values {
currentValue := sample.Value
if currentValue < lastValue {
if isCounter && currentValue < lastValue {
counterCorrection += lastValue - currentValue
}
lastValue = currentValue

View file

@ -145,13 +145,20 @@ var testMatrix = ast.Matrix{
},
Values: getTestValueStream(0, 100, 10, testStartTime),
},
// Counter resets.
// Counter reset in the middle of range.
{
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))...),
},
// 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)

View file

@ -319,15 +319,27 @@ func TestExpressions(t *testing.T) {
fullRanges: 1,
intervalRanges: 0,
}, {
// Counter resets are ignored by delta() if counter == 1.
expr: "delta(testcounter[50m], 1)",
output: []string{"testcounter{} => 90 @[%v]"},
// Counter resets in middle of range are ignored by delta() if counter == 1.
expr: "delta(testcounter_reset_middle[50m], 1)",
output: []string{"testcounter_reset_middle{} => 90 @[%v]"},
fullRanges: 1,
intervalRanges: 0,
}, {
// Counter resets are not ignored by delta() if counter == 0.
expr: "delta(testcounter[50m], 0)",
output: []string{"testcounter{} => 50 @[%v]"},
// Counter resets in middle of range are not ignored by delta() if counter == 0.
expr: "delta(testcounter_reset_middle[50m], 0)",
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,
intervalRanges: 0,
}, {