mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-25 21:54:10 -08:00
Merge pull request #641 from prometheus/stddev
Add stddev and stdvar aggregation functions.
This commit is contained in:
commit
e681a57d73
|
@ -68,6 +68,7 @@ type Matrix []SampleStream
|
|||
type groupedAggregation struct {
|
||||
labels clientmodel.COWMetric
|
||||
value clientmodel.SampleValue
|
||||
valuesSquaredSum clientmodel.SampleValue
|
||||
groupCount int
|
||||
}
|
||||
|
||||
|
@ -128,6 +129,8 @@ const (
|
|||
Min
|
||||
Max
|
||||
Count
|
||||
Stdvar
|
||||
Stddev
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -468,6 +471,12 @@ func (node *VectorAggregation) groupedAggregationsToVector(aggregations map[uint
|
|||
aggregation.value = aggregation.value / clientmodel.SampleValue(aggregation.groupCount)
|
||||
case Count:
|
||||
aggregation.value = clientmodel.SampleValue(aggregation.groupCount)
|
||||
case Stdvar:
|
||||
avg := float64(aggregation.value) / float64(aggregation.groupCount)
|
||||
aggregation.value = clientmodel.SampleValue(float64(aggregation.valuesSquaredSum)/float64(aggregation.groupCount) - avg*avg)
|
||||
case Stddev:
|
||||
avg := float64(aggregation.value) / float64(aggregation.groupCount)
|
||||
aggregation.value = clientmodel.SampleValue(math.Sqrt(float64(aggregation.valuesSquaredSum)/float64(aggregation.groupCount) - avg*avg))
|
||||
default:
|
||||
// For other aggregations, we already have the right value.
|
||||
}
|
||||
|
@ -509,6 +518,10 @@ func (node *VectorAggregation) Eval(timestamp clientmodel.Timestamp) Vector {
|
|||
}
|
||||
case Count:
|
||||
groupedResult.groupCount++
|
||||
case Stdvar, Stddev:
|
||||
groupedResult.value += sample.Value
|
||||
groupedResult.valuesSquaredSum += sample.Value * sample.Value
|
||||
groupedResult.groupCount++
|
||||
default:
|
||||
panic("Unknown aggregation type")
|
||||
}
|
||||
|
@ -531,6 +544,7 @@ func (node *VectorAggregation) Eval(timestamp clientmodel.Timestamp) Vector {
|
|||
result[groupingKey] = &groupedAggregation{
|
||||
labels: m,
|
||||
value: sample.Value,
|
||||
valuesSquaredSum: sample.Value * sample.Value,
|
||||
groupCount: 1,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,8 @@ func (aggrType AggrType) String() string {
|
|||
Min: "MIN",
|
||||
Max: "MAX",
|
||||
Count: "COUNT",
|
||||
Stdvar: "STDVAR",
|
||||
Stddev: "STDDEV",
|
||||
}
|
||||
return aggrTypeMap[aggrType]
|
||||
}
|
||||
|
|
|
@ -83,6 +83,8 @@ func NewVectorAggregation(aggrTypeStr string, vector ast.Node, groupBy clientmod
|
|||
"MIN": ast.Min,
|
||||
"AVG": ast.Avg,
|
||||
"COUNT": ast.Count,
|
||||
"STDVAR": ast.Stdvar,
|
||||
"STDDEV": ast.Stddev,
|
||||
}
|
||||
aggrType, ok := aggrTypes[aggrTypeStr]
|
||||
if !ok {
|
||||
|
|
|
@ -89,8 +89,8 @@ GROUP_LEFT|GROUP_RIGHT lval.str = lexer.token(); return MATCH_MOD
|
|||
group_left|group_right lval.str = strings.ToUpper(lexer.token()); return MATCH_MOD
|
||||
KEEPING_EXTRA|keeping_extra return KEEPING_EXTRA
|
||||
OFFSET|offset return OFFSET
|
||||
AVG|SUM|MAX|MIN|COUNT lval.str = lexer.token(); return AGGR_OP
|
||||
avg|sum|max|min|count lval.str = strings.ToUpper(lexer.token()); return AGGR_OP
|
||||
AVG|SUM|MAX|MIN|COUNT|STDVAR|STDDEV lval.str = lexer.token(); return AGGR_OP
|
||||
avg|sum|max|min|count|stdvar|stddev lval.str = strings.ToUpper(lexer.token()); return AGGR_OP
|
||||
\<|>|AND|OR|and|or lval.str = strings.ToUpper(lexer.token()); return CMP_OP
|
||||
==|!=|>=|<=|=~|!~ lval.str = lexer.token(); return CMP_OP
|
||||
[+\-] lval.str = lexer.token(); return ADDITIVE_OP
|
||||
|
|
1216
rules/lexer.l.go
1216
rules/lexer.l.go
File diff suppressed because it is too large
Load diff
|
@ -1295,6 +1295,32 @@ func TestExpressions(t *testing.T) {
|
|||
`{l="y"} => -Inf @[%v]`,
|
||||
},
|
||||
},
|
||||
{
|
||||
expr: `stddev(http_requests)`,
|
||||
output: []string{
|
||||
`{} => 229.12878474779 @[%v]`,
|
||||
},
|
||||
},
|
||||
{
|
||||
expr: `stddev by (instance)(http_requests)`,
|
||||
output: []string{
|
||||
`{instance="0"} => 223.60679774998 @[%v]`,
|
||||
`{instance="1"} => 223.60679774998 @[%v]`,
|
||||
},
|
||||
},
|
||||
{
|
||||
expr: `stdvar(http_requests)`,
|
||||
output: []string{
|
||||
`{} => 52500 @[%v]`,
|
||||
},
|
||||
},
|
||||
{
|
||||
expr: `stdvar by (instance)(http_requests)`,
|
||||
output: []string{
|
||||
`{instance="0"} => 50000 @[%v]`,
|
||||
`{instance="1"} => 50000 @[%v]`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
storage, closer := newTestStorage(t)
|
||||
|
|
|
@ -219,7 +219,7 @@ func NewTemplateExpander(text string, name string, data interface{}, timestamp c
|
|||
return fmt.Sprintf("%.4g%ss", v, prefix)
|
||||
},
|
||||
"pathPrefix": func() string {
|
||||
return pathPrefix;
|
||||
return pathPrefix
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue