@@ -11,6 +11,8 @@ import (
11
11
"sync"
12
12
"time"
13
13
14
+ "github.com/MrAlias/bind"
15
+
14
16
"go.opentelemetry.io/otel"
15
17
"go.opentelemetry.io/otel/attribute"
16
18
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace/internal/counter"
@@ -51,12 +53,10 @@ func New(options ...Option) (*Exporter, error) {
51
53
}
52
54
53
55
exporter .selfObservabilityEnabled = true
54
- exporter .selfObservabilityAttrs = []attribute.KeyValue {
55
- semconv .OTelComponentName (fmt .Sprintf ("%s/%d" , otelComponentType , counter .NextExporterID ())),
56
- semconv .OTelComponentTypeKey .String (otelComponentType ),
57
- }
58
- s := attribute .NewSet (exporter .selfObservabilityAttrs ... )
59
- exporter .selfObservabilitySetOpt = metric .WithAttributeSet (s )
56
+
57
+ name := fmt .Sprintf ("%s/%d" , otelComponentType , counter .NextExporterID ())
58
+ cmpnt := semconv .OTelComponentName (name )
59
+ cmpntT := semconv .OTelComponentTypeKey .String (otelComponentType )
60
60
61
61
mp := otel .GetMeterProvider ()
62
62
m := mp .Meter (
@@ -65,18 +65,35 @@ func New(options ...Option) (*Exporter, error) {
65
65
metric .WithSchemaURL (semconv .SchemaURL ),
66
66
)
67
67
68
- var err , e error
69
- if exporter . spanInflightMetric , e = otelconv .NewSDKExporterSpanInflight (m ); e != nil {
68
+ var err error
69
+ if i , e : = otelconv .NewSDKExporterSpanInflight (m ); e != nil {
70
70
e = fmt .Errorf ("failed to create span inflight metric: %w" , e )
71
71
err = errors .Join (err , e )
72
+ } else {
73
+ bound := bind .Int64UpDownCounter (i .Inst (), cmpnt , cmpntT )
74
+ exporter .spanInflightMetric = otelconv.SDKExporterSpanInflight {
75
+ Int64UpDownCounter : bound ,
76
+ }
72
77
}
73
- if exporter .spanExportedMetric , e = otelconv .NewSDKExporterSpanExported (m ); e != nil {
78
+
79
+ if i , e := otelconv .NewSDKExporterSpanExported (m ); e != nil {
74
80
e = fmt .Errorf ("failed to create span exported metric: %w" , e )
75
81
err = errors .Join (err , e )
82
+ } else {
83
+ bound := bind .Int64Counter (i .Inst (), cmpnt , cmpntT )
84
+ exporter .spanExportedMetric = otelconv.SDKExporterSpanExported {
85
+ Int64Counter : bound ,
86
+ }
76
87
}
77
- if exporter .operationDurationMetric , e = otelconv .NewSDKExporterOperationDuration (m ); e != nil {
88
+
89
+ if i , e := otelconv .NewSDKExporterOperationDuration (m ); e != nil {
78
90
e = fmt .Errorf ("failed to create operation duration metric: %w" , e )
79
91
err = errors .Join (err , e )
92
+ } else {
93
+ bound := bind .Float64Histogram (i .Inst (), cmpnt , cmpntT )
94
+ exporter .operationDurationMetric = otelconv.SDKExporterOperationDuration {
95
+ Float64Histogram : bound ,
96
+ }
80
97
}
81
98
82
99
return exporter , err
@@ -92,67 +109,39 @@ type Exporter struct {
92
109
stopped bool
93
110
94
111
selfObservabilityEnabled bool
95
- selfObservabilityAttrs []attribute.KeyValue // selfObservability common attributes
96
- selfObservabilitySetOpt metric.MeasurementOption
97
112
spanInflightMetric otelconv.SDKExporterSpanInflight
98
113
spanExportedMetric otelconv.SDKExporterSpanExported
99
114
operationDurationMetric otelconv.SDKExporterOperationDuration
100
115
}
101
116
102
- var (
103
- measureAttrsPool = sync.Pool {
104
- New : func () any {
105
- // "component.name" + "component.type" + "error.type"
106
- const n = 1 + 1 + 1
107
- s := make ([]attribute.KeyValue , 0 , n )
108
- // Return a pointer to a slice instead of a slice itself
109
- // to avoid allocations on every call.
110
- return & s
111
- },
112
- }
113
-
114
- addOptPool = & sync.Pool {
115
- New : func () any {
116
- const n = 1 // WithAttributeSet
117
- o := make ([]metric.AddOption , 0 , n )
118
- return & o
119
- },
120
- }
121
-
122
- recordOptPool = & sync.Pool {
123
- New : func () any {
124
- const n = 1 // WithAttributeSet
125
- o := make ([]metric.RecordOption , 0 , n )
126
- return & o
127
- },
128
- }
129
- )
117
+ var measureAttrsPool = sync.Pool {
118
+ New : func () any {
119
+ // "error.type"
120
+ const n = 1
121
+ s := make ([]attribute.KeyValue , 0 , n )
122
+ // Return a pointer to a slice instead of a slice itself
123
+ // to avoid allocations on every call.
124
+ return & s
125
+ },
126
+ }
130
127
131
128
// ExportSpans writes spans in json format to stdout.
132
129
func (e * Exporter ) ExportSpans (ctx context.Context , spans []trace.ReadOnlySpan ) (err error ) {
133
130
var success int64
134
131
if e .selfObservabilityEnabled {
135
132
count := int64 (len (spans ))
136
133
137
- addOpt := addOptPool .Get ().(* []metric.AddOption )
138
- defer func () {
139
- * addOpt = (* addOpt )[:0 ]
140
- addOptPool .Put (addOpt )
141
- }()
142
-
143
- * addOpt = append (* addOpt , e .selfObservabilitySetOpt )
144
-
145
- e .spanInflightMetric .Inst ().Add (ctx , count , * addOpt ... )
134
+ e .spanInflightMetric .Add (ctx , count )
146
135
defer func (starting time.Time ) {
147
- e .spanInflightMetric .Inst (). Add (ctx , - count , * addOpt ... )
136
+ e .spanInflightMetric .Add (ctx , - count )
148
137
149
138
// Record the success and duration of the operation.
150
139
//
151
140
// Do not exclude 0 values, as they are valid and indicate no spans
152
141
// were exported which is meaningful for certain aggregations.
153
- e .spanExportedMetric .Inst (). Add (ctx , success , * addOpt ... )
142
+ e .spanExportedMetric .Add (ctx , success )
154
143
155
- mOpt := e . selfObservabilitySetOpt
144
+ set := * attribute . EmptySet ()
156
145
if err != nil {
157
146
// additional attributes for self-observability,
158
147
// only spanExportedMetric and operationDurationMetric are supported.
@@ -161,36 +150,13 @@ func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan)
161
150
* attrs = (* attrs )[:0 ] // reset the slice for reuse
162
151
measureAttrsPool .Put (attrs )
163
152
}()
164
- * attrs = append (* attrs , e .selfObservabilityAttrs ... )
165
153
* attrs = append (* attrs , semconv .ErrorType (err ))
154
+ set = attribute .NewSet (* attrs ... )
166
155
167
- // Do not inefficiently make a copy of attrs by using
168
- // WithAttributes instead of WithAttributeSet.
169
- set := attribute .NewSet (* attrs ... )
170
- mOpt = metric .WithAttributeSet (set )
171
-
172
- // Reset addOpt with new attribute set.
173
- * addOpt = append ((* addOpt )[:0 ], mOpt )
174
-
175
- e .spanExportedMetric .Inst ().Add (
176
- ctx ,
177
- count - success ,
178
- * addOpt ... ,
179
- )
156
+ e .spanExportedMetric .AddSet (ctx , count - success , set )
180
157
}
181
158
182
- recordOpt := recordOptPool .Get ().(* []metric.RecordOption )
183
- defer func () {
184
- * recordOpt = (* recordOpt )[:0 ]
185
- recordOptPool .Put (recordOpt )
186
- }()
187
-
188
- * recordOpt = append (* recordOpt , mOpt )
189
- e .operationDurationMetric .Inst ().Record (
190
- ctx ,
191
- time .Since (starting ).Seconds (),
192
- * recordOpt ... ,
193
- )
159
+ e .operationDurationMetric .RecordSet (ctx , time .Since (starting ).Seconds (), set )
194
160
}(time .Now ())
195
161
}
196
162
0 commit comments