-
Notifications
You must be signed in to change notification settings - Fork 7
/
exporter.go
148 lines (122 loc) · 3.9 KB
/
exporter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package tracetest
import (
"fmt"
"strings"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/tracetest"
)
// TestTraceExporter is the interface for test trace span exporters.
type TestTraceExporter interface {
trace.SpanExporter
Exporter() trace.SpanExporter
Reset() TestTraceExporter
Spans() tracetest.SpanStubs
Span(name string) (tracetest.SpanStub, error)
HasSpan(expectedName string, expectedAttributes ...attribute.KeyValue) bool
ContainSpan(expectedName string, expectedAttributes ...attribute.KeyValue) bool
Dump()
}
// DefaultTestTraceExporter is the default [TestTraceExporter] implementation.
type DefaultTestTraceExporter struct {
*tracetest.InMemoryExporter
}
// NewDefaultTestTraceExporter returns a [DefaultTestTraceExporter], implementing [TestTraceExporter].
func NewDefaultTestTraceExporter() TestTraceExporter {
return &DefaultTestTraceExporter{
tracetest.NewInMemoryExporter(),
}
}
// Exporter returns the in memory internal exporter.
func (e *DefaultTestTraceExporter) Exporter() trace.SpanExporter {
return e.InMemoryExporter
}
// Reset resets the in memory internal exporter.
func (e *DefaultTestTraceExporter) Reset() TestTraceExporter {
e.InMemoryExporter.Reset()
return e
}
// Spans get the [tracetest.SpanStubs] from the in memory internal exporter.
func (e *DefaultTestTraceExporter) Spans() tracetest.SpanStubs {
return e.InMemoryExporter.GetSpans()
}
// Span get a specific [tracetest.SpanStub] from the in memory internal exporter by name.
func (e *DefaultTestTraceExporter) Span(name string) (tracetest.SpanStub, error) {
for _, span := range e.InMemoryExporter.GetSpans() {
if span.Name == name {
return span, nil
}
}
return tracetest.SpanStub{}, fmt.Errorf("span with name %s cannot be found", name)
}
// HasSpan return true if a trace span from the in memory internal buffer is exactly matching provided name and attributes.
func (e *DefaultTestTraceExporter) HasSpan(expectedName string, expectedAttributes ...attribute.KeyValue) bool {
for _, span := range e.InMemoryExporter.GetSpans() {
if span.Name == expectedName {
if len(expectedAttributes) == 0 {
return true
}
allMatch := true
for _, expectedAttribute := range expectedAttributes {
found := false
for _, spanAttribute := range span.Attributes {
if spanAttribute.Key == expectedAttribute.Key {
found = true
allMatch = allMatch && spanAttribute.Value == expectedAttribute.Value
}
}
if !found {
return false
}
}
if allMatch {
return true
}
}
}
return false
}
// ContainSpan return true if a trace span from the in memory internal buffer is partially matching provided name and attributes.
//
//nolint:cyclop,gocognit,exhaustive
func (e *DefaultTestTraceExporter) ContainSpan(expectedName string, expectedAttributes ...attribute.KeyValue) bool {
for _, span := range e.InMemoryExporter.GetSpans() {
if span.Name == expectedName {
if len(expectedAttributes) == 0 {
return true
}
allMatch := true
for _, expectedAttribute := range expectedAttributes {
found := false
for _, spanAttribute := range span.Attributes {
if spanAttribute.Key == expectedAttribute.Key {
found = true
switch spanAttribute.Value.Type() {
case attribute.STRING:
allMatch = allMatch && strings.Contains(
spanAttribute.Value.AsString(),
expectedAttribute.Value.AsString(),
)
default:
allMatch = allMatch && spanAttribute.Value == expectedAttribute.Value
}
}
}
if !found {
return false
}
}
if allMatch {
return true
}
}
}
return false
}
// Dump prints the [tracetest.SpanStubs] snapshots from the in memory internal exporter, for debugging purposes.
func (e *DefaultTestTraceExporter) Dump() {
for _, span := range e.Spans().Snapshots() {
//nolint:forbidigo
fmt.Printf("%v\n", span)
}
}