Skip to content

Commit

Permalink
Adds backtick for the quoted string token lexer. (#2095)
Browse files Browse the repository at this point in the history
* Fixes unit in stats request log. (#2093)

* Fix unit conversion in stats log.

🤦

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

* Fix the tests because you know ! you know ?

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

wip

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

* Add backtick for the quoted  string token lexer.

This allows to pass unescaped string to Loki.

For example we now support this :

`` {name="cassandra"} |~  `error=\w+` ``
`` {name!~`mysql-\d+`} ``

As you can see no escape is required when using ` quoted strings.

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

* Fixes newlines.

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

* Add back missing test.

Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com>
  • Loading branch information
cyriltovena authored May 19, 2020
1 parent c81be66 commit f9a2c43
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 17 deletions.
5 changes: 5 additions & 0 deletions docs/logql.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ the labels passed to the log stream selector will affect the relative
performance of the query's execution. The filter expression is then used to do a
distributed `grep` over the aggregated logs from the matching log streams.

> To avoid escaping special characters you can use the `` ` ``(back-tick) instead of `"` when quoting strings.
For example `` `\w+` `` is the same as `"\\w+"`, this is specially useful when writing regular expression which can contains many backslash that require escaping.

### Log Stream Selector

The log stream selector determines which log streams should be included in your
Expand Down Expand Up @@ -51,6 +54,7 @@ Examples:

- `{name=~"mysql.+"}`
- `{name!~"mysql.+"}`
- `` {name!~`mysql-\d+`} ``

The same rules that apply for [Prometheus Label
Selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#instant-vector-selectors)
Expand All @@ -64,6 +68,7 @@ regex:

- `{job="mysql"} |= "error"`
- `{name="kafka"} |~ "tsdb-ops.*io:2003"`
- `` {name="cassandra"} |~ `error=\w+` ``
- `{instance=~"kafka-[23]",name="kafka"} != kafka.server:type=ReplicaManager`

In the previous examples, `|=`, `|~`, and `!=` act as **filter operators** and
Expand Down
2 changes: 1 addition & 1 deletion pkg/logql/lex.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (l *lexer) Lex(lval *exprSymType) int {
lval.str = l.TokenText()
return NUMBER

case scanner.String:
case scanner.String, scanner.RawString:
var err error
lval.str, err = strconv.Unquote(l.TokenText())
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions pkg/logql/lex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ func TestLex(t *testing.T) {
expected []int
}{
{`{foo="bar"}`, []int{OPEN_BRACE, IDENTIFIER, EQ, STRING, CLOSE_BRACE}},
{"{foo=\"bar\"} |~ `\\w+`", []int{OPEN_BRACE, IDENTIFIER, EQ, STRING, CLOSE_BRACE, PIPE_MATCH, STRING}},
{`{foo="bar"} |~ "\\w+"`, []int{OPEN_BRACE, IDENTIFIER, EQ, STRING, CLOSE_BRACE, PIPE_MATCH, STRING}},
{`{ foo = "bar" }`, []int{OPEN_BRACE, IDENTIFIER, EQ, STRING, CLOSE_BRACE}},
{`{ foo != "bar" }`, []int{OPEN_BRACE, IDENTIFIER, NEQ, STRING, CLOSE_BRACE}},
{`{ foo =~ "bar" }`, []int{OPEN_BRACE, IDENTIFIER, RE, STRING, CLOSE_BRACE}},
Expand Down
51 changes: 35 additions & 16 deletions pkg/logql/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@ func TestParse(t *testing.T) {
exp Expr
err error
}{
{
// raw string
in: "count_over_time({foo=~`bar\\w+`}[12h] |~ `error\\`)",
exp: &rangeAggregationExpr{
operation: "count_over_time",
left: &logRange{
left: &filterExpr{
ty: labels.MatchRegexp,
match: "error\\",
left: &matchersExpr{
matchers: []*labels.Matcher{
mustNewMatcher(labels.MatchRegexp, "foo", "bar\\w+"),
},
},
},
interval: 12 * time.Hour,
},
},
},
{
// test [12h] before filter expr
in: `count_over_time({foo="bar"}[12h] |= "error")`,
Expand Down Expand Up @@ -658,10 +677,10 @@ func TestParse(t *testing.T) {
},
{
in: `
sum(count_over_time({foo="bar"}[5m])) by (foo) ^
sum(count_over_time({foo="bar"}[5m])) by (foo) /
sum(count_over_time({foo="bar"}[5m])) by (foo)
`,
sum(count_over_time({foo="bar"}[5m])) by (foo) ^
sum(count_over_time({foo="bar"}[5m])) by (foo) /
sum(count_over_time({foo="bar"}[5m])) by (foo)
`,
exp: mustNewBinOpExpr(
OpTypeDiv,
mustNewBinOpExpr(
Expand Down Expand Up @@ -720,10 +739,10 @@ func TestParse(t *testing.T) {
{
// operator precedence before left associativity
in: `
sum(count_over_time({foo="bar"}[5m])) by (foo) +
sum(count_over_time({foo="bar"}[5m])) by (foo) /
sum(count_over_time({foo="bar"}[5m])) by (foo)
`,
sum(count_over_time({foo="bar"}[5m])) by (foo) +
sum(count_over_time({foo="bar"}[5m])) by (foo) /
sum(count_over_time({foo="bar"}[5m])) by (foo)
`,
exp: mustNewBinOpExpr(
OpTypeAdd,
mustNewVectorAggregationExpr(newRangeAggregationExpr(
Expand Down Expand Up @@ -781,10 +800,10 @@ func TestParse(t *testing.T) {
},
{
in: `sum by (job) (
count_over_time({namespace="tns"} |= "level=error"[5m])
/
count_over_time({namespace="tns"}[5m])
)`,
count_over_time({namespace="tns"} |= "level=error"[5m])
/
count_over_time({namespace="tns"}[5m])
)`,
exp: mustNewVectorAggregationExpr(
mustNewBinOpExpr(OpTypeDiv,
newRangeAggregationExpr(
Expand Down Expand Up @@ -812,10 +831,10 @@ func TestParse(t *testing.T) {
},
{
in: `sum by (job) (
count_over_time({namespace="tns"} |= "level=error"[5m])
/
count_over_time({namespace="tns"}[5m])
) * 100`,
count_over_time({namespace="tns"} |= "level=error"[5m])
/
count_over_time({namespace="tns"}[5m])
) * 100`,
exp: mustNewBinOpExpr(OpTypeMul, mustNewVectorAggregationExpr(
mustNewBinOpExpr(OpTypeDiv,
newRangeAggregationExpr(
Expand Down

0 comments on commit f9a2c43

Please sign in to comment.