app/vmselect/promql: add label_value(q, label_name) func, which returns numeric value labels with name label_name in q

This commit is contained in:
Aliaksandr Valialkin 2019-08-20 00:28:24 +03:00
parent 4f738c8a15
commit d3fd113a80
2 changed files with 64 additions and 0 deletions

View file

@ -1302,6 +1302,44 @@ func TestExecSuccess(t *testing.T) {
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`label_value()`, func(t *testing.T) {
t.Parallel()
q := `with (
x = (
label_set(time(), "foo", "123.456", "__name__", "aaa"),
label_set(-time(), "foo", "bar", "__name__", "bbb"),
label_set(-time(), "__name__", "bxs"),
label_set(-time(), "foo", "45", "bar", "xs"),
)
)
sort(x + label_value(x, "foo"))`
r1 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{-955, -1155, -1355, -1555, -1755, -1955},
Timestamps: timestampsExpected,
}
r1.MetricName.Tags = []storage.Tag{
{
Key: []byte("bar"),
Value: []byte("xs"),
},
{
Key: []byte("foo"),
Value: []byte("45"),
},
}
r2 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{1123.456, 1323.456, 1523.456, 1723.456, 1923.456, 2123.456},
Timestamps: timestampsExpected,
}
r2.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("123.456"),
}}
resultExpected := []netstorage.Result{r1, r2}
f(q, resultExpected)
})
t.Run(`label_transform(mismatch)`, func(t *testing.T) {
t.Parallel()
q := `label_transform(time(), "__name__", "foobar", "xx")`

View file

@ -63,6 +63,7 @@ var transformFuncs = map[string]transformFunc{
"label_copy": transformLabelCopy,
"label_move": transformLabelMove,
"label_transform": transformLabelTransform,
"label_value": transformLabelValue,
"union": transformUnion,
"": transformUnion, // empty func is a synonim to union
"keep_last_value": transformKeepLastValue,
@ -881,6 +882,31 @@ func labelReplace(tss []*timeseries, srcLabel string, r *regexp.Regexp, dstLabel
return tss, nil
}
func transformLabelValue(tfa *transformFuncArg) ([]*timeseries, error) {
args := tfa.args
if err := expectTransformArgsNum(args, 2); err != nil {
return nil, err
}
labelName, err := getString(args[1], 1)
if err != nil {
return nil, fmt.Errorf("cannot get label name: %s", err)
}
rvs := args[0]
for _, ts := range rvs {
ts.MetricName.ResetMetricGroup()
labelValue := ts.MetricName.GetTagValue(labelName)
v, err := strconv.ParseFloat(string(labelValue), 64)
if err != nil {
v = nan
}
values := ts.Values
for i := range values {
values[i] = v
}
}
return rvs, nil
}
func transformLn(v float64) float64 {
return math.Log(v)
}