Skip to content

Commit

Permalink
FIX-2605: Make span.resource.xyz attributes work (#3284)
Browse files Browse the repository at this point in the history
* FIX-2605: Make span.resource.xyz attributes work

* Update CHANGELOG.md

Co-authored-by: Joe Elliott <joe.elliott@grafana.com>

---------

Co-authored-by: Joe Elliott <joe.elliott@grafana.com>
  • Loading branch information
mghildiy and joe-elliott committed Jan 17, 2024
1 parent e11ceb9 commit d457633
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* [FEATURE] TraceQL metrics queries [#3227](https://github.com/grafana/tempo/pull/3227) [#3252](https://github.com/grafana/tempo/pull/3252) [#3258](https://github.com/grafana/tempo/pull/3258) (@mdisibio @zalegrala)
* [FEATURE] Add support for multi-tenant queries. [#3087](https://github.com/grafana/tempo/pull/3087) (@electron0zero)
* [BUGFIX] Fix parsing of span.resource.xyz attributes in TraceQL. [#3284](https://github.com/grafana/tempo/pull/3284) (@mghildiy)
* [BUGFIX] Change exit code if config is successfully verified [#3174](https://github.com/grafana/tempo/pull/3174) (@am3o @agrib-01)
* [BUGFIX] The tempo-cli analyse blocks command no longer fails on compacted blocks [#3183](https://github.com/grafana/tempo/pull/3183) (@stoewer)
* [BUGFIX] Move waitgroup handling for poller error condition [#3224](https://github.com/grafana/tempo/pull/3224) (@zalegrala)
Expand Down
13 changes: 10 additions & 3 deletions pkg/traceql/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ type lexer struct {
errs []*ParseError

parsingAttribute bool
currentScope int
}

func (l *lexer) Lex(lval *yySymType) int {
Expand All @@ -103,8 +104,9 @@ func (l *lexer) Lex(lval *yySymType) int {

if l.parsingAttribute {
// parse out any scopes here
scopeToken, ok := tryScopeAttribute(&l.Scanner)
scopeToken, ok := tryScopeAttribute(&l.Scanner, l.currentScope)
if ok {
l.currentScope = scopeToken
return scopeToken
}

Expand Down Expand Up @@ -187,6 +189,10 @@ func (l *lexer) Lex(lval *yySymType) int {
break
}

if multiTok == PARENT_DOT || multiTok == SPAN_DOT || multiTok == RESOURCE_DOT {
l.currentScope = multiTok
}

// did we find a combination token?
if multiTok != -1 {
l.parsingAttribute = startsAttribute(multiTok)
Expand Down Expand Up @@ -261,7 +267,7 @@ func parseQuotedAtrribute(s *scanner.Scanner) (string, error) {
return sb.String(), nil
}

func tryScopeAttribute(l *scanner.Scanner) (int, bool) {
func tryScopeAttribute(l *scanner.Scanner, currentScope int) (int, bool) {
// copy the scanner to avoid advancing if it's not a scope.
s := *l
str := ""
Expand All @@ -273,7 +279,8 @@ func tryScopeAttribute(l *scanner.Scanner) (int, bool) {
str += string(s.Next())
}
tok := tokens[str]
if tok == RESOURCE_DOT || tok == SPAN_DOT {

if (tok == SPAN_DOT || tok == RESOURCE_DOT) && currentScope == PARENT_DOT {
// we have found scope attribute so consume the original scanner
for i := 0; i < len(str); i++ {
l.Next()
Expand Down
22 changes: 22 additions & 0 deletions pkg/traceql/lexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,28 @@ func TestLexerParseDuration(t *testing.T) {
}
}

func TestLexerScoping(t *testing.T) {
testLexer(t, ([]lexerTestCase{
{`span.foo3`, []int{SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`span.foo+bar`, []int{SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`span.foo-bar`, []int{SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`span.resource.foo`, []int{SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`parent.span.foo`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`span.foo.bar`, []int{SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}},
// resource attributes
{`resource.foo`, []int{RESOURCE_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`resource.count`, []int{RESOURCE_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`resource.foo3`, []int{RESOURCE_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`resource.foo+bar`, []int{RESOURCE_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`resource.foo-bar`, []int{RESOURCE_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`resource.span.foo`, []int{RESOURCE_DOT, IDENTIFIER, END_ATTRIBUTE}},
// parent span attributes
{`parent.span.foo`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`parent.span.count`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}},
{`parent.span.resource.id`, []int{PARENT_DOT, SPAN_DOT, IDENTIFIER, END_ATTRIBUTE}},
}))
}

func testLexer(t *testing.T, tcs []lexerTestCase) {
for _, tc := range tcs {
t.Run(tc.input, func(t *testing.T) {
Expand Down

0 comments on commit d457633

Please sign in to comment.