Skip to content

Commit

Permalink
feat(traceql): implement fmt.Stringer for matchers
Browse files Browse the repository at this point in the history
  • Loading branch information
tdakkota committed May 28, 2024
1 parent 1e68263 commit 56280c0
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 0 deletions.
54 changes: 54 additions & 0 deletions internal/traceql/traceqlengine/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package traceqlengine

import (
"context"
"fmt"
"strconv"
"time"

"go.opentelemetry.io/collector/pdata/ptrace"

"github.com/go-faster/oteldb/internal/iterators"
"github.com/go-faster/oteldb/internal/otelstorage"
"github.com/go-faster/oteldb/internal/traceql"
Expand All @@ -29,6 +33,56 @@ type SpanMatcher struct {
Static traceql.Static
}

// String implements [fmt.Stringer].
func (m SpanMatcher) String() string {
var static string
switch s := m.Static; s.Type {
case traceql.TypeString:
static = strconv.Quote(s.AsString())
case traceql.TypeInt:
static = strconv.FormatInt(s.AsInt(), 10)
case traceql.TypeNumber:
static = strconv.FormatFloat(s.AsNumber(), 'f', -1, 64)
case traceql.TypeBool:
static = strconv.FormatBool(s.AsBool())
case traceql.TypeNil:
static = "nil"
case traceql.TypeDuration:
static = s.AsDuration().String()
case traceql.TypeSpanStatus:
switch status := s.AsSpanStatus(); status {
case ptrace.StatusCodeUnset:
static = "unset"
case ptrace.StatusCodeOk:
static = "ok"
case ptrace.StatusCodeError:
static = "error"
default:
static = fmt.Sprintf("<invalid span status: %#v>", status)
}
case traceql.TypeSpanKind:
switch Kind := s.AsSpanKind(); Kind {
case ptrace.SpanKindUnspecified:
static = "unspecified"
case ptrace.SpanKindInternal:
static = "internal"
case ptrace.SpanKindServer:
static = "server"
case ptrace.SpanKindClient:
static = "client"
case ptrace.SpanKindProducer:
static = "producer"
case ptrace.SpanKindConsumer:
static = "consumer"
default:
static = fmt.Sprintf("<invalid span kind: %#v>", Kind)
}
default:
static = fmt.Sprintf("<invalid static: %#v>", s)
}
return fmt.Sprintf("%s %s %s", m.Attribute, m.Op, static)
}

// SelectSpansetsParams is a storage query params.
type SelectSpansetsParams struct {
Op traceql.SpansetOp // OpAnd, OpOr
Expand Down
96 changes: 96 additions & 0 deletions internal/traceql/traceqlengine/querier_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package traceqlengine

import (
"fmt"
"testing"
"time"

"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/pdata/ptrace"

"github.com/go-faster/oteldb/internal/traceql"
)

func TestSpanMatcher_String(t *testing.T) {
tests := []struct {
m SpanMatcher
want string
}{
{
SpanMatcher{
Attribute: traceql.Attribute{
Prop: traceql.SpanName,
},
Op: traceql.OpEq,
Static: traceql.Static{
Type: traceql.TypeString,
Str: "span",
},
},
`name = "span"`,
},
{
SpanMatcher{
Attribute: traceql.Attribute{
Name: "http.status_code",
},
Op: traceql.OpGte,
Static: traceql.Static{
Type: traceql.TypeInt,
Data: 400,
},
},
`.http.status_code >= 400`,
},
{
SpanMatcher{
Attribute: traceql.Attribute{
Prop: traceql.TraceDuration,
},
Op: traceql.OpLte,
Static: traceql.Static{
Type: traceql.TypeDuration,
Data: uint64(time.Second),
},
},
`traceDuration <= 1s`,
},
{
SpanMatcher{
Attribute: traceql.Attribute{
Prop: traceql.SpanStatus,
},
Op: traceql.OpEq,
Static: traceql.Static{
Type: traceql.TypeSpanStatus,
Data: uint64(ptrace.StatusCodeOk),
},
},
`status = ok`,
},
{
SpanMatcher{
Attribute: traceql.Attribute{
Prop: traceql.SpanKind,
},
Op: traceql.OpEq,
Static: traceql.Static{
Type: traceql.TypeSpanKind,
Data: uint64(ptrace.SpanKindClient),
},
},
`kind = client`,
},
}
for i, tt := range tests {
tt := tt
t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) {
s := tt.m.String()
require.Equal(t, tt.want, s)

// Ensure stringer produces valid TraceQL.
_, err := traceql.Parse("{" + s + "}")
require.NoError(t, err)
})
}
}

0 comments on commit 56280c0

Please sign in to comment.