diff --git a/CHANGELOG.md b/CHANGELOG.md index f895db85e97..299cc75faf3 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) * [CHANGE] Make vParquet4 the default block encoding [#3810](https://github.com/grafana/tempo/pull/3810) (@ie-pham) * [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 link attribute querying [#3814](https://github.com/grafana/tempo/pull/3814) (@ie-pham) * [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) diff --git a/docs/sources/tempo/traceql/_index.md b/docs/sources/tempo/traceql/_index.md index 6c410f28770..f41c18f9a0d 100644 --- a/docs/sources/tempo/traceql/_index.md +++ b/docs/sources/tempo/traceql/_index.md @@ -110,7 +110,7 @@ This example searches all Kubernetes clusters called `service-name` that have a ### Attribute fields -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). +TraceQL has four different attribute scopes: span attributes, resource attributes, event attributes, and link 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).

Example of span and resource  attributes.

@@ -142,6 +142,11 @@ You can query for an exception in your span event: { event.exception.message =~ ".*something went wrong.*" } ``` +You can search for an attribute in your link: +``` +{ link.opentracing.ref_type = "child_of" } +``` + ### Unscoped attribute fields Attributes can be unscoped if you are unsure if the requested attribute exists on the span or resource. diff --git a/pkg/parquetquery/iters_test.go b/pkg/parquetquery/iters_test.go index 71f0c0473d9..cec4e081a01 100644 --- a/pkg/parquetquery/iters_test.go +++ b/pkg/parquetquery/iters_test.go @@ -33,8 +33,8 @@ func TestNext(t *testing.T) { rn2 := RowNumber{0, 0, 0, 0, 0, 0, 0, 0} for i := 0; i < 1000; i++ { - r := rand.Intn(MaxDefinitionLevel) - d := rand.Intn(MaxDefinitionLevel) + r := rand.Intn(MaxDefinitionLevel + 1) + d := rand.Intn(MaxDefinitionLevel + 1) rn1.Next(r, d) rn2.nextSlow(r, d) diff --git a/pkg/traceql/expr.y b/pkg/traceql/expr.y index 4c5aa59e5cd..bbb905264ef 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 EVENT_DOT LINK_COLON + PARENT_DOT RESOURCE_DOT SPAN_DOT TRACE_COLON SPAN_COLON EVENT_COLON EVENT_DOT LINK_COLON LINK_DOT COUNT AVG MAX MIN SUM BY COALESCE SELECT END_ATTRIBUTE @@ -419,4 +419,5 @@ attributeField: | 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) } + | LINK_DOT IDENTIFIER END_ATTRIBUTE { $$ = NewScopedAttribute(AttributeScopeLink, false, $2) } ; diff --git a/pkg/traceql/expr.y.go b/pkg/traceql/expr.y.go index a1e6c539321..52bb44396ad 100644 --- a/pkg/traceql/expr.y.go +++ b/pkg/traceql/expr.y.go @@ -103,51 +103,52 @@ const SPAN_COLON = 57390 const EVENT_COLON = 57391 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 +const LINK_DOT = 57394 +const COUNT = 57395 +const AVG = 57396 +const MAX = 57397 +const MIN = 57398 +const SUM = 57399 +const BY = 57400 +const COALESCE = 57401 +const SELECT = 57402 +const END_ATTRIBUTE = 57403 +const RATE = 57404 +const COUNT_OVER_TIME = 57405 +const QUANTILE_OVER_TIME = 57406 +const HISTOGRAM_OVER_TIME = 57407 +const COMPARE = 57408 +const WITH = 57409 +const PIPE = 57410 +const AND = 57411 +const OR = 57412 +const EQ = 57413 +const NEQ = 57414 +const LT = 57415 +const LTE = 57416 +const GT = 57417 +const GTE = 57418 +const NRE = 57419 +const RE = 57420 +const DESC = 57421 +const ANCE = 57422 +const SIBL = 57423 +const NOT_CHILD = 57424 +const NOT_PARENT = 57425 +const NOT_DESC = 57426 +const NOT_ANCE = 57427 +const UNION_CHILD = 57428 +const UNION_PARENT = 57429 +const UNION_DESC = 57430 +const UNION_ANCE = 57431 +const UNION_SIBL = 57432 +const ADD = 57433 +const SUB = 57434 +const NOT = 57435 +const MUL = 57436 +const DIV = 57437 +const MOD = 57438 +const POW = 57439 var yyToknames = [...]string{ "$end", @@ -201,6 +202,7 @@ var yyToknames = [...]string{ "EVENT_COLON", "EVENT_DOT", "LINK_COLON", + "LINK_DOT", "COUNT", "AVG", "MAX", @@ -258,158 +260,160 @@ var yyExca = [...]int{ -1, 1, 1, -1, -2, 0, - -1, 286, + -1, 288, 13, 86, -2, 94, } const yyPrivate = 57344 -const yyLast = 948 +const yyLast = 959 var yyAct = [...]int{ - 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, + 101, 5, 100, 6, 99, 8, 224, 7, 276, 98, + 12, 67, 18, 13, 286, 2, 243, 90, 225, 94, + 77, 325, 201, 70, 66, 230, 231, 30, 232, 233, + 234, 243, 151, 29, 152, 200, 155, 200, 153, 85, + 86, 335, 87, 88, 89, 90, 232, 233, 234, 243, + 181, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 322, 72, 73, + 334, 74, 75, 76, 77, 318, 317, 321, 314, 313, + 312, 207, 87, 88, 89, 90, 74, 75, 76, 77, + 332, 311, 201, 228, 362, 227, 349, 226, 215, 217, + 218, 219, 220, 221, 222, 339, 338, 268, 269, 267, + 367, 223, 252, 370, 293, 246, 247, 248, 340, 366, + 293, 17, 371, 244, 245, 235, 236, 237, 238, 239, + 240, 242, 241, 244, 245, 235, 236, 237, 238, 239, + 240, 242, 241, 68, 11, 230, 231, 341, 232, 233, + 234, 243, 331, 253, 254, 230, 231, 327, 232, 233, + 234, 243, 326, 283, 270, 271, 272, 273, 274, 359, + 293, 358, 293, 356, 357, 284, 235, 236, 237, 238, + 239, 240, 242, 241, 283, 19, 20, 21, 17, 17, + 182, 161, 277, 354, 353, 204, 230, 231, 365, 232, + 233, 234, 243, 151, 355, 152, 345, 155, 344, 153, + 342, 343, 323, 324, 288, 206, 209, 210, 211, 212, + 213, 214, 285, 290, 282, 19, 20, 21, 281, 17, + 284, 161, 23, 26, 24, 25, 27, 14, 162, 15, + 205, 156, 157, 158, 159, 160, 369, 205, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, 280, 279, 278, 208, + 164, 22, 23, 26, 24, 25, 27, 14, 162, 15, + 149, 228, 228, 227, 227, 226, 226, 148, 257, 67, + 147, 67, 146, 330, 228, 258, 227, 259, 226, 328, + 329, 70, 260, 70, 290, 78, 79, 80, 81, 82, + 83, 22, 333, 145, 144, 92, 91, 364, 85, 86, + 84, 87, 88, 89, 90, 85, 86, 350, 87, 88, + 89, 90, 71, 336, 151, 337, 152, 316, 155, 28, + 153, 141, 142, 143, 315, 228, 228, 227, 227, 226, + 226, 351, 352, 361, 360, 256, 228, 255, 227, 251, + 226, 275, 363, 348, 347, 250, 228, 249, 227, 346, + 226, 69, 368, 102, 103, 104, 108, 131, 16, 93, + 95, 4, 150, 107, 105, 106, 110, 109, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 124, 123, 125, 126, 10, 127, 128, 129, 130, 203, + 154, 1, 134, 132, 133, 137, 138, 139, 135, 140, + 136, 320, 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, 319, + 96, 97, 134, 132, 133, 137, 138, 139, 135, 140, + 136, 310, 0, 0, 0, 0, 0, 244, 245, 235, + 236, 237, 238, 239, 240, 242, 241, 72, 73, 0, + 74, 75, 76, 77, 0, 0, 0, 0, 0, 230, + 231, 291, 232, 233, 234, 243, 0, 0, 0, 229, + 96, 97, 0, 0, 0, 244, 245, 235, 236, 237, + 238, 239, 240, 242, 241, 0, 0, 244, 245, 235, + 236, 237, 238, 239, 240, 242, 241, 230, 231, 0, + 232, 233, 234, 243, 0, 0, 0, 0, 0, 230, + 231, 0, 232, 233, 234, 243, 0, 244, 245, 235, + 236, 237, 238, 239, 240, 242, 241, 244, 245, 235, + 236, 237, 238, 239, 240, 242, 241, 202, 0, 230, + 231, 0, 232, 233, 234, 243, 0, 0, 0, 230, + 231, 0, 232, 233, 234, 243, 78, 79, 80, 81, + 82, 83, 199, 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, 0, 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, - 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, + 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, 0, 17, 0, + 289, 0, 19, 20, 21, 50, 17, 49, 287, 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, 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, 161, 19, 20, 21, 0, 0, 0, 216, 0, + 22, 261, 0, 262, 264, 265, 0, 263, 22, 0, + 0, 0, 65, 3, 0, 266, 0, 0, 0, 0, + 0, 0, 0, 0, 23, 26, 24, 25, 27, 14, + 0, 15, 23, 26, 24, 25, 27, 0, 0, 23, + 26, 24, 25, 27, 163, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 131, 0, 22, 0, 0, 0, 0, 0, 0, + 0, 22, 0, 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, 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, + 128, 129, 130, 0, 0, 0, 134, 132, 133, 137, + 138, 139, 135, 140, 136, 102, 103, 104, 108, 0, + 0, 0, 208, 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{ - 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, + 781, -34, -41, 633, -1000, 611, -1000, -1000, -1000, 781, + -1000, 532, -1000, 525, 304, 303, -1000, 368, -1000, -1000, + -1000, -1000, 335, 302, 301, 280, 278, 275, -1000, 268, + 179, 258, 258, 258, 258, 258, 258, 258, 258, 258, + 258, 258, 258, 258, 258, 258, 258, 258, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 589, 24, 564, 396, 182, + 234, 910, 257, 257, 257, 257, 257, 257, -1000, -1000, + -1000, -1000, -1000, -1000, 796, 796, 796, 796, 796, 796, + 796, 418, 862, -1000, 498, 418, 418, 418, -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, 363, 361, 355, 108, 353, 351, 261, 784, 80, + 65, -1000, -1000, -1000, 151, 418, 418, 418, 418, 188, + -1000, 611, -1000, -1000, -1000, -1000, 256, 255, 254, 216, + 212, 789, 210, 680, 726, -1000, -1000, -1000, -1000, 680, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 648, 179, -1000, -1000, -1000, -1000, 648, -1000, -1000, -1000, + -1000, 662, 178, -1000, -1000, -1000, -1000, 662, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -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, + -1000, 219, -1000, -1000, -1000, -1000, -23, -1000, 718, -8, + -8, -77, -77, -77, -77, -52, 796, -12, -12, -80, + -80, -80, -80, 488, 235, -1000, -1000, -1000, -1000, -1000, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 458, -48, -48, 30, + 19, 18, 17, 340, 333, 15, 14, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 446, 408, 64, 54, 199, -1000, -50, 149, 144, + 862, 862, 111, 564, 227, 139, 22, 726, -1000, 718, + -46, -1000, -1000, 862, -48, -48, -81, -81, -81, -66, + -66, -66, -66, -66, -66, -66, -66, -81, 105, 105, + -1000, -1000, -1000, -1000, -1000, 9, -20, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 188, 932, 48, 47, 104, 134, + 197, -1000, 219, -1000, -1000, -1000, -1000, -1000, 196, 194, + 357, 38, -1000, 321, 862, 862, 180, -1000, -1000, 192, + 160, 158, 156, 347, 36, 862, -1000, 311, -1000, -1000, + -1000, -1000, 186, 106, 96, 862, -1000, 240, 100, 109, + -1000, -1000, } var yyPgo = [...]int{ - 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, + 0, 411, 7, 410, 5, 6, 1, 822, 404, 14, + 10, 3, 320, 382, 381, 143, 13, 378, 371, 12, + 19, 9, 4, 2, 0, 18, 369, 8, 361, 339, } var yyR1 = [...]int{ @@ -432,7 +436,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, 23, 23, } var yyR2 = [...]int{ @@ -455,47 +459,48 @@ 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, 3, + 4, 4, 3, 3, } var yyChk = [...]int{ -1000, -1, -9, -7, -14, -6, -11, -2, -4, 12, - -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, + -8, -15, -10, -16, 58, 60, -17, 10, -19, 6, + 7, 8, 92, 53, 55, 56, 54, 57, -29, 67, + 68, 69, 75, 73, 79, 80, 70, 81, 82, 83, + 84, 85, 77, 86, 87, 88, 89, 90, 69, 75, + 73, 79, 80, 70, 81, 82, 83, 77, 85, 84, + 86, 87, 90, 89, 88, -7, -9, -6, -15, -18, + -16, -12, 91, 92, 94, 95, 96, 97, 71, 72, + 73, 74, 75, 76, -12, 91, 92, 94, 95, 96, + 97, 12, 12, 11, -20, 12, 92, 93, -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, 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, + 40, 9, 45, 46, 44, 50, 52, 47, 48, 49, + 51, 6, 7, 8, 12, 12, 12, 12, 12, 12, + -13, -6, -11, -2, -3, -4, 62, 63, 64, 65, + 66, 12, 59, -7, 12, -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, + -7, -6, 12, -6, -6, -6, -6, -6, -6, -6, + -6, -6, -6, -6, -6, -6, -6, -6, -6, 13, + 13, 68, 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, + 91, 92, 94, 95, 96, 71, 72, 73, 74, 75, + 76, 78, 77, 97, 69, 70, -20, -20, -20, 4, + 4, 4, 4, 45, 46, 4, 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, 61, 61, 61, 61, 4, 4, 61, 61, 13, + 13, 13, 13, 13, 14, 71, 13, 13, -25, -25, + -10, 13, 68, -25, 61, 61, -27, -21, 58, 58, + 14, 13, 13, 14, 12, 12, -26, 7, 6, 58, + 6, -5, -5, 14, 13, 12, 13, 14, 13, 13, + 7, 6, 58, -5, 6, 12, 13, 14, -5, 6, + 13, 13, } var yyDef = [...]int{ @@ -513,29 +518,30 @@ var yyDef = [...]int{ 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, 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, 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, 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, + 0, 0, 0, 0, 0, 0, 0, 138, 139, 0, + 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, 193, 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{ @@ -552,7 +558,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, 96, + 92, 93, 94, 95, 96, 97, } var yyTok3 = [...]int{ 0, @@ -2047,6 +2053,12 @@ yydefault: { yyVAL.attributeField = NewScopedAttribute(AttributeScopeEvent, false, yyDollar[2].staticStr) } + case 193: + yyDollar = yyS[yypt-3 : yypt+1] +//line pkg/traceql/expr.y:422 + { + yyVAL.attributeField = NewScopedAttribute(AttributeScopeLink, false, yyDollar[2].staticStr) + } } goto yystack /* stack new state and value */ } diff --git a/pkg/traceql/lexer.go b/pkg/traceql/lexer.go index afc07981fdb..a1ad1aa096c 100644 --- a/pkg/traceql/lexer.go +++ b/pkg/traceql/lexer.go @@ -87,6 +87,7 @@ var tokens = map[string]int{ "event:": EVENT_COLON, "link:": LINK_COLON, "event.": EVENT_DOT, + "link.": LINK_DOT, "count": COUNT, "avg": AVG, "max": MAX, @@ -215,7 +216,8 @@ func (l *lexer) Lex(lval *yySymType) int { multiTok == TRACE_COLON || multiTok == EVENT_COLON || multiTok == LINK_COLON || - multiTok == EVENT_DOT { + multiTok == EVENT_DOT || + multiTok == LINK_DOT { l.currentScope = multiTok } @@ -406,5 +408,6 @@ func startsAttribute(tok int) bool { tok == RESOURCE_DOT || tok == SPAN_DOT || tok == PARENT_DOT || - tok == EVENT_DOT + tok == EVENT_DOT || + tok == LINK_DOT } diff --git a/pkg/traceql/lexer_test.go b/pkg/traceql/lexer_test.go index 3767d343f66..66123ea175a 100644 --- a/pkg/traceql/lexer_test.go +++ b/pkg/traceql/lexer_test.go @@ -51,6 +51,13 @@ func TestLexerAttributes(t *testing.T) { {`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}}, + // link attributes + {`link.foo`, []int{LINK_DOT, IDENTIFIER, END_ATTRIBUTE}}, + {`link.count`, []int{LINK_DOT, IDENTIFIER, END_ATTRIBUTE}}, + {`link.count`, []int{LINK_DOT, IDENTIFIER, END_ATTRIBUTE}}, + {`link.foo3`, []int{LINK_DOT, IDENTIFIER, END_ATTRIBUTE}}, + {`link.foo+bar`, []int{LINK_DOT, IDENTIFIER, END_ATTRIBUTE}}, + {`link.foo-bar`, []int{LINK_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 e9d1ac8ed70..c067a0a0813 100644 --- a/pkg/traceql/parse_test.go +++ b/pkg/traceql/parse_test.go @@ -1021,6 +1021,7 @@ func TestAttributes(t *testing.T) { {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: "link.foo.bar", expected: NewScopedAttribute(AttributeScopeLink, 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 6b0a1531d05..e4b5c90dca2 100644 --- a/pkg/traceql/test_examples.yaml +++ b/pkg/traceql/test_examples.yaml @@ -52,6 +52,7 @@ valid: - '{ 1 < 1h }' - '{ 1 <= 1.1 }' - '{ event.foo = "bar" }' + - '{ link.foo = "bar" }' # scoped intrinsics - '{ trace:duration > 2s }' - '{ trace:rootName = "a" }' diff --git a/tempodb/encoding/vparquet4/block_traceql.go b/tempodb/encoding/vparquet4/block_traceql.go index cea7fe5aaf2..eb32d96a004 100644 --- a/tempodb/encoding/vparquet4/block_traceql.go +++ b/tempodb/encoding/vparquet4/block_traceql.go @@ -887,6 +887,11 @@ const ( 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" + columnPathLinkAttrKey = "rs.list.element.ss.list.element.Spans.list.element.Links.list.element.Attrs.list.element.Key" + columnPathLinkAttrString = "rs.list.element.ss.list.element.Spans.list.element.Links.list.element.Attrs.list.element.Value.list.element" + columnPathLinkAttrInt = "rs.list.element.ss.list.element.Spans.list.element.Links.list.element.Attrs.list.element.ValueInt.list.element" + columnPathLinkAttrDouble = "rs.list.element.ss.list.element.Spans.list.element.Links.list.element.Attrs.list.element.ValueDouble.list.element" + columnPathLinkAttrBool = "rs.list.element.ss.list.element.Spans.list.element.Links.list.element.Attrs.list.element.ValueBool.list.element" otherEntrySpansetKey = "spanset" otherEntrySpanKey = "span" @@ -1368,36 +1373,47 @@ func (i *mergeSpansetIterator) Close() { // matching columns using parquetquery.Predicates. Results are collected The final return is an iterator where each result is 1 Spanset for each trace. // // Diagram: -// -// 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 +// ------------ +// Link attribute iterator: key -----------------------------------------------------> | attribute | +// ... ------------------------------------------------------> | collector | +// Link attribute iterator: valueN -----------------------------------------------------> | | +// ------------ +// | +// | +// Link column iterator 1 --------------------------------------------------------------------- | +// (ex: span ID, trace ID) | | +// | | +// | | +// V V +// Event attribute iterator: key -------------------------------------------- ------------ +// ... ----------------------------------------- | | link | +// Event attribute iterator: valueN --------------------------------------- | | | collector | +// | | | ------------ +// 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 V // ------------------------------------------------- // | span collector | // ------------------------------------------------- @@ -1553,7 +1569,7 @@ func createAllIterator(ctx context.Context, primaryIter parquetquery.Iterator, c innerIterators = append(innerIterators, eventIter) } - linkIter, err := createLinkIterator(makeIter, catConditions.link) + linkIter, err := createLinkIterator(makeIter, catConditions.link, allConditions, selectAll) if err != nil { return nil, fmt.Errorf("creating link iterator: %w", err) } @@ -1643,12 +1659,13 @@ func createEventIterator(makeIter makeIterFn, primaryIter parquetquery.Iterator, return parquetquery.NewLeftJoinIterator(DefinitionLevelResourceSpansILSSpanEvent, required, eventIters, eventCol, parquetquery.WithPool(pqEventPool)) } -func createLinkIterator(makeIter makeIterFn, conditions []traceql.Condition) (parquetquery.Iterator, error) { +func createLinkIterator(makeIter makeIterFn, conditions []traceql.Condition, allConditions, selectAll bool) (parquetquery.Iterator, error) { if len(conditions) == 0 { return nil, nil } linkIters := make([]parquetquery.Iterator, 0, len(conditions)) + var genericConditions []traceql.Condition for _, cond := range conditions { switch cond.Attribute.Intrinsic { @@ -1658,6 +1675,7 @@ func createLinkIterator(makeIter makeIterFn, conditions []traceql.Condition) (pa return nil, err } linkIters = append(linkIters, makeIter(columnPathLinkTraceID, pred, columnPathLinkTraceID)) + continue case traceql.IntrinsicLinkSpanID: pred, err := createBytesPredicate(cond.Op, cond.Operands, false) @@ -1665,14 +1683,51 @@ func createLinkIterator(makeIter makeIterFn, conditions []traceql.Condition) (pa return nil, err } linkIters = append(linkIters, makeIter(columnPathLinkSpanID, pred, columnPathLinkSpanID)) + continue } + genericConditions = append(genericConditions, cond) + } + + attrIter, err := createAttributeIterator(makeIter, genericConditions, DefinitionLevelResourceSpansILSSpanLinkAttrs, + columnPathLinkAttrKey, columnPathLinkAttrString, columnPathLinkAttrInt, columnPathLinkAttrDouble, columnPathLinkAttrBool, allConditions, selectAll) + if err != nil { + return nil, fmt.Errorf("creating link attribute iterator: %w", err) + } + + if attrIter != nil { + linkIters = append(linkIters, attrIter) + } + + var required []parquetquery.Iterator + 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) + } + + linkCol := &linkCollector{ + minAttributes: minCount, + } + + if allConditions { + required = append(required, linkIters...) + linkIters = nil + } + + if len(required) == 0 { + required = []parquetquery.Iterator{makeIter(columnPathLinkSpanID, nil, "")} } - if len(linkIters) == 0 { + if len(linkIters) == 0 && len(required) == 0 { return nil, nil } - return parquetquery.NewJoinIterator(DefinitionLevelResourceSpansILSSpanLink, linkIters, &linkCollector{}, parquetquery.WithPool(pqLinkPool)), nil + return parquetquery.NewLeftJoinIterator(DefinitionLevelResourceSpansILSSpanEvent, required, linkIters, linkCol, parquetquery.WithPool(pqLinkPool)) } // createSpanIterator iterates through all span-level columns, groups them into rows representing @@ -2939,7 +2994,9 @@ func getLink() *link { // linkCollector receives rows from the link columns and joins them together into // map[key]value entries with the right type. -type linkCollector struct{} +type linkCollector struct { + minAttributes int +} var _ parquetquery.GroupPredicate = (*linkCollector)(nil) @@ -2963,6 +3020,16 @@ func (c *linkCollector) KeepGroup(res *parquetquery.IteratorResult) bool { l = getLink() } + // extract from attribute collector + for _, e := range res.OtherEntries { + if v, ok := e.Value.(traceql.Static); ok { + l.attrs = append(l.attrs, attrVal{ + a: newLinkAttr(e.Key), + s: v, + }) + } + } + for _, e := range res.Entries { switch e.Key { case columnPathLinkTraceID: @@ -2978,6 +3045,13 @@ func (c *linkCollector) KeepGroup(res *parquetquery.IteratorResult) bool { } } + if c.minAttributes > 0 { + if len(l.attrs) < c.minAttributes { + putLink(l) + return false + } + } + res.Reset() res.AppendOtherValue(otherEntryLinkKey, l) @@ -2996,6 +3070,10 @@ func newEventAttr(name string) traceql.Attribute { return traceql.NewScopedAttribute(traceql.AttributeScopeEvent, false, name) } +func newLinkAttr(name string) traceql.Attribute { + return traceql.NewScopedAttribute(traceql.AttributeScopeLink, 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 e0f748b8de4..d3c266175d2 100644 --- a/tempodb/encoding/vparquet4/block_traceql_meta_test.go +++ b/tempodb/encoding/vparquet4/block_traceql_meta_test.go @@ -640,6 +640,39 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { ), ), }, + { + "Link attribute lookup", + makeReq( + parse(t, `{link.opentracing.ref_type =~ "child"}`), // + ), + 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))}, + }, + linkAttrs: []attrVal{ + {traceql.NewScopedAttribute(traceql.AttributeScopeLink, false, "opentracing.ref_type"), traceql.NewStaticString("child-of")}, + }, + }, + ), + ), + }, } for _, tc := range testCases { @@ -678,6 +711,12 @@ func TestBackendBlockSearchFetchMetaData(t *testing.T) { if len(spn.spanAttrs) == 0 { spn.spanAttrs = nil } + if len(spn.linkAttrs) == 0 { + spn.linkAttrs = nil + } + if len(spn.eventAttrs) == 0 { + spn.eventAttrs = nil + } // sort actual attrs to get consistent comparisons sortSpanAttrs(spn) diff --git a/tempodb/encoding/vparquet4/block_traceql_test.go b/tempodb/encoding/vparquet4/block_traceql_test.go index 8502b412a71..c94fcad3f1c 100644 --- a/tempodb/encoding/vparquet4/block_traceql_test.go +++ b/tempodb/encoding/vparquet4/block_traceql_test.go @@ -155,6 +155,7 @@ func TestBackendBlockSearchTraceQL(t *testing.T) { // Links {"link:spanID", traceql.MustExtractFetchSpansRequestWithMetadata(`{link:spanID = "1234567890abcdef"}`)}, {"link:traceID", traceql.MustExtractFetchSpansRequestWithMetadata(`{link:traceID = "1234567890abcdef1234567890abcdef"}`)}, + {"link.opentracing.ref_type", traceql.MustExtractFetchSpansRequestWithMetadata(`{link.opentracing.ref_type = "child-of"}`)}, // Basic data types and operations {".float = 456.78", traceql.MustExtractFetchSpansRequestWithMetadata(`{.float = 456.78}`)}, // Float == {".float != 456.79", traceql.MustExtractFetchSpansRequestWithMetadata(`{.float != 456.79}`)}, // Float != @@ -418,7 +419,7 @@ func fullyPopulatedTestTrace(id common.ID) *Trace { TraceState: "state", DroppedAttributesCount: 3, Attrs: []Attribute{ - attr("link-attr-key-1", "link-value-1"), + attr("opentracing.ref_type", "child-of"), }, }, } diff --git a/tempodb/encoding/vparquet4/schema.go b/tempodb/encoding/vparquet4/schema.go index 448e40a3323..25d71d2e6b4 100644 --- a/tempodb/encoding/vparquet4/schema.go +++ b/tempodb/encoding/vparquet4/schema.go @@ -55,6 +55,7 @@ const ( DefinitionLevelResourceSpansILSSpanEvent = 4 DefinitionLevelResourceSpansILSSpanLink = 4 DefinitionLevelResourceSpansILSSpanEventAttrs = 5 + DefinitionLevelResourceSpansILSSpanLinkAttrs = 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 1e4acc33955..232e0a668de 100644 --- a/tempodb/tempodb_search_test.go +++ b/tempodb/tempodb_search_test.go @@ -58,8 +58,8 @@ func TestSearchCompleteBlock(t *testing.T) { ) }) if vers == vparquet4.VersionString { - t.Run("event query", func(t *testing.T) { - runEventSearchTest(t, vers) + t.Run("event/link query", func(t *testing.T) { + runEventLinkSearchTest(t, vers) }) } } @@ -1578,7 +1578,7 @@ 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) { +func runEventLinkSearchTest(t *testing.T, blockVersion string) { // only run this test for vparquet4 if blockVersion != vparquet4.VersionString { return @@ -1624,6 +1624,7 @@ func runEventSearchTest(t *testing.T, blockVersion string) { rw := r.(*readerWriter) wantID, wantTr, start, end, wantMeta := makeExpectedTrace() + wantIDText := util.TraceIDToHexString(wantID) searchesThatMatch := []*tempopb.SearchRequest{ { @@ -1632,6 +1633,12 @@ func runEventSearchTest(t *testing.T, blockVersion string) { { Query: "{ event:name = `event name` }", }, + { + Query: "{ link.relation = `child-of` }", + }, + { + Query: "{ link:traceID = `" + wantIDText + "` }", + }, } // Write to wal @@ -1832,6 +1839,15 @@ func makeExpectedTrace() ( }, }, }, + Links: []*v1.Span_Link{ + { + TraceId: id, + SpanId: []byte{4, 5, 6}, + Attributes: []*v1_common.KeyValue{ + stringKV("relation", "child-of"), + }, + }, + }, }, }, },