Skip to content

Commit

Permalink
Allow to aggregate binary operations. (#1970)
Browse files Browse the repository at this point in the history
* Allow to aggregate binary operations.

For example:
	`sum by (job) (count_over_time({namespace="tns"}[5m] |= "level=error") / count_over_time({namespace="tns"}[5m]))`

would have failed previously.

Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com>

* Add missing () rules in yacc.

Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com>
  • Loading branch information
cyriltovena authored Apr 29, 2020
1 parent 989fb10 commit dc5cf8f
Show file tree
Hide file tree
Showing 5 changed files with 355 additions and 185 deletions.
5 changes: 5 additions & 0 deletions pkg/logql/ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ func Test_SampleExpr_String(t *testing.T) {
sum by (cluster) (count_over_time({job="postgres"}[5m]))
`,
`sum by (cluster) (count_over_time({job="mysql"}[5m])) / min(count_over_time({job="mysql"}[5m])) `,
`sum by (job) (
count_over_time({namespace="tns"} |= "level=error"[5m])
/
count_over_time({namespace="tns"}[5m])
)`,
} {
t.Run(tc, func(t *testing.T) {
expr, err := ParseExpr(tc)
Expand Down
52 changes: 52 additions & 0 deletions pkg/logql/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,58 @@ func TestEngine_NewRangeQuery(t *testing.T) {
},
},
},
{
`avg by (app) (
sum by (app) (rate({app=~"foo|bar"} |~".+bar" [1m])) +
sum by (app) (rate({app=~"foo|bar"} |~".+bar" [1m])) /
sum by (app) (rate({app=~"foo|bar"} |~".+bar" [1m]))
) * 2
`,
time.Unix(60, 0), time.Unix(180, 0), 30 * time.Second, logproto.FORWARD, 100,
[][]*logproto.Stream{
{
newStream(testSize, factor(5, identity), `{app="foo"}`),
newStream(testSize, factor(5, identity), `{app="bar"}`),
},
},
[]SelectParams{
{&logproto.QueryRequest{Direction: logproto.FORWARD, Start: time.Unix(0, 0), End: time.Unix(180, 0), Limit: 0, Selector: `{app=~"foo|bar"}|~".+bar"`}},
},
promql.Matrix{
promql.Series{
Metric: labels.Labels{{Name: "app", Value: "bar"}},
Points: []promql.Point{{T: 60 * 1000, V: 2.4}, {T: 90 * 1000, V: 2.4}, {T: 120 * 1000, V: 2.4}, {T: 150 * 1000, V: 2.4}, {T: 180 * 1000, V: 2.4}},
},
promql.Series{
Metric: labels.Labels{{Name: "app", Value: "foo"}},
Points: []promql.Point{{T: 60 * 1000, V: 2.4}, {T: 90 * 1000, V: 2.4}, {T: 120 * 1000, V: 2.4}, {T: 150 * 1000, V: 2.4}, {T: 180 * 1000, V: 2.4}},
},
},
},
{
` sum (
sum by (app) (rate({app=~"foo|bar"} |~".+bar" [1m])) +
sum by (app) (rate({app=~"foo|bar"} |~".+bar" [1m])) /
sum by (app) (rate({app=~"foo|bar"} |~".+bar" [1m]))
) + 1
`,
time.Unix(60, 0), time.Unix(180, 0), 30 * time.Second, logproto.FORWARD, 100,
[][]*logproto.Stream{
{
newStream(testSize, factor(5, identity), `{app="foo"}`),
newStream(testSize, factor(5, identity), `{app="bar"}`),
},
},
[]SelectParams{
{&logproto.QueryRequest{Direction: logproto.FORWARD, Start: time.Unix(0, 0), End: time.Unix(180, 0), Limit: 0, Selector: `{app=~"foo|bar"}|~".+bar"`}},
},
promql.Matrix{
promql.Series{
Metric: labels.Labels{},
Points: []promql.Point{{T: 60 * 1000, V: 3.4}, {T: 90 * 1000, V: 3.4}, {T: 120 * 1000, V: 3.4}, {T: 150 * 1000, V: 3.4}, {T: 180 * 1000, V: 3.4}},
},
},
},
{
`1+1--1`,
time.Unix(60, 0), time.Unix(180, 0), 30 * time.Second, 0, logproto.FORWARD, 100,
Expand Down
34 changes: 19 additions & 15 deletions pkg/logql/expr.y
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
RangeOp string
Selector []*labels.Matcher
VectorAggregationExpr SampleExpr
MetricExpr SampleExpr
VectorOp string
BinOpExpr SampleExpr
binOp string
Expand All @@ -35,6 +36,7 @@ import (
%type <Grouping> grouping
%type <Labels> labels
%type <LogExpr> logExpr
%type <MetricExpr> metricExpr
%type <LogRangeExpr> logRangeExpr
%type <Matcher> matcher
%type <Matchers> matchers
Expand Down Expand Up @@ -64,11 +66,15 @@ root: expr { exprlex.(*lexer).expr = $1 };

expr:
logExpr { $$ = $1 }
| rangeAggregationExpr { $$ = $1 }
| vectorAggregationExpr { $$ = $1 }
| binOpExpr { $$ = $1 }
| literalExpr { $$ = $1 }
| OPEN_PARENTHESIS expr CLOSE_PARENTHESIS { $$ = $2 }
| metricExpr { $$ = $1 }
;

metricExpr:
rangeAggregationExpr { $$ = $1 }
| vectorAggregationExpr { $$ = $1 }
| binOpExpr { $$ = $1 }
| literalExpr { $$ = $1 }
| OPEN_PARENTHESIS metricExpr CLOSE_PARENTHESIS { $$ = $2 }
;

logExpr:
Expand All @@ -91,17 +97,12 @@ rangeAggregationExpr: rangeOp OPEN_PARENTHESIS logRangeExpr CLOSE_PARENTHESIS {

vectorAggregationExpr:
// Aggregations with 1 argument.
vectorOp OPEN_PARENTHESIS rangeAggregationExpr CLOSE_PARENTHESIS { $$ = mustNewVectorAggregationExpr($3, $1, nil, nil) }
| vectorOp OPEN_PARENTHESIS vectorAggregationExpr CLOSE_PARENTHESIS { $$ = mustNewVectorAggregationExpr($3, $1, nil, nil) }
| vectorOp grouping OPEN_PARENTHESIS rangeAggregationExpr CLOSE_PARENTHESIS { $$ = mustNewVectorAggregationExpr($4, $1, $2, nil,) }
| vectorOp grouping OPEN_PARENTHESIS vectorAggregationExpr CLOSE_PARENTHESIS { $$ = mustNewVectorAggregationExpr($4, $1, $2, nil,) }
| vectorOp OPEN_PARENTHESIS rangeAggregationExpr CLOSE_PARENTHESIS grouping { $$ = mustNewVectorAggregationExpr($3, $1, $5, nil) }
| vectorOp OPEN_PARENTHESIS vectorAggregationExpr CLOSE_PARENTHESIS grouping { $$ = mustNewVectorAggregationExpr($3, $1, $5, nil) }
vectorOp OPEN_PARENTHESIS metricExpr CLOSE_PARENTHESIS { $$ = mustNewVectorAggregationExpr($3, $1, nil, nil) }
| vectorOp grouping OPEN_PARENTHESIS metricExpr CLOSE_PARENTHESIS { $$ = mustNewVectorAggregationExpr($4, $1, $2, nil,) }
| vectorOp OPEN_PARENTHESIS metricExpr CLOSE_PARENTHESIS grouping { $$ = mustNewVectorAggregationExpr($3, $1, $5, nil) }
// Aggregations with 2 arguments.
| vectorOp OPEN_PARENTHESIS NUMBER COMMA vectorAggregationExpr CLOSE_PARENTHESIS { $$ = mustNewVectorAggregationExpr($5, $1, nil, &$3) }
| vectorOp OPEN_PARENTHESIS NUMBER COMMA vectorAggregationExpr CLOSE_PARENTHESIS grouping { $$ = mustNewVectorAggregationExpr($5, $1, $7, &$3) }
| vectorOp OPEN_PARENTHESIS NUMBER COMMA rangeAggregationExpr CLOSE_PARENTHESIS { $$ = mustNewVectorAggregationExpr($5, $1, nil, &$3) }
| vectorOp OPEN_PARENTHESIS NUMBER COMMA rangeAggregationExpr CLOSE_PARENTHESIS grouping { $$ = mustNewVectorAggregationExpr($5, $1, $7, &$3) }
| vectorOp OPEN_PARENTHESIS NUMBER COMMA metricExpr CLOSE_PARENTHESIS { $$ = mustNewVectorAggregationExpr($5, $1, nil, &$3) }
| vectorOp OPEN_PARENTHESIS NUMBER COMMA metricExpr CLOSE_PARENTHESIS grouping { $$ = mustNewVectorAggregationExpr($5, $1, $7, &$3) }
;

filter:
Expand Down Expand Up @@ -144,11 +145,13 @@ binOpExpr:
| expr DIV expr { $$ = mustNewBinOpExpr("/", $1, $3) }
| expr MOD expr { $$ = mustNewBinOpExpr("%", $1, $3) }
| expr POW expr { $$ = mustNewBinOpExpr("^", $1, $3) }
;

literalExpr:
NUMBER { $$ = mustNewLiteralExpr( $1, false ) }
| ADD NUMBER { $$ = mustNewLiteralExpr( $2, false ) }
| SUB NUMBER { $$ = mustNewLiteralExpr( $2, true ) }
;

vectorOp:
SUM { $$ = OpTypeSum }
Expand All @@ -165,6 +168,7 @@ vectorOp:
rangeOp:
COUNT_OVER_TIME { $$ = OpTypeCountOverTime }
| RATE { $$ = OpTypeRate }
;


labels:
Expand Down
Loading

0 comments on commit dc5cf8f

Please sign in to comment.