mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-26 06:04:05 -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 {
|
type groupedAggregation struct {
|
||||||
labels clientmodel.COWMetric
|
labels clientmodel.COWMetric
|
||||||
value clientmodel.SampleValue
|
value clientmodel.SampleValue
|
||||||
|
valuesSquaredSum clientmodel.SampleValue
|
||||||
groupCount int
|
groupCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +129,8 @@ const (
|
||||||
Min
|
Min
|
||||||
Max
|
Max
|
||||||
Count
|
Count
|
||||||
|
Stdvar
|
||||||
|
Stddev
|
||||||
)
|
)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -468,6 +471,12 @@ func (node *VectorAggregation) groupedAggregationsToVector(aggregations map[uint
|
||||||
aggregation.value = aggregation.value / clientmodel.SampleValue(aggregation.groupCount)
|
aggregation.value = aggregation.value / clientmodel.SampleValue(aggregation.groupCount)
|
||||||
case Count:
|
case Count:
|
||||||
aggregation.value = clientmodel.SampleValue(aggregation.groupCount)
|
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:
|
default:
|
||||||
// For other aggregations, we already have the right value.
|
// For other aggregations, we already have the right value.
|
||||||
}
|
}
|
||||||
|
@ -509,6 +518,10 @@ func (node *VectorAggregation) Eval(timestamp clientmodel.Timestamp) Vector {
|
||||||
}
|
}
|
||||||
case Count:
|
case Count:
|
||||||
groupedResult.groupCount++
|
groupedResult.groupCount++
|
||||||
|
case Stdvar, Stddev:
|
||||||
|
groupedResult.value += sample.Value
|
||||||
|
groupedResult.valuesSquaredSum += sample.Value * sample.Value
|
||||||
|
groupedResult.groupCount++
|
||||||
default:
|
default:
|
||||||
panic("Unknown aggregation type")
|
panic("Unknown aggregation type")
|
||||||
}
|
}
|
||||||
|
@ -531,6 +544,7 @@ func (node *VectorAggregation) Eval(timestamp clientmodel.Timestamp) Vector {
|
||||||
result[groupingKey] = &groupedAggregation{
|
result[groupingKey] = &groupedAggregation{
|
||||||
labels: m,
|
labels: m,
|
||||||
value: sample.Value,
|
value: sample.Value,
|
||||||
|
valuesSquaredSum: sample.Value * sample.Value,
|
||||||
groupCount: 1,
|
groupCount: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,8 @@ func (aggrType AggrType) String() string {
|
||||||
Min: "MIN",
|
Min: "MIN",
|
||||||
Max: "MAX",
|
Max: "MAX",
|
||||||
Count: "COUNT",
|
Count: "COUNT",
|
||||||
|
Stdvar: "STDVAR",
|
||||||
|
Stddev: "STDDEV",
|
||||||
}
|
}
|
||||||
return aggrTypeMap[aggrType]
|
return aggrTypeMap[aggrType]
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,8 @@ func NewVectorAggregation(aggrTypeStr string, vector ast.Node, groupBy clientmod
|
||||||
"MIN": ast.Min,
|
"MIN": ast.Min,
|
||||||
"AVG": ast.Avg,
|
"AVG": ast.Avg,
|
||||||
"COUNT": ast.Count,
|
"COUNT": ast.Count,
|
||||||
|
"STDVAR": ast.Stdvar,
|
||||||
|
"STDDEV": ast.Stddev,
|
||||||
}
|
}
|
||||||
aggrType, ok := aggrTypes[aggrTypeStr]
|
aggrType, ok := aggrTypes[aggrTypeStr]
|
||||||
if !ok {
|
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
|
group_left|group_right lval.str = strings.ToUpper(lexer.token()); return MATCH_MOD
|
||||||
KEEPING_EXTRA|keeping_extra return KEEPING_EXTRA
|
KEEPING_EXTRA|keeping_extra return KEEPING_EXTRA
|
||||||
OFFSET|offset return OFFSET
|
OFFSET|offset return OFFSET
|
||||||
AVG|SUM|MAX|MIN|COUNT lval.str = lexer.token(); return AGGR_OP
|
AVG|SUM|MAX|MIN|COUNT|STDVAR|STDDEV 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 = strings.ToUpper(lexer.token()); return AGGR_OP
|
||||||
\<|>|AND|OR|and|or lval.str = strings.ToUpper(lexer.token()); return CMP_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 CMP_OP
|
||||||
[+\-] lval.str = lexer.token(); return ADDITIVE_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]`,
|
`{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)
|
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)
|
return fmt.Sprintf("%.4g%ss", v, prefix)
|
||||||
},
|
},
|
||||||
"pathPrefix": func() string {
|
"pathPrefix": func() string {
|
||||||
return pathPrefix;
|
return pathPrefix
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue