Add quantile_over_time function

This commit is contained in:
Brian Brazil 2016-07-08 13:22:22 +01:00
parent 08891beb5f
commit b0342ba9ec
2 changed files with 96 additions and 2 deletions

View file

@ -478,6 +478,51 @@ func funcSumOverTime(ev *evaluator, args Expressions) model.Value {
})
}
// === quantile_over_time(matrix model.ValMatrix) Vector ===
func funcQuantileOverTime(ev *evaluator, args Expressions) model.Value {
q := ev.evalFloat(args[0])
mat := ev.evalMatrix(args[1])
resultVector := vector{}
for _, el := range mat {
if len(el.Values) == 0 {
continue
}
el.Metric.Del(model.MetricNameLabel)
var result float64
if q < 0 {
result = math.Inf(-1)
} else if q > 1 {
result = math.Inf(+1)
} else {
values := make([]float64, 0, len(el.Values))
for _, v := range el.Values {
values = append(values, float64(v.Value))
}
sort.Float64s(values)
n := float64(len(el.Values))
// When the quantile lies between two samples,
// we use a weighted average of the two samples.
rank := q * (n-1)
lowerIndex := math.Max(0, math.Floor(rank))
upperIndex := math.Min(n-1, lowerIndex+1)
weight := rank - math.Floor(rank)
result = values[int(lowerIndex)] * (1 - weight) + values[int(upperIndex)] * weight
}
resultVector = append(resultVector, &sample{
Metric: el.Metric,
Value: model.SampleValue(result),
Timestamp: ev.Timestamp,
})
}
return resultVector
}
// === stddev_over_time(matrix model.ValMatrix) Vector ===
func funcStddevOverTime(ev *evaluator, args Expressions) model.Value {
return aggrOverTime(ev, args, func(values []model.SamplePair) model.SampleValue {
@ -504,7 +549,7 @@ func funcStdvarOverTime(ev *evaluator, args Expressions) model.Value {
avg := sum / count
return squaredSum/count - avg*avg
})
}
// === abs(vector model.ValVector) Vector ===
func funcAbs(ev *evaluator, args Expressions) model.Value {
@ -973,6 +1018,12 @@ var functions = map[string]*Function{
ReturnType: model.ValVector,
Call: funcPredictLinear,
},
"quantile_over_time": {
Name: "quantile_over_time",
ArgTypes: []model.ValueType{model.ValScalar, model.ValMatrix},
ReturnType: model.ValVector,
Call: funcQuantileOverTime,
},
"rate": {
Name: "rate",
ArgTypes: []model.ValueType{model.ValMatrix},

View file

@ -276,7 +276,6 @@ eval instant at 8000s holt_winters(http_requests[1m], 0.01, 0.1)
{job="api-server", instance="0", group="canary"} 24000
{job="api-server", instance="1", group="canary"} -32000
# Tests for stddev_over_time and stdvar_over_time.
clear
load 10s
@ -287,3 +286,47 @@ eval instant at 1m stdvar_over_time(metric[1m])
eval instant at 1m stddev_over_time(metric[1m])
{} 3.249615
# Tests for quantile_over_time
clear
load 10s
data{test="two samples"} 0 1
data{test="three samples"} 0 1 2
data{test="uneven samples"} 0 1 4
eval instant at 1m quantile_over_time(0, data[1m])
{test="two samples"} 0
{test="three samples"} 0
{test="uneven samples"} 0
eval instant at 1m quantile_over_time(0.5, data[1m])
{test="two samples"} 0.5
{test="three samples"} 1
{test="uneven samples"} 1
eval instant at 1m quantile_over_time(0.75, data[1m])
{test="two samples"} 0.75
{test="three samples"} 1.5
{test="uneven samples"} 2.5
eval instant at 1m quantile_over_time(0.8, data[1m])
{test="two samples"} 0.8
{test="three samples"} 1.6
{test="uneven samples"} 2.8
eval instant at 1m quantile_over_time(1, data[1m])
{test="two samples"} 1
{test="three samples"} 2
{test="uneven samples"} 4
eval instant at 1m quantile_over_time(-1, data[1m])
{test="two samples"} -Inf
{test="three samples"} -Inf
{test="uneven samples"} -Inf
eval instant at 1m quantile_over_time(2, data[1m])
{test="two samples"} +Inf
{test="three samples"} +Inf
{test="uneven samples"} +Inf
>>>>>>> Add quantile_over_time function