Skip to content

Commit

Permalink
[jptrace] Add SpanIter helper function (jaegertracing#6407)
Browse files Browse the repository at this point in the history
This will be especially useful once we upgrade to Go 1.23, where we'd be
able to do
```
var tr ptrace.Traces
for _, span := range jptrace.SpanIter(tr) {
}
```

---------

Signed-off-by: Yuri Shkuro <[email protected]>
Signed-off-by: Mahad Zaryab <[email protected]>
Co-authored-by: Mahad Zaryab <[email protected]>
Co-authored-by: Mahad Zaryab <[email protected]>
  • Loading branch information
3 people authored Dec 30, 2024
1 parent 7117fa8 commit fc518ce
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 0 deletions.
40 changes: 40 additions & 0 deletions internal/jptrace/spaniter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) 2024 The Jaeger Authors.
// SPDX-License-Identifier: Apache-2.0

package jptrace

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

"github.com/jaegertracing/jaeger/pkg/iter"
)

type SpanIterPos struct {
Resource ptrace.ResourceSpans
ResourceIndex int
Scope ptrace.ScopeSpans
ScopeIndex int
}

// SpanIter iterates over all spans in the provided ptrace.Traces and yields each span.
func SpanIter(traces ptrace.Traces) iter.Seq2[SpanIterPos, ptrace.Span] {
return func(yield func(SpanIterPos, ptrace.Span) bool) {
var pos SpanIterPos
for i := 0; i < traces.ResourceSpans().Len(); i++ {
resource := traces.ResourceSpans().At(i)
pos.Resource = resource
pos.ResourceIndex = i
for j := 0; j < resource.ScopeSpans().Len(); j++ {
scope := resource.ScopeSpans().At(j)
pos.Scope = scope
pos.ScopeIndex = j
for k := 0; k < scope.Spans().Len(); k++ {
span := scope.Spans().At(k)
if !yield(pos, span) {
return
}
}
}
}
}
}
94 changes: 94 additions & 0 deletions internal/jptrace/spaniter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright (c) 2024 The Jaeger Authors.
// SPDX-License-Identifier: Apache-2.0

package jptrace

import (
"testing"

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

func TestSpanIter(t *testing.T) {
traces := ptrace.NewTraces()

resource1 := traces.ResourceSpans().AppendEmpty()
scope1 := resource1.ScopeSpans().AppendEmpty()

span1 := scope1.Spans().AppendEmpty()
span1.SetName("span-1")

span2 := scope1.Spans().AppendEmpty()
span2.SetName("span-2")

resource2 := traces.ResourceSpans().AppendEmpty()
scope2 := resource2.ScopeSpans().AppendEmpty()

span3 := scope2.Spans().AppendEmpty()
span3.SetName("span-3")

scope3 := resource2.ScopeSpans().AppendEmpty()

span4 := scope3.Spans().AppendEmpty()
span4.SetName("span-4")

spanIter := SpanIter(traces)
var spans []ptrace.Span
var positions []SpanIterPos
spanIter(func(pos SpanIterPos, span ptrace.Span) bool {
spans = append(spans, span)
positions = append(positions, pos)
return true
})

assert.Len(t, spans, 4)
assert.Equal(t, "span-1", spans[0].Name())
assert.Equal(t, "span-2", spans[1].Name())
assert.Equal(t, "span-3", spans[2].Name())
assert.Equal(t, "span-4", spans[3].Name())

assert.Len(t, positions, 4)
assert.Equal(t, 0, positions[0].ResourceIndex)
assert.Equal(t, resource1, positions[0].Resource)
assert.Equal(t, 0, positions[0].ScopeIndex)
assert.Equal(t, scope1, positions[0].Scope)

assert.Equal(t, 0, positions[1].ResourceIndex)
assert.Equal(t, resource1, positions[1].Resource)
assert.Equal(t, 0, positions[1].ScopeIndex)
assert.Equal(t, scope1, positions[1].Scope)

assert.Equal(t, 1, positions[2].ResourceIndex)
assert.Equal(t, resource2, positions[2].Resource)
assert.Equal(t, 0, positions[2].ScopeIndex)
assert.Equal(t, scope2, positions[2].Scope)

assert.Equal(t, 1, positions[3].ResourceIndex)
assert.Equal(t, resource2, positions[3].Resource)
assert.Equal(t, 1, positions[3].ScopeIndex)
assert.Equal(t, scope3, positions[3].Scope)
}

func TestSpanIterStopIteration(t *testing.T) {
traces := ptrace.NewTraces()

resource1 := traces.ResourceSpans().AppendEmpty()
scope1 := resource1.ScopeSpans().AppendEmpty()

span1 := scope1.Spans().AppendEmpty()
span1.SetName("span-1")

span2 := scope1.Spans().AppendEmpty()
span2.SetName("span-2")

spanIter := SpanIter(traces)
var spans []ptrace.Span
spanIter(func(_ SpanIterPos, span ptrace.Span) bool {
spans = append(spans, span)
return false
})

assert.Len(t, spans, 1)
assert.Equal(t, "span-1", spans[0].Name())
}

0 comments on commit fc518ce

Please sign in to comment.