Files
Martin DisibioandGitHub 8eb14bde39 [TraceQL Metrics] New baseline comparison function (#3695)
* Initial working version of compare

* Clean/rename

* Redo meta labels for type and error. Add required parameter for max values

* Add selectAll support to vParquet4

* vp2 unsupported

* comment out test for now

* Rename select all field

* lint

* compare() return topN and make it optional

* Add callback version of AllAttributes to avoid map alloc

* Fix lookup table

* Hideous but working version with totals per attribute and classification

* less hideous, and restore full time series processing

* instant-ish query

* add selectall attributes

* Adding partial finished test for selectAll, blocked for now

* lint

* Review feedback, reenable using traceid and traceDuration in the filter

* changelog

* Finish vp4 selectall test, refactor some methods to share with test

* Fix comment and remove test hacks
2024-06-21 09:36:32 -04:00

122 lines
2.8 KiB
Go

package traceqlmetrics
import (
"context"
"github.com/grafana/tempo/pkg/traceql"
)
type mockSpan struct {
start uint64
duration uint64
attrs map[traceql.Attribute]traceql.Static
}
var _ traceql.Span = (*mockSpan)(nil)
func newMockSpan() *mockSpan {
return &mockSpan{
attrs: map[traceql.Attribute]traceql.Static{},
}
}
func (m *mockSpan) WithDuration(d uint64) *mockSpan {
m.duration = d
return m
}
func (m *mockSpan) WithAttributes(nameValuePairs ...string) *mockSpan {
for i := 0; i < len(nameValuePairs); i += 2 {
attr := traceql.MustParseIdentifier(nameValuePairs[i])
value := traceql.NewStaticString(nameValuePairs[i+1])
m.attrs[attr] = value
}
return m
}
func (m *mockSpan) WithStart(t uint64) *mockSpan {
m.start = t
return m
}
func (m *mockSpan) WithErr() *mockSpan {
m.attrs[traceql.NewIntrinsic(traceql.IntrinsicStatus)] = traceql.NewStaticStatus(traceql.StatusError)
return m
}
func (m *mockSpan) AllAttributes() map[traceql.Attribute]traceql.Static { return m.attrs }
func (m *mockSpan) ID() []byte { return nil }
func (m *mockSpan) StartTimeUnixNanos() uint64 { return m.start }
func (m *mockSpan) DurationNanos() uint64 { return m.duration }
func (m *mockSpan) DescendantOf([]traceql.Span, []traceql.Span, bool, bool, bool, []traceql.Span) []traceql.Span {
return nil
}
func (m *mockSpan) AttributeFor(a traceql.Attribute) (traceql.Static, bool) {
s, ok := m.attrs[a]
return s, ok
}
func (m *mockSpan) AllAttributesFunc(cb func(traceql.Attribute, traceql.Static)) {
for k, v := range m.attrs {
cb(k, v)
}
}
func (m *mockSpan) SiblingOf([]traceql.Span, []traceql.Span, bool, bool, []traceql.Span) []traceql.Span {
return nil
}
func (m *mockSpan) ChildOf([]traceql.Span, []traceql.Span, bool, bool, bool, []traceql.Span) []traceql.Span {
return nil
}
type mockFetcher struct {
filter traceql.SecondPassFn
Spansets []*traceql.Spanset
}
var (
_ traceql.SpansetFetcher = (*mockFetcher)(nil)
_ traceql.SpansetIterator = (*mockFetcher)(nil)
)
func (m *mockFetcher) Fetch(_ context.Context, req traceql.FetchSpansRequest) (traceql.FetchSpansResponse, error) {
m.filter = req.SecondPass
return traceql.FetchSpansResponse{
Results: m,
}, nil
}
func (m *mockFetcher) Next(context.Context) (*traceql.Spanset, error) {
if len(m.Spansets) == 0 {
return nil, nil
}
// Pop first
s := m.Spansets[0]
m.Spansets = m.Spansets[1:]
// Return as-is
if m.filter == nil {
return s, nil
}
// Run through filter which may return multiple
ss, err := m.filter(s)
if err != nil {
return nil, err
}
// Just return the first - this will need to change if we ever use
// this mock for more advanced stuff
if len(ss) == 0 {
return nil, nil
}
return ss[0], nil
}
func (m *mockFetcher) Close() {}