Add function to drop common labels in a vector.

This fixes https://github.com/prometheus/prometheus/issues/384.

Change-Id: I2973c4baeb8a4618ec3875fb11c6fcf5d111784b
This commit is contained in:
Julius Volz 2014-08-05 19:56:35 +02:00
parent f7cd18abdf
commit b65c5dd752
2 changed files with 53 additions and 0 deletions

View File

@ -246,6 +246,44 @@ func bottomkImpl(timestamp clientmodel.Timestamp, view *viewAdapter, args []Node
return Vector(bottomk) return Vector(bottomk)
} }
// === drop_common_labels(node VectorNode) Vector ===
func dropCommonLabelsImpl(timestamp clientmodel.Timestamp, view *viewAdapter, args []Node) interface{} {
vector := args[0].(VectorNode).Eval(timestamp, view)
if len(vector) < 1 {
return Vector{}
}
common := clientmodel.LabelSet{}
for k, v := range vector[0].Metric {
// TODO(julius): Revisit this when https://github.com/prometheus/prometheus/issues/380
// is implemented.
if k == clientmodel.MetricNameLabel {
continue
}
common[k] = v
}
for _, el := range vector[1:] {
for k, v := range common {
if el.Metric[k] != v {
// Deletion of map entries while iterating over them is safe.
// From http://golang.org/ref/spec#For_statements:
// "If map entries that have not yet been reached are deleted during
// iteration, the corresponding iteration values will not be produced."
delete(common, k)
}
}
}
for _, el := range vector {
for k, _ := range el.Metric {
if _, ok := common[k]; ok {
delete(el.Metric, k)
}
}
}
return vector
}
// === sampleVectorImpl() Vector === // === sampleVectorImpl() Vector ===
func sampleVectorImpl(timestamp clientmodel.Timestamp, view *viewAdapter, args []Node) interface{} { func sampleVectorImpl(timestamp clientmodel.Timestamp, view *viewAdapter, args []Node) interface{} {
return Vector{ return Vector{
@ -450,6 +488,12 @@ var functions = map[string]*Function{
returnType: VECTOR, returnType: VECTOR,
callFn: deltaImpl, callFn: deltaImpl,
}, },
"drop_common_labels": {
name: "drop_common_labels",
argTypes: []ExprType{VECTOR},
returnType: VECTOR,
callFn: dropCommonLabelsImpl,
},
"max_over_time": { "max_over_time": {
name: "max_over_time", name: "max_over_time",
argTypes: []ExprType{MATRIX}, argTypes: []ExprType{MATRIX},

View File

@ -540,6 +540,15 @@ func TestExpressions(t *testing.T) {
fullRanges: 0, fullRanges: 0,
intervalRanges: 0, intervalRanges: 0,
}, },
{
expr: `drop_common_labels(http_requests{group="production",job="api-server"})`,
output: []string{
`http_requests{instance="0"} => 100 @[%v]`,
`http_requests{instance="1"} => 200 @[%v]`,
},
fullRanges: 0,
intervalRanges: 2,
},
} }
tieredStorage, closer := newTestStorage(t) tieredStorage, closer := newTestStorage(t)