diff --git a/CHANGELOG.md b/CHANGELOG.md
index 44f67816624..7f69a62f5a4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
* [CHANGE] Update Go to 1.22.4 [#3757](https://github.com/grafana/tempo/pull/3757) [#3793](https://github.com/grafana/tempo/pull/3793) (@joe-elliott, @mapno)
* [FEATURE] TraceQL support for link scope and link:traceID and link:spanID [#3741](https://github.com/grafana/tempo/pull/3741) (@stoewer)
* [FEATURE] TraceQL support for event scope and event:name intrinsic [#3708](https://github.com/grafana/tempo/pull/3708) (@stoewer)
+* [FEATURE] TraecQL support for event attributes [#3708](https://github.com/grafana/tempo/pull/3748) (@ie-pham)
* [FEATURE] Flush and query RF1 blocks for TraceQL metric queries [#3628](https://github.com/grafana/tempo/pull/3628) [#3691](https://github.com/grafana/tempo/pull/3691) [#3723](https://github.com/grafana/tempo/pull/3723) (@mapno)
* [FEATURE] Add new compare() metrics function [#3695](https://github.com/grafana/tempo/pull/3695) (@mdisibio)
* [ENHANCEMENT] Tag value lookup use protobuf internally for improved latency [#3731](https://github.com/grafana/tempo/pull/3731) (@mdisibio)
diff --git a/docs/sources/tempo/traceql/_index.md b/docs/sources/tempo/traceql/_index.md
index 6efc8dd14a7..76899cfa5a0 100644
--- a/docs/sources/tempo/traceql/_index.md
+++ b/docs/sources/tempo/traceql/_index.md
@@ -101,7 +101,7 @@ possible to span-level intrinsics.
### Attribute fields
-There are two types of attributes: span attributes and resource attributes. By expanding a span in the Grafana UI, you can see both its span attributes (1 in the screenshot) and resource attributes (2 in the screenshot).
+TraceQL has three different attribute scopes: span attributes, resource attributes, and event attributes. By expanding a span in the Grafana UI, you can see both its span attributes (1 in the screenshot) and resource attributes (2 in the screenshot).

@@ -128,6 +128,11 @@ Find any database connection string that goes to a Postgres or MySQL database:
{ span.db.system =~ "postgresql|mysql" }
```
+You can query for an exception in your span event:
+```
+{ event.exception.message =~ ".*something went wrong.*" }
+```
+
### Unscoped attribute fields
Attributes can be unscoped if you are unsure if the requested attribute exists on the span or resource. When possible, use scoped instead of unscoped attributes. Scoped attributes provide faster query results.
diff --git a/pkg/parquetquery/iters.go b/pkg/parquetquery/iters.go
index ebf44fc43fb..bcd62a380eb 100644
--- a/pkg/parquetquery/iters.go
+++ b/pkg/parquetquery/iters.go
@@ -30,14 +30,14 @@ import (
// D 0, 1, 0
// E 0, 2, -1
//
-// Currently supports 6 levels of nesting which should be enough for anybody. :)
-type RowNumber [6]int32
+// Currently supports 8 levels of nesting which should be enough for anybody. :)
+type RowNumber [8]int32
-const MaxDefinitionLevel = 5
+const MaxDefinitionLevel = 7
// EmptyRowNumber creates an empty invalid row number.
func EmptyRowNumber() RowNumber {
- return RowNumber{-1, -1, -1, -1, -1, -1}
+ return RowNumber{-1, -1, -1, -1, -1, -1, -1, -1}
}
// MaxRowNumber is a helper that represents the maximum(-ish) representable value.
@@ -80,10 +80,12 @@ func EqualRowNumber(upToDefinitionLevel int, a, b RowNumber) bool {
(a[2] == b[2] || upToDefinitionLevel < 2) &&
(a[3] == b[3] || upToDefinitionLevel < 3) &&
(a[4] == b[4] || upToDefinitionLevel < 4) &&
- (a[5] == b[5] || upToDefinitionLevel < 5)
+ (a[5] == b[5] || upToDefinitionLevel < 5) &&
+ (a[6] == b[6] || upToDefinitionLevel < 6) &&
+ (a[7] == b[7] || upToDefinitionLevel < 7)
}
-func TruncateRowNumber(definitionLevelToKeep int, t RowNumber) RowNumber {
+func truncateRowNumberSlow(definitionLevelToKeep int, t RowNumber) RowNumber {
n := EmptyRowNumber()
for i := 0; i <= definitionLevelToKeep; i++ {
n[i] = t[i]
@@ -91,6 +93,29 @@ func TruncateRowNumber(definitionLevelToKeep int, t RowNumber) RowNumber {
return n
}
+func TruncateRowNumber(definitionLevelToKeep int, t RowNumber) RowNumber {
+ switch definitionLevelToKeep {
+ case 0:
+ return RowNumber{t[0], -1, -1, -1, -1, -1, -1, -1}
+ case 1:
+ return RowNumber{t[0], t[1], -1, -1, -1, -1, -1, -1}
+ case 2:
+ return RowNumber{t[0], t[1], t[2], -1, -1, -1, -1, -1}
+ case 3:
+ return RowNumber{t[0], t[1], t[2], t[3], -1, -1, -1, -1}
+ case 4:
+ return RowNumber{t[0], t[1], t[2], t[3], t[4], -1, -1, -1}
+ case 5:
+ return RowNumber{t[0], t[1], t[2], t[3], t[4], t[5], -1, -1}
+ case 6:
+ return RowNumber{t[0], t[1], t[2], t[3], t[4], t[5], t[6], -1}
+ case 7:
+ return RowNumber{t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]}
+ default:
+ panic(fmt.Sprintf("definition level out of bound: should be [0:7] but got %d", definitionLevelToKeep))
+ }
+}
+
func (t *RowNumber) Valid() bool {
return t[0] >= 0
}
@@ -123,36 +148,66 @@ func (t *RowNumber) Next(repetitionLevel, definitionLevel int) {
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 1:
t[1] = 0
t[2] = -1
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 2:
t[1] = 0
t[2] = 0
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 3:
t[1] = 0
t[2] = 0
t[3] = 0
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 4:
t[1] = 0
t[2] = 0
t[3] = 0
t[4] = 0
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 5:
t[1] = 0
t[2] = 0
t[3] = 0
t[4] = 0
t[5] = 0
+ t[6] = -1
+ t[7] = -1
+ case 6:
+ t[1] = 0
+ t[2] = 0
+ t[3] = 0
+ t[4] = 0
+ t[5] = 0
+ t[6] = 0
+ t[7] = -1
+ case 7:
+ t[1] = 0
+ t[2] = 0
+ t[3] = 0
+ t[4] = 0
+ t[5] = 0
+ t[6] = 0
+ t[7] = 0
+ default:
+ panicWhenInvalidDefinitionLevel(definitionLevel)
}
case 1:
switch definitionLevel {
@@ -162,31 +217,59 @@ func (t *RowNumber) Next(repetitionLevel, definitionLevel int) {
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 1:
t[2] = -1
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 2:
t[2] = 0
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 3:
t[2] = 0
t[3] = 0
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 4:
t[2] = 0
t[3] = 0
t[4] = 0
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 5:
t[2] = 0
t[3] = 0
t[4] = 0
t[5] = 0
+ t[6] = -1
+ t[7] = -1
+ case 6:
+ t[2] = 0
+ t[3] = 0
+ t[4] = 0
+ t[5] = 0
+ t[6] = 0
+ t[7] = -1
+ case 7:
+ t[2] = 0
+ t[3] = 0
+ t[4] = 0
+ t[5] = 0
+ t[6] = 0
+ t[7] = 0
+ default:
+ panicWhenInvalidDefinitionLevel(definitionLevel)
}
case 2:
switch definitionLevel {
@@ -196,27 +279,53 @@ func (t *RowNumber) Next(repetitionLevel, definitionLevel int) {
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 1:
t[2] = -1
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 2:
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 3:
t[3] = 0
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 4:
t[3] = 0
t[4] = 0
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 5:
t[3] = 0
t[4] = 0
t[5] = 0
+ t[6] = -1
+ t[7] = -1
+ case 6:
+ t[3] = 0
+ t[4] = 0
+ t[5] = 0
+ t[6] = 0
+ t[7] = -1
+ case 7:
+ t[3] = 0
+ t[4] = 0
+ t[5] = 0
+ t[6] = 0
+ t[7] = 0
+ default:
+ panicWhenInvalidDefinitionLevel(definitionLevel)
}
case 3:
switch definitionLevel {
@@ -226,24 +335,48 @@ func (t *RowNumber) Next(repetitionLevel, definitionLevel int) {
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 1:
t[2] = -1
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 2:
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 3:
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 4:
t[4] = 0
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 5:
t[4] = 0
t[5] = 0
+ t[6] = -1
+ t[7] = -1
+ case 6:
+ t[4] = 0
+ t[5] = 0
+ t[6] = 0
+ t[7] = -1
+ case 7:
+ t[4] = 0
+ t[5] = 0
+ t[6] = 0
+ t[7] = 0
+ default:
+ panicWhenInvalidDefinitionLevel(definitionLevel)
}
case 4:
switch definitionLevel {
@@ -253,22 +386,44 @@ func (t *RowNumber) Next(repetitionLevel, definitionLevel int) {
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 1:
t[2] = -1
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 2:
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 3:
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 4:
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 5:
t[5] = 0
+ t[6] = -1
+ t[7] = -1
+ case 6:
+ t[5] = 0
+ t[6] = 0
+ t[7] = -1
+ case 7:
+ t[5] = 0
+ t[6] = 0
+ t[7] = 0
+ default:
+ panicWhenInvalidDefinitionLevel(definitionLevel)
}
case 5:
switch definitionLevel {
@@ -278,20 +433,124 @@ func (t *RowNumber) Next(repetitionLevel, definitionLevel int) {
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
+ case 1:
+ t[2] = -1
+ t[3] = -1
+ t[4] = -1
+ t[5] = -1
+ t[6] = -1
+ t[7] = -1
+ case 2:
+ t[3] = -1
+ t[4] = -1
+ t[5] = -1
+ t[6] = -1
+ t[7] = -1
+ case 3:
+ t[4] = -1
+ t[5] = -1
+ t[6] = -1
+ t[7] = -1
+ case 4:
+ t[5] = -1
+ t[6] = -1
+ t[7] = -1
+ case 5:
+ t[6] = -1
+ t[7] = -1
+ case 6:
+ t[6] = 0
+ t[7] = -1
+ case 7:
+ t[6] = 0
+ t[7] = 0
+ default:
+ panicWhenInvalidDefinitionLevel(definitionLevel)
+ }
+ case 6:
+ switch definitionLevel {
+ case 0:
+ t[1] = -1
+ t[2] = -1
+ t[3] = -1
+ t[4] = -1
+ t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 1:
t[2] = -1
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 2:
t[3] = -1
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 3:
t[4] = -1
t[5] = -1
+ t[6] = -1
+ t[7] = -1
case 4:
t[5] = -1
+ t[6] = -1
+ t[7] = -1
+ case 5:
+ t[6] = -1
+ t[7] = -1
+ case 6:
+ t[7] = -1
+ case 7:
+ t[7] = 0
+ default:
+ panicWhenInvalidDefinitionLevel(definitionLevel)
+ }
+ case 7:
+ switch definitionLevel {
+ case 0:
+ t[1] = -1
+ t[2] = -1
+ t[3] = -1
+ t[4] = -1
+ t[5] = -1
+ t[6] = -1
+ t[7] = -1
+ case 1:
+ t[2] = -1
+ t[3] = -1
+ t[4] = -1
+ t[5] = -1
+ t[6] = -1
+ t[7] = -1
+ case 2:
+ t[3] = -1
+ t[4] = -1
+ t[5] = -1
+ t[6] = -1
+ t[7] = -1
+ case 3:
+ t[4] = -1
+ t[5] = -1
+ t[6] = -1
+ t[7] = -1
+ case 4:
+ t[5] = -1
+ t[6] = -1
+ t[7] = -1
+ case 5:
+ t[6] = -1
+ t[7] = -1
+ case 6:
+ t[7] = -1
+ case 7:
+ default:
+ panicWhenInvalidDefinitionLevel(definitionLevel)
}
}
}
@@ -1940,6 +2199,10 @@ func (a *KeyValueGroupPredicate) KeepGroup(group *IteratorResult) bool {
return true
}
+func panicWhenInvalidDefinitionLevel(definitionLevel int) {
+ panic(fmt.Sprintf("definition level out of bound: should be [0:7] but got %d", definitionLevel))
+}
+
/*func printGroup(g *iteratorResult) {
fmt.Println("---group---")
for _, e := range g.entries {
diff --git a/pkg/parquetquery/iters_test.go b/pkg/parquetquery/iters_test.go
index 304ff31ed1f..71f0c0473d9 100644
--- a/pkg/parquetquery/iters_test.go
+++ b/pkg/parquetquery/iters_test.go
@@ -29,12 +29,12 @@ var iterTestCases = []struct {
// TestNext compares the unrolled Next() with the original nextSlow() to
// prevent drift
func TestNext(t *testing.T) {
- rn1 := RowNumber{0, 0, 0, 0, 0, 0}
- rn2 := RowNumber{0, 0, 0, 0, 0, 0}
+ rn1 := RowNumber{0, 0, 0, 0, 0, 0, 0, 0}
+ rn2 := RowNumber{0, 0, 0, 0, 0, 0, 0, 0}
for i := 0; i < 1000; i++ {
- r := rand.Intn(6)
- d := rand.Intn(6)
+ r := rand.Intn(MaxDefinitionLevel)
+ d := rand.Intn(MaxDefinitionLevel)
rn1.Next(r, d)
rn2.nextSlow(r, d)
@@ -43,9 +43,58 @@ func TestNext(t *testing.T) {
}
}
+// TestTruncate compares the unrolled TruncateRowNumber() with the original truncateRowNumberSlow() to
+// prevent drift
+func TestTruncateRowNumber(t *testing.T) {
+ for i := 0; i <= MaxDefinitionLevel; i++ {
+ rn := RowNumber{1, 2, 3, 4, 5, 6, 7, 8}
+
+ newR := TruncateRowNumber(i, rn)
+ oldR := truncateRowNumberSlow(i, rn)
+
+ require.Equal(t, newR, oldR)
+ }
+}
+
+func TestInvalidDefinitionLevelTruncate(t *testing.T) {
+ t.Run("TruncateRowNumber -1", func(t *testing.T) {
+ assertPanic(t, func() {
+ rn := RowNumber{1, 2, 3, 4, 5, 6, 7, 8}
+ d := -1
+ TruncateRowNumber(d, rn)
+ })
+ })
+ t.Run("TruncateRowNumber Max+1", func(t *testing.T) {
+ assertPanic(t, func() {
+ rn := RowNumber{1, 2, 3, 4, 5, 6, 7, 8}
+ d := MaxDefinitionLevel + 1
+ TruncateRowNumber(d, rn)
+ })
+ })
+}
+
+func TestInvalidDefinitionLevelNext(t *testing.T) {
+ t.Run("Next -1", func(t *testing.T) {
+ assertPanic(t, func() {
+ rn := RowNumber{1, 2, 3, 4, 5, 6, 7, 8}
+ r := 0
+ d := -1
+ rn.Next(r, d)
+ })
+ })
+ t.Run("Next Max+1", func(t *testing.T) {
+ assertPanic(t, func() {
+ rn := RowNumber{1, 2, 3, 4, 5, 6, 7, 8}
+ r := 0
+ d := MaxDefinitionLevel + 1
+ rn.Next(r, d)
+ })
+ })
+}
+
func TestRowNumber(t *testing.T) {
tr := EmptyRowNumber()
- require.Equal(t, RowNumber{-1, -1, -1, -1, -1, -1}, tr)
+ require.Equal(t, RowNumber{-1, -1, -1, -1, -1, -1, -1, -1}, tr)
steps := []struct {
repetitionLevel int
@@ -53,11 +102,11 @@ func TestRowNumber(t *testing.T) {
expected RowNumber
}{
// Name.Language.Country examples from the Dremel whitepaper
- {0, 3, RowNumber{0, 0, 0, 0, -1, -1}},
- {2, 2, RowNumber{0, 0, 1, -1, -1, -1}},
- {1, 1, RowNumber{0, 1, -1, -1, -1, -1}},
- {1, 3, RowNumber{0, 2, 0, 0, -1, -1}},
- {0, 1, RowNumber{1, 0, -1, -1, -1, -1}},
+ {0, 3, RowNumber{0, 0, 0, 0, -1, -1, -1, -1}},
+ {2, 2, RowNumber{0, 0, 1, -1, -1, -1, -1, -1}},
+ {1, 1, RowNumber{0, 1, -1, -1, -1, -1, -1, -1}},
+ {1, 3, RowNumber{0, 2, 0, 0, -1, -1, -1, -1}},
+ {0, 1, RowNumber{1, 0, -1, -1, -1, -1, -1, -1}},
}
for _, step := range steps {
@@ -88,8 +137,8 @@ func TestRowNumberPreceding(t *testing.T) {
testCases := []struct {
start, preceding RowNumber
}{
- {RowNumber{1000, -1, -1, -1, -1, -1}, RowNumber{999, -1, -1, -1, -1, -1}},
- {RowNumber{1000, 0, 0, 0, 0, 0}, RowNumber{999, math.MaxInt32, math.MaxInt32, math.MaxInt32, math.MaxInt32, math.MaxInt32}},
+ {RowNumber{1000, -1, -1, -1, -1, -1, -1, -1}, RowNumber{999, -1, -1, -1, -1, -1, -1, -1}},
+ {RowNumber{1000, 0, 0, 0, 0, 0, 0, 0}, RowNumber{999, math.MaxInt32, math.MaxInt32, math.MaxInt32, math.MaxInt32, math.MaxInt32, math.MaxInt32, math.MaxInt32}},
}
for _, tc := range testCases {
@@ -117,7 +166,7 @@ func testColumnIterator(t *testing.T, makeIter makeTestIterFn) {
res, err := iter.Next()
require.NoError(t, err)
require.NotNil(t, res, "i=%d", i)
- require.Equal(t, RowNumber{int32(i), -1, -1, -1, -1, -1}, res.RowNumber)
+ require.Equal(t, RowNumber{int32(i), -1, -1, -1, -1, -1, -1, -1}, res.RowNumber)
require.Equal(t, int64(i), res.ToMap()["A"][0].Int64())
}
@@ -156,7 +205,7 @@ func testColumnIteratorSeek(t *testing.T, makeIter makeTestIterFn) {
res, err := iter.SeekTo(rn, 0)
require.NoError(t, err)
require.NotNil(t, res, "seekTo=%v", seekTo)
- require.Equal(t, RowNumber{seekTo, -1, -1, -1, -1, -1}, res.RowNumber)
+ require.Equal(t, RowNumber{seekTo, -1, -1, -1, -1, -1, -1, -1}, res.RowNumber)
require.Equal(t, seekTo, res.ToMap()["A"][0].Int32())
}
}
@@ -189,7 +238,7 @@ func testColumnIteratorPredicate(t *testing.T, makeIter makeTestIterFn) {
res, err := iter.Next()
require.NoError(t, err)
require.NotNil(t, res)
- require.Equal(t, RowNumber{expectedResult, -1, -1, -1, -1, -1}, res.RowNumber)
+ require.Equal(t, RowNumber{expectedResult, -1, -1, -1, -1, -1, -1, -1}, res.RowNumber)
require.Equal(t, expectedResult, res.ToMap()["A"][0].Int32())
}
}
@@ -357,14 +406,23 @@ func TestEqualRowNumber(t *testing.T) {
}
func BenchmarkEqualRowNumber(b *testing.B) {
- r1 := RowNumber{1, 2, 3, 4, 5, 6}
- r2 := RowNumber{1, 2, 3, 5, 7, 9}
+ r1 := RowNumber{1, 2, 3, 4, 5, 6, 7, 8}
+ r2 := RowNumber{1, 2, 3, 5, 7, 9, 11, 13}
for d := 0; d <= MaxDefinitionLevel; d++ {
b.Run(strconv.Itoa(d), func(b *testing.B) {
for i := 0; i < b.N; i++ {
- EqualRowNumber(3, r1, r2)
+ EqualRowNumber(d, r1, r2)
}
})
}
}
+
+func assertPanic(t *testing.T, f func()) {
+ defer func() {
+ if r := recover(); r == nil {
+ t.Errorf("no panic")
+ }
+ }()
+ f()
+}
diff --git a/pkg/traceql/expr.y b/pkg/traceql/expr.y
index d9c39c63650..4c5aa59e5cd 100644
--- a/pkg/traceql/expr.y
+++ b/pkg/traceql/expr.y
@@ -94,7 +94,7 @@ import (
KIND_UNSPECIFIED KIND_INTERNAL KIND_SERVER KIND_CLIENT KIND_PRODUCER KIND_CONSUMER
IDURATION CHILDCOUNT NAME STATUS STATUS_MESSAGE PARENT KIND ROOTNAME ROOTSERVICENAME
ROOTSERVICE TRACEDURATION NESTEDSETLEFT NESTEDSETRIGHT NESTEDSETPARENT ID TRACE_ID SPAN_ID
- PARENT_DOT RESOURCE_DOT SPAN_DOT TRACE_COLON SPAN_COLON EVENT_COLON LINK_COLON
+ PARENT_DOT RESOURCE_DOT SPAN_DOT TRACE_COLON SPAN_COLON EVENT_COLON EVENT_DOT LINK_COLON
COUNT AVG MAX MIN SUM
BY COALESCE SELECT
END_ATTRIBUTE
@@ -405,10 +405,10 @@ scopedIntrinsicField:
| SPAN_COLON STATUS_MESSAGE { $$ = NewIntrinsic(IntrinsicStatusMessage) }
| SPAN_COLON ID { $$ = NewIntrinsic(IntrinsicSpanID) }
// event:
- | EVENT_COLON NAME { $$ = NewIntrinsic(IntrinsicEventName) }
+ | EVENT_COLON NAME { $$ = NewIntrinsic(IntrinsicEventName) }
// link:
- | LINK_COLON TRACE_ID { $$ = NewIntrinsic(IntrinsicLinkTraceID) }
- | LINK_COLON SPAN_ID { $$ = NewIntrinsic(IntrinsicLinkSpanID) }
+ | LINK_COLON TRACE_ID { $$ = NewIntrinsic(IntrinsicLinkTraceID) }
+ | LINK_COLON SPAN_ID { $$ = NewIntrinsic(IntrinsicLinkSpanID) }
;
attributeField:
@@ -418,4 +418,5 @@ attributeField:
| PARENT_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeNone, true, $2) }
| PARENT_DOT RESOURCE_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeResource, true, $3) }
| PARENT_DOT SPAN_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeSpan, true, $3) }
+ | EVENT_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeEvent, false, $2) }
;
diff --git a/pkg/traceql/expr.y.go b/pkg/traceql/expr.y.go
index c2458817be1..a1e6c539321 100644
--- a/pkg/traceql/expr.y.go
+++ b/pkg/traceql/expr.y.go
@@ -101,52 +101,53 @@ const SPAN_DOT = 57388
const TRACE_COLON = 57389
const SPAN_COLON = 57390
const EVENT_COLON = 57391
-const LINK_COLON = 57392
-const COUNT = 57393
-const AVG = 57394
-const MAX = 57395
-const MIN = 57396
-const SUM = 57397
-const BY = 57398
-const COALESCE = 57399
-const SELECT = 57400
-const END_ATTRIBUTE = 57401
-const RATE = 57402
-const COUNT_OVER_TIME = 57403
-const QUANTILE_OVER_TIME = 57404
-const HISTOGRAM_OVER_TIME = 57405
-const COMPARE = 57406
-const WITH = 57407
-const PIPE = 57408
-const AND = 57409
-const OR = 57410
-const EQ = 57411
-const NEQ = 57412
-const LT = 57413
-const LTE = 57414
-const GT = 57415
-const GTE = 57416
-const NRE = 57417
-const RE = 57418
-const DESC = 57419
-const ANCE = 57420
-const SIBL = 57421
-const NOT_CHILD = 57422
-const NOT_PARENT = 57423
-const NOT_DESC = 57424
-const NOT_ANCE = 57425
-const UNION_CHILD = 57426
-const UNION_PARENT = 57427
-const UNION_DESC = 57428
-const UNION_ANCE = 57429
-const UNION_SIBL = 57430
-const ADD = 57431
-const SUB = 57432
-const NOT = 57433
-const MUL = 57434
-const DIV = 57435
-const MOD = 57436
-const POW = 57437
+const EVENT_DOT = 57392
+const LINK_COLON = 57393
+const COUNT = 57394
+const AVG = 57395
+const MAX = 57396
+const MIN = 57397
+const SUM = 57398
+const BY = 57399
+const COALESCE = 57400
+const SELECT = 57401
+const END_ATTRIBUTE = 57402
+const RATE = 57403
+const COUNT_OVER_TIME = 57404
+const QUANTILE_OVER_TIME = 57405
+const HISTOGRAM_OVER_TIME = 57406
+const COMPARE = 57407
+const WITH = 57408
+const PIPE = 57409
+const AND = 57410
+const OR = 57411
+const EQ = 57412
+const NEQ = 57413
+const LT = 57414
+const LTE = 57415
+const GT = 57416
+const GTE = 57417
+const NRE = 57418
+const RE = 57419
+const DESC = 57420
+const ANCE = 57421
+const SIBL = 57422
+const NOT_CHILD = 57423
+const NOT_PARENT = 57424
+const NOT_DESC = 57425
+const NOT_ANCE = 57426
+const UNION_CHILD = 57427
+const UNION_PARENT = 57428
+const UNION_DESC = 57429
+const UNION_ANCE = 57430
+const UNION_SIBL = 57431
+const ADD = 57432
+const SUB = 57433
+const NOT = 57434
+const MUL = 57435
+const DIV = 57436
+const MOD = 57437
+const POW = 57438
var yyToknames = [...]string{
"$end",
@@ -198,6 +199,7 @@ var yyToknames = [...]string{
"TRACE_COLON",
"SPAN_COLON",
"EVENT_COLON",
+ "EVENT_DOT",
"LINK_COLON",
"COUNT",
"AVG",
@@ -256,158 +258,158 @@ var yyExca = [...]int{
-1, 1,
1, -1,
-2, 0,
- -1, 284,
+ -1, 286,
13, 86,
-2, 94,
}
const yyPrivate = 57344
-const yyLast = 949
+const yyLast = 948
var yyAct = [...]int{
- 101, 5, 100, 6, 99, 8, 222, 7, 272, 98,
- 12, 67, 18, 13, 282, 2, 241, 90, 223, 94,
- 77, 319, 198, 70, 66, 228, 229, 198, 230, 231,
- 232, 241, 149, 199, 150, 30, 153, 29, 151, 85,
- 86, 329, 87, 88, 89, 90, 230, 231, 232, 241,
- 179, 181, 182, 183, 184, 185, 186, 187, 188, 189,
- 190, 191, 192, 193, 194, 195, 196, 316, 72, 73,
- 328, 74, 75, 76, 77, 326, 310, 315, 309, 308,
- 199, 205, 87, 88, 89, 90, 74, 75, 76, 77,
- 307, 356, 343, 226, 333, 225, 332, 224, 213, 215,
- 216, 217, 218, 219, 220, 264, 265, 263, 364, 289,
- 250, 221, 360, 289, 361, 244, 245, 246, 334, 17,
- 365, 242, 243, 233, 234, 235, 236, 237, 238, 240,
- 239, 242, 243, 233, 234, 235, 236, 237, 238, 240,
- 239, 68, 11, 228, 229, 335, 230, 231, 232, 241,
- 325, 251, 252, 228, 229, 321, 230, 231, 232, 241,
- 320, 279, 266, 267, 268, 269, 270, 353, 289, 352,
- 289, 350, 351, 280, 233, 234, 235, 236, 237, 238,
- 240, 239, 279, 202, 19, 20, 21, 17, 17, 180,
- 159, 359, 363, 203, 228, 229, 349, 230, 231, 232,
- 241, 149, 339, 150, 338, 153, 281, 151, 348, 347,
- 336, 337, 284, 204, 207, 208, 209, 210, 211, 212,
- 278, 286, 317, 318, 288, 289, 277, 276, 280, 23,
- 26, 24, 25, 27, 14, 160, 15, 275, 154, 155,
- 156, 157, 158, 274, 206, 162, 358, 200, 290, 291,
- 292, 293, 294, 295, 296, 297, 298, 299, 300, 301,
- 302, 303, 304, 305, 147, 146, 145, 144, 22, 85,
- 86, 143, 87, 88, 89, 90, 142, 226, 226, 225,
- 225, 224, 224, 92, 253, 67, 91, 67, 344, 324,
- 226, 254, 225, 255, 224, 322, 323, 70, 256, 70,
- 286, 48, 53, 355, 354, 50, 273, 49, 327, 57,
- 312, 51, 52, 54, 55, 56, 59, 58, 60, 61,
- 64, 63, 62, 84, 139, 140, 141, 330, 149, 331,
- 150, 311, 153, 249, 151, 71, 342, 341, 248, 226,
- 226, 225, 225, 224, 224, 345, 346, 247, 28, 271,
- 226, 340, 225, 69, 224, 16, 357, 4, 148, 10,
- 226, 152, 225, 1, 224, 0, 362, 102, 103, 104,
- 108, 131, 0, 93, 95, 0, 0, 107, 105, 106,
- 110, 109, 111, 112, 113, 114, 115, 116, 117, 118,
- 119, 120, 121, 122, 124, 123, 125, 126, 0, 127,
- 128, 129, 130, 201, 0, 0, 134, 132, 133, 135,
- 136, 137, 138, 314, 0, 102, 103, 104, 108, 131,
- 0, 0, 95, 0, 0, 107, 105, 106, 110, 109,
- 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
- 121, 122, 124, 123, 125, 126, 0, 127, 128, 129,
- 130, 313, 96, 97, 134, 132, 133, 135, 136, 137,
- 138, 306, 0, 0, 0, 0, 0, 242, 243, 233,
- 234, 235, 236, 237, 238, 240, 239, 0, 0, 72,
- 73, 0, 74, 75, 76, 77, 0, 0, 0, 228,
- 229, 287, 230, 231, 232, 241, 0, 0, 0, 227,
- 96, 97, 0, 0, 0, 242, 243, 233, 234, 235,
- 236, 237, 238, 240, 239, 242, 243, 233, 234, 235,
- 236, 237, 238, 240, 239, 0, 0, 228, 229, 203,
- 230, 231, 232, 241, 0, 0, 0, 228, 229, 0,
- 230, 231, 232, 241, 0, 242, 243, 233, 234, 235,
- 236, 237, 238, 240, 239, 242, 243, 233, 234, 235,
- 236, 237, 238, 240, 239, 0, 0, 228, 229, 0,
- 230, 231, 232, 241, 197, 0, 0, 228, 229, 0,
- 230, 231, 232, 241, 0, 78, 79, 80, 81, 82,
- 83, 0, 78, 79, 80, 81, 82, 83, 0, 78,
- 79, 80, 81, 82, 83, 85, 86, 0, 87, 88,
- 89, 90, 85, 86, 0, 87, 88, 89, 90, 72,
- 73, 0, 74, 75, 76, 77, 0, 0, 31, 36,
- 0, 0, 33, 0, 32, 0, 42, 0, 34, 35,
- 37, 38, 39, 40, 41, 43, 44, 45, 46, 47,
- 48, 53, 0, 0, 50, 0, 49, 0, 57, 0,
- 51, 52, 54, 55, 56, 59, 58, 60, 61, 64,
- 63, 62, 31, 36, 0, 0, 33, 0, 32, 0,
- 42, 0, 34, 35, 37, 38, 39, 40, 41, 43,
- 44, 45, 46, 47, 19, 20, 21, 0, 17, 0,
- 159, 0, 19, 20, 21, 0, 17, 0, 285, 0,
- 19, 20, 21, 50, 17, 49, 283, 57, 0, 51,
- 52, 54, 55, 56, 59, 58, 60, 61, 64, 63,
- 62, 0, 0, 0, 0, 0, 0, 0, 0, 23,
- 26, 24, 25, 27, 14, 160, 15, 23, 26, 24,
+ 101, 5, 100, 6, 99, 8, 223, 7, 274, 98,
+ 12, 67, 18, 13, 284, 2, 242, 90, 224, 94,
+ 77, 322, 200, 70, 66, 19, 20, 21, 30, 17,
+ 29, 287, 150, 332, 151, 331, 154, 315, 152, 229,
+ 230, 312, 231, 232, 233, 242, 231, 232, 233, 242,
+ 180, 182, 183, 184, 185, 186, 187, 188, 189, 190,
+ 191, 192, 193, 194, 195, 196, 197, 319, 311, 310,
+ 309, 23, 26, 24, 25, 27, 14, 318, 15, 85,
+ 86, 206, 87, 88, 89, 90, 72, 73, 199, 74,
+ 75, 76, 77, 227, 359, 226, 346, 225, 214, 216,
+ 217, 218, 219, 220, 221, 87, 88, 89, 90, 199,
+ 22, 222, 336, 335, 265, 245, 246, 247, 74, 75,
+ 76, 77, 243, 244, 234, 235, 236, 237, 238, 239,
+ 241, 240, 243, 244, 234, 235, 236, 237, 238, 239,
+ 241, 240, 329, 204, 229, 230, 364, 231, 232, 233,
+ 242, 251, 266, 267, 229, 230, 337, 231, 232, 233,
+ 242, 368, 281, 200, 269, 270, 271, 272, 367, 291,
+ 363, 291, 356, 291, 282, 234, 235, 236, 237, 238,
+ 239, 241, 240, 281, 19, 20, 21, 338, 17, 17,
+ 160, 181, 252, 253, 328, 229, 230, 324, 231, 232,
+ 233, 242, 150, 255, 151, 323, 154, 268, 152, 203,
+ 256, 362, 257, 286, 355, 291, 352, 258, 353, 354,
+ 85, 86, 288, 87, 88, 89, 90, 351, 350, 282,
+ 23, 26, 24, 25, 27, 14, 161, 15, 342, 155,
+ 156, 157, 158, 159, 339, 340, 204, 320, 321, 292,
+ 293, 294, 295, 296, 297, 298, 299, 300, 301, 302,
+ 303, 304, 305, 306, 307, 341, 19, 20, 21, 22,
+ 17, 259, 160, 260, 262, 263, 283, 261, 280, 227,
+ 227, 226, 226, 225, 225, 264, 279, 67, 278, 67,
+ 277, 327, 227, 276, 226, 207, 225, 325, 326, 70,
+ 163, 70, 288, 78, 79, 80, 81, 82, 83, 148,
+ 330, 147, 23, 26, 24, 25, 27, 14, 161, 15,
+ 290, 291, 146, 85, 86, 145, 87, 88, 89, 90,
+ 333, 150, 334, 151, 144, 154, 143, 152, 92, 91,
+ 84, 17, 227, 227, 226, 226, 225, 225, 348, 349,
+ 366, 22, 71, 227, 361, 226, 347, 225, 28, 360,
+ 140, 141, 142, 227, 275, 226, 314, 225, 313, 365,
+ 102, 103, 104, 108, 131, 254, 93, 95, 358, 357,
+ 107, 105, 106, 110, 109, 111, 112, 113, 114, 115,
+ 116, 117, 118, 119, 120, 121, 122, 124, 123, 125,
+ 126, 250, 127, 128, 129, 130, 202, 345, 344, 134,
+ 132, 133, 136, 137, 138, 135, 139, 317, 273, 102,
+ 103, 104, 108, 131, 249, 248, 95, 343, 69, 107,
+ 105, 106, 110, 109, 111, 112, 113, 114, 115, 116,
+ 117, 118, 119, 120, 121, 122, 124, 123, 125, 126,
+ 16, 127, 128, 129, 130, 316, 96, 97, 134, 132,
+ 133, 136, 137, 138, 135, 139, 308, 4, 149, 10,
+ 153, 1, 243, 244, 234, 235, 236, 237, 238, 239,
+ 241, 240, 0, 72, 73, 0, 74, 75, 76, 77,
+ 0, 0, 0, 0, 229, 230, 289, 231, 232, 233,
+ 242, 0, 0, 0, 228, 96, 97, 0, 0, 0,
+ 243, 244, 234, 235, 236, 237, 238, 239, 241, 240,
+ 0, 243, 244, 234, 235, 236, 237, 238, 239, 241,
+ 240, 0, 229, 230, 0, 231, 232, 233, 242, 0,
+ 0, 0, 0, 229, 230, 0, 231, 232, 233, 242,
+ 0, 243, 244, 234, 235, 236, 237, 238, 239, 241,
+ 240, 243, 244, 234, 235, 236, 237, 238, 239, 241,
+ 240, 201, 0, 229, 230, 0, 231, 232, 233, 242,
+ 0, 0, 0, 229, 230, 0, 231, 232, 233, 242,
+ 78, 79, 80, 81, 82, 83, 198, 78, 79, 80,
+ 81, 82, 83, 0, 0, 0, 0, 0, 0, 0,
+ 85, 86, 0, 87, 88, 89, 90, 72, 73, 0,
+ 74, 75, 76, 77, 0, 0, 48, 53, 0, 0,
+ 50, 0, 49, 0, 57, 0, 51, 52, 54, 55,
+ 56, 59, 58, 60, 61, 64, 63, 62, 0, 0,
+ 0, 31, 36, 0, 0, 33, 0, 32, 0, 42,
+ 0, 34, 35, 37, 38, 39, 40, 41, 43, 44,
+ 45, 46, 47, 48, 53, 0, 0, 50, 0, 49,
+ 0, 57, 0, 51, 52, 54, 55, 56, 59, 58,
+ 60, 61, 64, 63, 62, 31, 36, 0, 0, 33,
+ 0, 32, 0, 42, 0, 34, 35, 37, 38, 39,
+ 40, 41, 43, 44, 45, 46, 47, 19, 20, 21,
+ 50, 17, 49, 285, 57, 0, 51, 52, 54, 55,
+ 56, 59, 58, 60, 61, 64, 63, 62, 33, 0,
+ 32, 0, 42, 0, 34, 35, 37, 38, 39, 40,
+ 41, 43, 44, 45, 46, 47, 0, 0, 0, 0,
+ 0, 0, 0, 23, 26, 24, 25, 27, 14, 0,
+ 15, 19, 20, 21, 0, 17, 0, 9, 0, 19,
+ 20, 21, 0, 17, 0, 160, 19, 20, 21, 0,
+ 0, 0, 215, 0, 0, 0, 0, 0, 0, 0,
+ 68, 11, 22, 0, 0, 65, 3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 23, 26, 24,
25, 27, 14, 0, 15, 23, 26, 24, 25, 27,
- 14, 0, 15, 19, 20, 21, 0, 17, 0, 9,
- 0, 19, 20, 21, 0, 17, 0, 159, 22, 19,
- 20, 21, 0, 0, 0, 214, 22, 0, 0, 33,
- 0, 32, 0, 42, 22, 34, 35, 37, 38, 39,
- 40, 41, 43, 44, 45, 46, 47, 0, 23, 26,
- 24, 25, 27, 14, 0, 15, 23, 26, 24, 25,
- 27, 0, 0, 0, 23, 26, 24, 25, 27, 257,
- 0, 258, 260, 261, 0, 259, 0, 0, 0, 0,
- 0, 0, 0, 262, 0, 0, 131, 22, 0, 0,
- 0, 0, 0, 0, 0, 22, 65, 3, 0, 0,
- 0, 0, 0, 22, 118, 119, 120, 121, 122, 124,
- 123, 125, 126, 0, 127, 128, 129, 130, 0, 0,
- 0, 134, 132, 133, 135, 136, 137, 138, 161, 163,
- 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
- 174, 175, 176, 177, 178, 102, 103, 104, 108, 0,
- 0, 0, 206, 0, 0, 107, 105, 106, 110, 109,
- 111, 112, 113, 114, 115, 116, 117, 102, 103, 104,
- 108, 0, 0, 0, 0, 0, 0, 107, 105, 106,
- 110, 109, 111, 112, 113, 114, 115, 116, 117,
+ 0, 0, 23, 26, 24, 25, 27, 162, 164, 165,
+ 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 0, 0, 22, 0, 0, 0,
+ 0, 131, 0, 0, 22, 0, 0, 0, 0, 0,
+ 0, 22, 205, 208, 209, 210, 211, 212, 213, 118,
+ 119, 120, 121, 122, 124, 123, 125, 126, 0, 127,
+ 128, 129, 130, 0, 0, 0, 134, 132, 133, 136,
+ 137, 138, 135, 139, 102, 103, 104, 108, 0, 0,
+ 0, 207, 0, 0, 107, 105, 106, 110, 109, 111,
+ 112, 113, 114, 115, 116, 117, 102, 103, 104, 108,
+ 0, 0, 0, 0, 0, 0, 107, 105, 106, 110,
+ 109, 111, 112, 113, 114, 115, 116, 117,
}
var yyPact = [...]int{
- 757, -28, -31, 605, -1000, 583, -1000, -1000, -1000, 757,
- -1000, 530, -1000, 523, 274, 271, -1000, 362, -1000, -1000,
- -1000, -1000, 318, 264, 259, 255, 254, 253, -1000, 252,
- 178, 233, 233, 233, 233, 233, 233, 233, 233, 233,
- 233, 233, 233, 233, 233, 233, 233, 233, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 561, 14, 234, 390, 170,
- 516, 900, 232, 232, 232, 232, 232, 232, -1000, -1000,
- -1000, -1000, -1000, -1000, 773, 773, 773, 773, 773, 773,
- 773, 410, 837, -1000, 488, 410, 410, 410, -1000, -1000,
+ 765, -36, -39, 627, -1000, 605, -1000, -1000, -1000, 765,
+ -1000, 527, -1000, 520, 327, 326, -1000, 365, -1000, -1000,
+ -1000, -1000, 354, 324, 322, 313, 310, 299, -1000, 297,
+ 178, 288, 288, 288, 288, 288, 288, 288, 288, 288,
+ 288, 288, 288, 288, 288, 288, 288, 288, 179, 179,
+ 179, 179, 179, 179, 179, 179, 179, 179, 179, 179,
+ 179, 179, 179, 179, 179, 583, 96, 558, 393, 196,
+ 233, 899, 283, 283, 283, 283, 283, 283, -1000, -1000,
+ -1000, -1000, -1000, -1000, 780, 780, 780, 780, 780, 780,
+ 780, 414, 852, -1000, 493, 414, 414, 414, -1000, -1000,
+ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+ -1000, 421, 420, 397, 147, 371, 176, 244, 85, 110,
+ -1000, -1000, -1000, 194, 414, 414, 414, 414, 360, -1000,
+ 605, -1000, -1000, -1000, -1000, 281, 278, 276, 274, 266,
+ 773, 264, 666, 711, -1000, -1000, -1000, -1000, 666, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+ 648, 179, -1000, -1000, -1000, -1000, 648, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
- -1000, 343, 334, 329, 106, 257, 802, 78, 63, -1000,
- -1000, -1000, 149, 410, 410, 410, 410, 302, -1000, 583,
- -1000, -1000, -1000, -1000, 231, 225, 215, 214, 208, 765,
- 194, 718, 704, -1000, -1000, -1000, -1000, 718, -1000, -1000,
- -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 642,
- 177, -1000, -1000, -1000, -1000, 642, -1000, -1000, -1000, -1000,
- -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 688,
- -1000, -1000, -1000, -1000, -21, -1000, 696, -6, -6, -75,
- -75, -75, -75, -50, 773, -10, -10, -78, -78, -78,
- -78, 478, 211, -1000, -1000, -1000, -1000, -1000, 410, 410,
- 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
- 410, 410, 410, 410, 448, -46, -46, 31, 20, 19,
- 17, 327, 306, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
- -1000, -1000, -1000, -1000, -1000, -1000, -1000, 438, 400, 64,
- 54, 209, -1000, -48, 147, 142, 837, 837, 109, 234,
- 180, 137, 9, 704, -1000, 696, -33, -1000, -1000, 837,
- -46, -46, -79, -79, -79, -64, -64, -64, -64, -64,
- -64, -64, -64, -79, 105, 105, -1000, -1000, -1000, -1000,
- -1000, 11, -18, -1000, -1000, -1000, -1000, -1000, 302, 922,
- 40, 38, 104, 132, 197, -1000, 688, -1000, -1000, -1000,
- -1000, -1000, 192, 190, 330, 36, -1000, 282, 837, 837,
- 195, -1000, -1000, 184, 158, 156, 154, 297, 35, 837,
- -1000, 240, -1000, -1000, -1000, -1000, 179, 99, 100, 837,
- -1000, 186, 95, 107, -1000, -1000,
+ 260, -1000, -1000, -1000, -1000, -4, -1000, 19, 25, 25,
+ -76, -76, -76, -76, -11, 780, 12, 12, -79, -79,
+ -79, -79, 483, 307, -1000, -1000, -1000, -1000, -1000, 414,
+ 414, 414, 414, 414, 414, 414, 414, 414, 414, 414,
+ 414, 414, 414, 414, 414, 453, -47, -47, 10, 9,
+ 8, -19, 364, 362, -23, -1000, -1000, -1000, -1000, -1000,
+ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 442,
+ 404, 64, 54, 234, -1000, -49, 192, 184, 852, 852,
+ 331, 558, 130, 181, 75, 711, -1000, 19, -45, -1000,
+ -1000, 852, -47, -47, -80, -80, -80, -51, -51, -51,
+ -51, -51, -51, -51, -51, -80, 105, 105, -1000, -1000,
+ -1000, -1000, -1000, -25, -27, -1000, -1000, -1000, -1000, -1000,
+ -1000, 360, 921, 56, 55, 142, 174, 231, -1000, 260,
+ -1000, -1000, -1000, -1000, -1000, 253, 226, 401, 39, -1000,
+ 350, 852, 852, 214, -1000, -1000, 204, 205, 201, 159,
+ 372, 37, 852, -1000, 348, -1000, -1000, -1000, -1000, 199,
+ 157, 132, 852, -1000, 344, 155, 148, -1000, -1000,
}
var yyPgo = [...]int{
- 0, 363, 7, 361, 5, 6, 1, 856, 359, 14,
- 10, 3, 323, 358, 357, 141, 13, 355, 353, 12,
- 19, 9, 4, 2, 0, 18, 351, 8, 349, 348,
+ 0, 471, 7, 470, 5, 6, 1, 805, 469, 14,
+ 10, 3, 340, 468, 467, 800, 13, 450, 428, 12,
+ 19, 9, 4, 2, 0, 18, 427, 8, 418, 358,
}
var yyR1 = [...]int{
@@ -430,7 +432,7 @@ var yyR1 = [...]int{
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 23, 23, 23, 23,
- 23, 23,
+ 23, 23, 23,
}
var yyR2 = [...]int{
@@ -453,47 +455,47 @@ var yyR2 = [...]int{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
- 4, 4,
+ 4, 4, 3,
}
var yyChk = [...]int{
-1000, -1, -9, -7, -14, -6, -11, -2, -4, 12,
- -8, -15, -10, -16, 56, 58, -17, 10, -19, 6,
- 7, 8, 90, 51, 53, 54, 52, 55, -29, 65,
- 66, 67, 73, 71, 77, 78, 68, 79, 80, 81,
- 82, 83, 75, 84, 85, 86, 87, 88, 67, 73,
- 71, 77, 78, 68, 79, 80, 81, 75, 83, 82,
- 84, 85, 88, 87, 86, -7, -9, -6, -15, -18,
- -16, -12, 89, 90, 92, 93, 94, 95, 69, 70,
- 71, 72, 73, 74, -12, 89, 90, 92, 93, 94,
- 95, 12, 12, 11, -20, 12, 90, 91, -21, -22,
+ -8, -15, -10, -16, 57, 59, -17, 10, -19, 6,
+ 7, 8, 91, 52, 54, 55, 53, 56, -29, 66,
+ 67, 68, 74, 72, 78, 79, 69, 80, 81, 82,
+ 83, 84, 76, 85, 86, 87, 88, 89, 68, 74,
+ 72, 78, 79, 69, 80, 81, 82, 76, 84, 83,
+ 85, 86, 89, 88, 87, -7, -9, -6, -15, -18,
+ -16, -12, 90, 91, 93, 94, 95, 96, 70, 71,
+ 72, 73, 74, 75, -12, 90, 91, 93, 94, 95,
+ 96, 12, 12, 11, -20, 12, 91, 92, -21, -22,
-23, -24, 5, 6, 7, 16, 17, 15, 8, 19,
18, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 33, 32, 34, 35, 37, 38, 39,
- 40, 9, 45, 46, 44, 47, 48, 49, 50, 6,
- 7, 8, 12, 12, 12, 12, 12, 12, -13, -6,
- -11, -2, -3, -4, 60, 61, 62, 63, 64, 12,
- 57, -7, 12, -7, -7, -7, -7, -7, -7, -7,
- -7, -7, -7, -7, -7, -7, -7, -7, -7, -6,
- 12, -6, -6, -6, -6, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, 13, 13, 66,
- 13, 13, 13, 13, -15, -21, 12, -15, -15, -15,
- -15, -15, -15, -16, 12, -16, -16, -16, -16, -16,
- -16, -20, -5, -25, -22, -23, -24, 11, 89, 90,
- 92, 93, 94, 69, 70, 71, 72, 73, 74, 76,
- 75, 95, 67, 68, -20, -20, -20, 4, 4, 4,
- 4, 45, 46, 27, 34, 36, 41, 27, 29, 33,
- 30, 31, 41, 29, 42, 43, 13, -20, -20, -20,
- -20, -28, -27, 4, 12, 12, 12, 12, 12, -6,
- -16, 12, -9, 12, -19, 12, -9, 13, 13, 14,
- -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, -20, -20, -20, 13, 59, 59, 59,
- 59, 4, 4, 13, 13, 13, 13, 13, 14, 69,
- 13, 13, -25, -25, -10, 13, 66, -25, 59, 59,
- -27, -21, 56, 56, 14, 13, 13, 14, 12, 12,
- -26, 7, 6, 56, 6, -5, -5, 14, 13, 12,
- 13, 14, 13, 13, 7, 6, 56, -5, 6, 12,
- 13, 14, -5, 6, 13, 13,
+ 40, 9, 45, 46, 44, 50, 47, 48, 49, 51,
+ 6, 7, 8, 12, 12, 12, 12, 12, 12, -13,
+ -6, -11, -2, -3, -4, 61, 62, 63, 64, 65,
+ 12, 58, -7, 12, -7, -7, -7, -7, -7, -7,
+ -7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
+ -6, 12, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, 13, 13,
+ 67, 13, 13, 13, 13, -15, -21, 12, -15, -15,
+ -15, -15, -15, -15, -16, 12, -16, -16, -16, -16,
+ -16, -16, -20, -5, -25, -22, -23, -24, 11, 90,
+ 91, 93, 94, 95, 70, 71, 72, 73, 74, 75,
+ 77, 76, 96, 68, 69, -20, -20, -20, 4, 4,
+ 4, 4, 45, 46, 4, 27, 34, 36, 41, 27,
+ 29, 33, 30, 31, 41, 29, 42, 43, 13, -20,
+ -20, -20, -20, -28, -27, 4, 12, 12, 12, 12,
+ 12, -6, -16, 12, -9, 12, -19, 12, -9, 13,
+ 13, 14, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20, -20, 13, 60,
+ 60, 60, 60, 4, 4, 60, 13, 13, 13, 13,
+ 13, 14, 70, 13, 13, -25, -25, -10, 13, 67,
+ -25, 60, 60, -27, -21, 57, 57, 14, 13, 13,
+ 14, 12, 12, -26, 7, 6, 57, 6, -5, -5,
+ 14, 13, 12, 13, 14, 13, 13, 7, 6, 57,
+ -5, 6, 12, 13, 14, -5, 6, 13, 13,
}
var yyDef = [...]int{
@@ -510,30 +512,30 @@ var yyDef = [...]int{
142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
- 172, 0, 0, 0, 0, 0, 0, 0, 0, 98,
- 99, 100, 0, 0, 0, 0, 0, 0, 4, 30,
- 31, 32, 33, 34, 0, 0, 0, 0, 0, 0,
- 0, 7, 0, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 48,
- 0, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 63, 64, 6, 25, 0,
- 47, 77, 85, 87, 75, 76, 0, 78, 79, 80,
- 81, 82, 83, 68, 0, 88, 89, 90, 91, 92,
- 93, 0, 0, 41, 38, 39, 40, 67, 0, 0,
+ 172, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 98, 99, 100, 0, 0, 0, 0, 0, 0, 4,
+ 30, 31, 32, 33, 34, 0, 0, 0, 0, 0,
+ 0, 0, 7, 0, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 48, 0, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 6, 25,
+ 0, 47, 77, 85, 87, 75, 76, 0, 78, 79,
+ 80, 81, 82, 83, 68, 0, 88, 89, 90, 91,
+ 92, 93, 0, 0, 41, 38, 39, 40, 67, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 138, 139, 0, 0, 0,
- 0, 0, 0, 173, 174, 175, 176, 177, 178, 179,
- 180, 181, 182, 183, 184, 185, 101, 0, 0, 0,
- 0, 0, 119, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, -2, 0, 0, 35, 37, 0,
- 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
- 132, 133, 134, 135, 136, 137, 121, 186, 187, 188,
- 189, 0, 0, 102, 103, 104, 105, 118, 0, 0,
- 106, 108, 0, 0, 0, 36, 0, 42, 190, 191,
- 120, 117, 0, 0, 0, 112, 114, 0, 0, 0,
- 0, 43, 44, 0, 0, 0, 0, 0, 110, 0,
- 115, 0, 107, 109, 45, 46, 0, 0, 0, 0,
- 113, 0, 0, 0, 111, 116,
+ 0, 0, 0, 0, 0, 0, 138, 139, 0, 0,
+ 0, 0, 0, 0, 0, 173, 174, 175, 176, 177,
+ 178, 179, 180, 181, 182, 183, 184, 185, 101, 0,
+ 0, 0, 0, 0, 119, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, -2, 0, 0, 35,
+ 37, 0, 122, 123, 124, 125, 126, 127, 128, 129,
+ 130, 131, 132, 133, 134, 135, 136, 137, 121, 186,
+ 187, 188, 189, 0, 0, 192, 102, 103, 104, 105,
+ 118, 0, 0, 106, 108, 0, 0, 0, 36, 0,
+ 42, 190, 191, 120, 117, 0, 0, 0, 112, 114,
+ 0, 0, 0, 0, 43, 44, 0, 0, 0, 0,
+ 0, 110, 0, 115, 0, 107, 109, 45, 46, 0,
+ 0, 0, 0, 113, 0, 0, 0, 111, 116,
}
var yyTok1 = [...]int{
@@ -550,7 +552,7 @@ var yyTok2 = [...]int{
62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- 92, 93, 94, 95,
+ 92, 93, 94, 95, 96,
}
var yyTok3 = [...]int{
0,
@@ -2039,6 +2041,12 @@ yydefault:
{
yyVAL.attributeField = NewScopedAttribute(AttributeScopeSpan, true, yyDollar[3].staticStr)
}
+ case 192:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line pkg/traceql/expr.y:421
+ {
+ yyVAL.attributeField = NewScopedAttribute(AttributeScopeEvent, false, yyDollar[2].staticStr)
+ }
}
goto yystack /* stack new state and value */
}
diff --git a/pkg/traceql/lexer.go b/pkg/traceql/lexer.go
index ff818b0f7cd..afc07981fdb 100644
--- a/pkg/traceql/lexer.go
+++ b/pkg/traceql/lexer.go
@@ -86,6 +86,7 @@ var tokens = map[string]int{
"span:": SPAN_COLON,
"event:": EVENT_COLON,
"link:": LINK_COLON,
+ "event.": EVENT_DOT,
"count": COUNT,
"avg": AVG,
"max": MAX,
@@ -213,7 +214,8 @@ func (l *lexer) Lex(lval *yySymType) int {
multiTok == SPAN_COLON ||
multiTok == TRACE_COLON ||
multiTok == EVENT_COLON ||
- multiTok == LINK_COLON {
+ multiTok == LINK_COLON ||
+ multiTok == EVENT_DOT {
l.currentScope = multiTok
}
@@ -403,5 +405,6 @@ func startsAttribute(tok int) bool {
return tok == DOT ||
tok == RESOURCE_DOT ||
tok == SPAN_DOT ||
- tok == PARENT_DOT
+ tok == PARENT_DOT ||
+ tok == EVENT_DOT
}
diff --git a/pkg/traceql/lexer_test.go b/pkg/traceql/lexer_test.go
index caf7ccdcafb..3767d343f66 100644
--- a/pkg/traceql/lexer_test.go
+++ b/pkg/traceql/lexer_test.go
@@ -44,6 +44,13 @@ func TestLexerAttributes(t *testing.T) {
{`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}},
+ // event attributes
+ {`event.foo`, []int{EVENT_DOT, IDENTIFIER, END_ATTRIBUTE}},
+ {`event.count`, []int{EVENT_DOT, IDENTIFIER, END_ATTRIBUTE}},
+ {`event.count`, []int{EVENT_DOT, IDENTIFIER, END_ATTRIBUTE}},
+ {`event.foo3`, []int{EVENT_DOT, IDENTIFIER, END_ATTRIBUTE}},
+ {`event.foo+bar`, []int{EVENT_DOT, IDENTIFIER, END_ATTRIBUTE}},
+ {`event.foo-bar`, []int{EVENT_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}},
diff --git a/pkg/traceql/parse_test.go b/pkg/traceql/parse_test.go
index 74ebf99ce44..e9d1ac8ed70 100644
--- a/pkg/traceql/parse_test.go
+++ b/pkg/traceql/parse_test.go
@@ -1020,6 +1020,7 @@ func TestAttributes(t *testing.T) {
{in: "parent.foo.bar.baz", expected: NewScopedAttribute(AttributeScopeNone, true, "foo.bar.baz")},
{in: "resource.foo.bar.baz", expected: NewScopedAttribute(AttributeScopeResource, false, "foo.bar.baz")},
{in: "span.foo.bar", expected: NewScopedAttribute(AttributeScopeSpan, false, "foo.bar")},
+ {in: "event.foo.bar", expected: NewScopedAttribute(AttributeScopeEvent, false, "foo.bar")},
{in: "parent.resource.foo", expected: NewScopedAttribute(AttributeScopeResource, true, "foo")},
{in: "parent.span.foo", expected: NewScopedAttribute(AttributeScopeSpan, true, "foo")},
{in: "parent.resource.foo.bar.baz", expected: NewScopedAttribute(AttributeScopeResource, true, "foo.bar.baz")},
diff --git a/pkg/traceql/test_examples.yaml b/pkg/traceql/test_examples.yaml
index 75c8636a6f1..6b0a1531d05 100644
--- a/pkg/traceql/test_examples.yaml
+++ b/pkg/traceql/test_examples.yaml
@@ -51,6 +51,7 @@ valid:
- '{ duration > 1s }'
- '{ 1 < 1h }'
- '{ 1 <= 1.1 }'
+ - '{ event.foo = "bar" }'
# scoped intrinsics
- '{ trace:duration > 2s }'
- '{ trace:rootName = "a" }'
@@ -318,4 +319,3 @@ unsupported:
# parsed and the ast is dumped to stdout. this is a debugging tool
dump:
-- '{ trace:id = "3485734785643"}'
\ No newline at end of file
diff --git a/tempodb/encoding/vparquet4/block_traceql.go b/tempodb/encoding/vparquet4/block_traceql.go
index 83c2f90446e..cea7fe5aaf2 100644
--- a/tempodb/encoding/vparquet4/block_traceql.go
+++ b/tempodb/encoding/vparquet4/block_traceql.go
@@ -882,6 +882,11 @@ const (
columnPathEventName = "rs.list.element.ss.list.element.Spans.list.element.Events.list.element.Name"
columnPathLinkTraceID = "rs.list.element.ss.list.element.Spans.list.element.Links.list.element.TraceID"
columnPathLinkSpanID = "rs.list.element.ss.list.element.Spans.list.element.Links.list.element.SpanID"
+ columnPathEventAttrKey = "rs.list.element.ss.list.element.Spans.list.element.Events.list.element.Attrs.list.element.Key"
+ columnPathEventAttrString = "rs.list.element.ss.list.element.Spans.list.element.Events.list.element.Attrs.list.element.Value.list.element"
+ columnPathEventAttrInt = "rs.list.element.ss.list.element.Spans.list.element.Events.list.element.Attrs.list.element.ValueInt.list.element"
+ columnPathEventAttrDouble = "rs.list.element.ss.list.element.Spans.list.element.Events.list.element.Attrs.list.element.ValueDouble.list.element"
+ columnPathEventAttrBool = "rs.list.element.ss.list.element.Spans.list.element.Events.list.element.Attrs.list.element.ValueBool.list.element"
otherEntrySpansetKey = "spanset"
otherEntrySpanKey = "span"
@@ -1364,27 +1369,38 @@ func (i *mergeSpansetIterator) Close() {
//
// Diagram:
//
-// Span attribute iterator: key -----------------------------
-// ... -------------------------- |
-// Span attribute iterator: valueN ----------------------| | |
-// | | |
-// V V V
-// -------------
-// | attribute |
-// | collector |
-// -------------
-// |
-// | List of attributes
-// |
-// |
-// Span column iterator 1 --------------------------- |
-// ... ------------------------ | |
-// Span column iterator N --------------------- | | |
-// (ex: name, status) | | | |
-// V V V V
-// ------------------
-// | span collector |
-// ------------------
+// Event attribute iterator: key --------------------------------------------
+// ... ----------------------------------------- |
+// Event attribute iterator: valueN --------------------------------------- | |
+// | | |
+// V V V
+// ------------
+// Event column iterator 1 --------------------------------------------- | attribute |
+// (ex: name, time since) | | collector |
+// | ------------
+// | |
+// V V
+// Span attribute iterator: key ------------------------- ------------
+// ... ----------------------- | | event |
+// Span attribute iterator: valueN -------------------| | | | collector |
+// | | | -------------
+// V V V |
+// ------------- |
+// | attribute | | list
+// | collector | | of
+// ------------- | events
+// | |
+// | List |
+// | of span |
+// | attributes |
+// Span column iterator 1 --------------------------- | |
+// ... ------------------------ | | |
+// Span column iterator N --------------------- | | | |
+// (ex: name, status) | | | | |
+// V V V V V
+// -------------------------------------------------
+// | span collector |
+// -------------------------------------------------
// |
// | List of Spans
// Resource attribute |
@@ -1529,7 +1545,7 @@ func createAllIterator(ctx context.Context, primaryIter parquetquery.Iterator, c
innerIterators = append(innerIterators, primaryIter)
}
- eventIter, err := createEventIterator(makeIter, catConditions.event)
+ eventIter, err := createEventIterator(makeIter, primaryIter, catConditions.event, allConditions, selectAll)
if err != nil {
return nil, fmt.Errorf("creating event iterator: %w", err)
}
@@ -1558,12 +1574,13 @@ func createAllIterator(ctx context.Context, primaryIter parquetquery.Iterator, c
return createTraceIterator(makeIter, resourceIter, catConditions.trace, start, end, shardID, shardCount, allConditions, selectAll)
}
-func createEventIterator(makeIter makeIterFn, conditions []traceql.Condition) (parquetquery.Iterator, error) {
+func createEventIterator(makeIter makeIterFn, primaryIter parquetquery.Iterator, conditions []traceql.Condition, allConditions bool, selectAll bool) (parquetquery.Iterator, error) {
if len(conditions) == 0 {
return nil, nil
}
eventIters := make([]parquetquery.Iterator, 0, len(conditions))
+ var genericConditions []traceql.Condition
for _, cond := range conditions {
switch cond.Attribute.Intrinsic {
@@ -1573,14 +1590,57 @@ func createEventIterator(makeIter makeIterFn, conditions []traceql.Condition) (p
return nil, err
}
eventIters = append(eventIters, makeIter(columnPathEventName, pred, columnPathEventName))
+ continue
+ }
+ genericConditions = append(genericConditions, cond)
+ }
+
+ attrIter, err := createAttributeIterator(makeIter, genericConditions, DefinitionLevelResourceSpansILSSpanEventAttrs,
+ columnPathEventAttrKey, columnPathEventAttrString, columnPathEventAttrInt, columnPathEventAttrDouble, columnPathEventAttrBool, allConditions, selectAll)
+ if err != nil {
+ return nil, fmt.Errorf("creating event attribute iterator: %w", err)
+ }
+
+ if attrIter != nil {
+ eventIters = append(eventIters, attrIter)
+ }
+
+ var required []parquetquery.Iterator
+ if primaryIter != nil {
+ required = []parquetquery.Iterator{primaryIter}
+ }
+
+ minCount := 0
+
+ if allConditions {
+ // The final number of expected attributes.
+ distinct := map[string]struct{}{}
+ for _, cond := range conditions {
+ distinct[cond.Attribute.Name] = struct{}{}
}
+ minCount = len(distinct)
}
- if len(eventIters) == 0 {
+ eventCol := &eventCollector{
+ minAttributes: minCount,
+ }
+
+ // This is an optimization for when all of the span conditions must be met.
+ // We simply move all iterators into the required list.
+ if allConditions {
+ required = append(required, eventIters...)
+ eventIters = nil
+ }
+
+ if len(required) == 0 {
+ required = []parquetquery.Iterator{makeIter(columnPathEventName, nil, "")}
+ }
+
+ if len(eventIters) == 0 && len(required) == 0 {
return nil, nil
}
- return parquetquery.NewJoinIterator(DefinitionLevelResourceSpansILSSpanEvent, eventIters, &eventCollector{}, parquetquery.WithPool(pqEventPool)), nil
+ return parquetquery.NewLeftJoinIterator(DefinitionLevelResourceSpansILSSpanEvent, required, eventIters, eventCol, parquetquery.WithPool(pqEventPool))
}
func createLinkIterator(makeIter makeIterFn, conditions []traceql.Condition) (parquetquery.Iterator, error) {
@@ -2799,7 +2859,9 @@ func getEvent() *event {
// eventCollector receives rows from the event columns and joins them together into
// map[key]value entries with the right type.
-type eventCollector struct{}
+type eventCollector struct {
+ minAttributes int
+}
var _ parquetquery.GroupPredicate = (*eventCollector)(nil)
@@ -2823,6 +2885,16 @@ func (c *eventCollector) KeepGroup(res *parquetquery.IteratorResult) bool {
ev = getEvent()
}
+ // extract from attribute collector
+ for _, e := range res.OtherEntries {
+ if v, ok := e.Value.(traceql.Static); ok {
+ ev.attrs = append(ev.attrs, attrVal{
+ a: newEventAttr(e.Key),
+ s: v,
+ })
+ }
+ }
+
for _, e := range res.Entries {
switch e.Key {
case columnPathEventName:
@@ -2833,6 +2905,13 @@ func (c *eventCollector) KeepGroup(res *parquetquery.IteratorResult) bool {
}
}
+ if c.minAttributes > 0 {
+ if len(ev.attrs) < c.minAttributes {
+ putEvent(ev)
+ return false
+ }
+ }
+
res.Reset()
res.AppendOtherValue(otherEntryEventKey, ev)
@@ -2913,6 +2992,10 @@ func newResAttr(name string) traceql.Attribute {
return traceql.NewScopedAttribute(traceql.AttributeScopeResource, false, name)
}
+func newEventAttr(name string) traceql.Attribute {
+ return traceql.NewScopedAttribute(traceql.AttributeScopeEvent, false, name)
+}
+
func unionIfNeeded(definitionLevel int, iters []parquetquery.Iterator, pred parquetquery.GroupPredicate) parquetquery.Iterator {
switch len(iters) {
case 0:
diff --git a/tempodb/encoding/vparquet4/block_traceql_meta_test.go b/tempodb/encoding/vparquet4/block_traceql_meta_test.go
index 0d3d5a8051c..e0f748b8de4 100644
--- a/tempodb/encoding/vparquet4/block_traceql_meta_test.go
+++ b/tempodb/encoding/vparquet4/block_traceql_meta_test.go
@@ -541,6 +541,39 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) {
),
),
},
+ {
+ "Event attribute lookup",
+ makeReq(
+ parse(t, `{event.message =~ "excepti"}`), //
+ ),
+ makeSpansets(
+ makeSpanset(
+ wantTr.TraceID,
+ wantTr.RootSpanName,
+ wantTr.RootServiceName,
+ wantTr.StartTimeUnixNano,
+ wantTr.DurationNano,
+ &span{
+ id: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID,
+ startTimeUnixNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].StartTimeUnixNano,
+ durationNanos: wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].DurationNano,
+ spanAttrs: []attrVal{
+ {traceql.NewIntrinsic(traceql.IntrinsicDuration), traceql.NewStaticDuration(100 * time.Second)},
+ {traceql.NewIntrinsic(traceql.IntrinsicSpanID), traceql.NewStaticString(util.SpanIDToHexString(wantTr.ResourceSpans[0].ScopeSpans[0].Spans[0].SpanID))},
+ },
+ traceAttrs: []attrVal{
+ {traceql.NewIntrinsic(traceql.IntrinsicTraceRootService), traceql.NewStaticString("RootService")},
+ {traceql.NewIntrinsic(traceql.IntrinsicTraceRootSpan), traceql.NewStaticString("RootSpan")},
+ {traceql.NewIntrinsic(traceql.IntrinsicTraceDuration), traceql.NewStaticDuration(100 * time.Millisecond)},
+ {traceql.NewIntrinsic(traceql.IntrinsicTraceID), traceql.NewStaticString(util.TraceIDToHexString(wantTr.TraceID))},
+ },
+ eventAttrs: []attrVal{
+ {traceql.NewScopedAttribute(traceql.AttributeScopeEvent, false, "message"), traceql.NewStaticString("exception")},
+ },
+ },
+ ),
+ ),
+ },
{
"Intrinsic link trace ID lookup",
makeReq(
diff --git a/tempodb/encoding/vparquet4/block_traceql_test.go b/tempodb/encoding/vparquet4/block_traceql_test.go
index 0c1cb4bdf27..8502b412a71 100644
--- a/tempodb/encoding/vparquet4/block_traceql_test.go
+++ b/tempodb/encoding/vparquet4/block_traceql_test.go
@@ -151,6 +151,7 @@ func TestBackendBlockSearchTraceQL(t *testing.T) {
{"span.dedicated.span.4", traceql.MustExtractFetchSpansRequestWithMetadata(`{span.dedicated.span.4 = "dedicated-span-attr-value-4"}`)},
// Events
{"event:name", traceql.MustExtractFetchSpansRequestWithMetadata(`{event:name = "e1"}`)},
+ {"event.message", traceql.MustExtractFetchSpansRequestWithMetadata(`{event.message =~ "exception"}`)},
// Links
{"link:spanID", traceql.MustExtractFetchSpansRequestWithMetadata(`{link:spanID = "1234567890abcdef"}`)},
{"link:traceID", traceql.MustExtractFetchSpansRequestWithMetadata(`{link:traceID = "1234567890abcdef1234567890abcdef"}`)},
@@ -525,6 +526,7 @@ func fullyPopulatedTestTrace(id common.ID) *Trace {
Attrs: []Attribute{
attr("event-attr-key-1", "event-value-1"),
attr("event-attr-key-2", "event-value-2"),
+ attr("message", "exception"),
},
},
{TimeSinceStartNano: 2, Name: "e2", Attrs: []Attribute{}},
diff --git a/tempodb/encoding/vparquet4/schema.go b/tempodb/encoding/vparquet4/schema.go
index 8b41f292fd1..448e40a3323 100644
--- a/tempodb/encoding/vparquet4/schema.go
+++ b/tempodb/encoding/vparquet4/schema.go
@@ -46,14 +46,15 @@ const (
// These definition levels match the schema below
const (
- DefinitionLevelTrace = 0
- DefinitionLevelServiceStats = 1
- DefinitionLevelResourceSpans = 1
- DefinitionLevelResourceAttrs = 2
- DefinitionLevelResourceSpansILSSpan = 3
- DefinitionLevelResourceSpansILSSpanAttrs = 4
- DefinitionLevelResourceSpansILSSpanEvent = 4
- DefinitionLevelResourceSpansILSSpanLink = 4
+ DefinitionLevelTrace = 0
+ DefinitionLevelServiceStats = 1
+ DefinitionLevelResourceSpans = 1
+ DefinitionLevelResourceAttrs = 2
+ DefinitionLevelResourceSpansILSSpan = 3
+ DefinitionLevelResourceSpansILSSpanAttrs = 4
+ DefinitionLevelResourceSpansILSSpanEvent = 4
+ DefinitionLevelResourceSpansILSSpanLink = 4
+ DefinitionLevelResourceSpansILSSpanEventAttrs = 5
FieldResourceAttrKey = "rs.list.element.Resource.Attrs.list.element.Key"
FieldResourceAttrVal = "rs.list.element.Resource.Attrs.list.element.Value.list.element"
diff --git a/tempodb/tempodb_search_test.go b/tempodb/tempodb_search_test.go
index 4e657c7b039..1e4acc33955 100644
--- a/tempodb/tempodb_search_test.go
+++ b/tempodb/tempodb_search_test.go
@@ -34,6 +34,7 @@ import (
"github.com/grafana/tempo/tempodb/encoding/common"
v2 "github.com/grafana/tempo/tempodb/encoding/v2"
"github.com/grafana/tempo/tempodb/encoding/vparquet2"
+ "github.com/grafana/tempo/tempodb/encoding/vparquet4"
"github.com/grafana/tempo/tempodb/wal"
)
@@ -56,6 +57,11 @@ func TestSearchCompleteBlock(t *testing.T) {
autoComplete,
)
})
+ if vers == vparquet4.VersionString {
+ t.Run("event query", func(t *testing.T) {
+ runEventSearchTest(t, vers)
+ })
+ }
}
}
@@ -1528,7 +1534,8 @@ func runCompleteBlockSearchTest(t *testing.T, blockVersion string, runners ...ru
r.EnablePolling(ctx, &mockJobSharder{})
rw := r.(*readerWriter)
- wantID, wantTr, start, end, wantMeta, searchesThatMatch, searchesThatDontMatch := searchTestSuite()
+ wantID, wantTr, start, end, wantMeta := makeExpectedTrace()
+ searchesThatMatch, searchesThatDontMatch := searchTestSuite()
// Write to wal
wal := w.WAL()
@@ -1571,6 +1578,118 @@ func runCompleteBlockSearchTest(t *testing.T, blockVersion string, runners ...ru
// todo: do some compaction and then call runner again
}
+func runEventSearchTest(t *testing.T, blockVersion string) {
+ // only run this test for vparquet4
+ if blockVersion != vparquet4.VersionString {
+ return
+ }
+
+ tempDir := t.TempDir()
+
+ r, w, c, err := New(&Config{
+ Backend: backend.Local,
+ Local: &local.Config{
+ Path: path.Join(tempDir, "traces"),
+ },
+ Block: &common.BlockConfig{
+ IndexDownsampleBytes: 17,
+ BloomFP: .01,
+ BloomShardSizeBytes: 100_000,
+ Version: blockVersion,
+ IndexPageSizeBytes: 1000,
+ RowGroupSizeBytes: 10000,
+ },
+ WAL: &wal.Config{
+ Filepath: path.Join(tempDir, "wal"),
+ IngestionSlack: time.Since(time.Time{}),
+ },
+ Search: &SearchConfig{
+ ChunkSizeBytes: 1_000_000,
+ ReadBufferCount: 8, ReadBufferSizeBytes: 4 * 1024 * 1024,
+ },
+ BlocklistPoll: 0,
+ }, nil, log.NewNopLogger())
+ require.NoError(t, err)
+
+ err = c.EnableCompaction(context.Background(), &CompactorConfig{
+ ChunkSizeBytes: 10,
+ MaxCompactionRange: time.Hour,
+ BlockRetention: 0,
+ CompactedBlockRetention: 0,
+ }, &mockSharder{}, &mockOverrides{})
+ require.NoError(t, err)
+
+ ctx := context.Background()
+ r.EnablePolling(ctx, &mockJobSharder{})
+ rw := r.(*readerWriter)
+
+ wantID, wantTr, start, end, wantMeta := makeExpectedTrace()
+
+ searchesThatMatch := []*tempopb.SearchRequest{
+ {
+ Query: "{ event.exception.message = `random error` }",
+ },
+ {
+ Query: "{ event:name = `event name` }",
+ },
+ }
+
+ // Write to wal
+ wal := w.WAL()
+
+ meta := &backend.BlockMeta{BlockID: uuid.New(), TenantID: testTenantID}
+ head, err := wal.NewBlock(meta, model.CurrentEncoding)
+ require.NoError(t, err)
+ dec := model.MustNewSegmentDecoder(model.CurrentEncoding)
+
+ totalTraces := 50
+ wantTrIdx := rand.Intn(totalTraces)
+ for i := 0; i < totalTraces; i++ {
+ var tr *tempopb.Trace
+ var id []byte
+ if i == wantTrIdx {
+ tr = wantTr
+ id = wantID
+ } else {
+ id = test.ValidTraceID(nil)
+ tr = test.MakeTrace(10, id)
+ }
+ b1, err := dec.PrepareForWrite(tr, start, end)
+ require.NoError(t, err)
+
+ b2, err := dec.ToObject([][]byte{b1})
+ require.NoError(t, err)
+ err = head.Append(id, b2, start, end)
+ require.NoError(t, err)
+ }
+
+ // Complete block
+ block, err := w.CompleteBlock(context.Background(), head)
+ require.NoError(t, err)
+ blockMeta := block.BlockMeta()
+
+ e := traceql.NewEngine()
+
+ for _, req := range searchesThatMatch {
+ fetcher := traceql.NewSpansetFetcherWrapper(func(ctx context.Context, req traceql.FetchSpansRequest) (traceql.FetchSpansResponse, error) {
+ return rw.Fetch(ctx, blockMeta, req, common.DefaultSearchOptions())
+ })
+
+ res, err := e.ExecuteSearch(ctx, req, fetcher)
+ if errors.Is(err, common.ErrUnsupported) {
+ continue
+ }
+
+ require.NoError(t, err, "search request: %+v", req)
+ actual := actualForExpectedMeta(wantMeta, res)
+ require.NotNil(t, actual, "search request: %v", req)
+ actual.SpanSet = nil // todo: add the matching spansets to wantmeta
+ actual.SpanSets = nil
+ actual.ServiceStats = nil
+ require.Equal(t, wantMeta, actual, "search request: %v", req)
+ }
+}
+
func stringKV(k, v string) *v1_common.KeyValue {
return &v1_common.KeyValue{
Key: k,
@@ -1651,13 +1770,11 @@ func addTraceQL(req *tempopb.SearchRequest) {
// - expected - The exact search result that should be returned for every matching request
// - searchesThatMatch - List of search requests that are expected to match the trace
// - searchesThatDontMatch - List of requests that don't match the trace
-func searchTestSuite() (
+func makeExpectedTrace() (
id []byte,
tr *tempopb.Trace,
start, end uint32,
expected *tempopb.TraceSearchMetadata,
- searchesThatMatch []*tempopb.SearchRequest,
- searchesThatDontMatch []*tempopb.SearchRequest,
) {
id = test.ValidTraceID(nil)
@@ -1706,6 +1823,15 @@ func searchTestSuite() (
stringKV("span-dedicated.01", "span-1a"),
stringKV("span-dedicated.02", "span-2a"),
},
+ Events: []*v1.Span_Event{
+ {
+ TimeUnixNano: uint64(1000*time.Second) + 100,
+ Name: "event name",
+ Attributes: []*v1_common.KeyValue{
+ stringKV("exception.message", "random error"),
+ },
+ },
+ },
},
},
},
@@ -1802,7 +1928,13 @@ func searchTestSuite() (
RootServiceName: "RootService",
RootTraceName: "RootSpan",
}
+ return
+}
+func searchTestSuite() (
+ searchesThatMatch []*tempopb.SearchRequest,
+ searchesThatDontMatch []*tempopb.SearchRequest,
+) {
// Matches
searchesThatMatch = []*tempopb.SearchRequest{
{