@@ -6,19 +6,21 @@ package stdoutlog // import "go.opentelemetry.io/otel/exporters/stdout/stdoutlog
6
6
import (
7
7
"context"
8
8
"encoding/json"
9
+ "errors"
9
10
"fmt"
10
11
"sync"
11
12
"sync/atomic"
12
13
"time"
13
14
14
15
"go.opentelemetry.io/otel"
15
16
"go.opentelemetry.io/otel/attribute"
17
+ "go.opentelemetry.io/otel/exporters/stdout/stdoutlog/internal/counter"
16
18
"go.opentelemetry.io/otel/exporters/stdout/stdoutlog/internal/x"
17
19
"go.opentelemetry.io/otel/metric"
18
20
"go.opentelemetry.io/otel/sdk"
19
21
"go.opentelemetry.io/otel/sdk/log"
20
- semconv "go.opentelemetry.io/otel/semconv/v1.36 .0"
21
- "go.opentelemetry.io/otel/semconv/v1.36 .0/otelconv"
22
+ semconv "go.opentelemetry.io/otel/semconv/v1.37 .0"
23
+ "go.opentelemetry.io/otel/semconv/v1.37 .0/otelconv"
22
24
)
23
25
24
26
// otelComponentType is a name identifying the type of the OpenTelemetry component.
@@ -29,12 +31,12 @@ var _ log.Exporter = &Exporter{}
29
31
// Exporter writes JSON-encoded log records to an [io.Writer] ([os.Stdout] by default).
30
32
// Exporter must be created with [New].
31
33
type Exporter struct {
32
- encoder atomic.Pointer [json.Encoder ]
33
- timestamps bool
34
- selfObservability * selfObservability
34
+ encoder atomic.Pointer [json.Encoder ]
35
+ timestamps bool
36
+ inst * instrumentationImpl
35
37
}
36
38
37
- type selfObservability struct {
39
+ type instrumentationImpl struct {
38
40
attrs []attribute.KeyValue
39
41
inflightMetric otelconv.SDKExporterLogInflight
40
42
exportedMetric otelconv.SDKExporterLogExported
@@ -54,23 +56,23 @@ func New(options ...Option) (*Exporter, error) {
54
56
timestamps : cfg .Timestamps ,
55
57
}
56
58
e .encoder .Store (enc )
57
- selfObs , err := newSelfObservability ()
59
+ selfObs , err := newInstrumentation ()
58
60
if err != nil {
59
61
return nil , err
60
62
}
61
- e .selfObservability = selfObs
63
+ e .inst = selfObs
62
64
63
65
return & e , nil
64
66
}
65
67
66
- func newSelfObservability () (* selfObservability , error ) {
68
+ func newInstrumentation () (* instrumentationImpl , error ) {
67
69
if ! x .SelfObservability .Enabled () {
68
70
return nil , nil
69
71
}
70
72
71
- selfObservability := & selfObservability {
73
+ inst := & instrumentationImpl {
72
74
attrs : []attribute.KeyValue {
73
- semconv .OTelComponentName (fmt .Sprintf ("%s/%d" , otelComponentType , nextExporterID ())),
75
+ semconv .OTelComponentName (fmt .Sprintf ("%s/%d" , otelComponentType , counter . NextExporterID ())),
74
76
semconv .OTelComponentTypeKey .String (otelComponentType ),
75
77
},
76
78
}
@@ -81,24 +83,23 @@ func newSelfObservability() (*selfObservability, error) {
81
83
metric .WithSchemaURL (semconv .SchemaURL ),
82
84
)
83
85
84
- var err error
85
- if selfObservability .inflightMetric , err = otelconv .NewSDKExporterLogInflight (m ); err != nil {
86
- return nil , err
87
- }
88
- if selfObservability .exportedMetric , err = otelconv .NewSDKExporterLogExported (m ); err != nil {
89
- return nil , err
90
- }
91
- if selfObservability .operationDurationMetric , err = otelconv .NewSDKExporterOperationDuration (m ); err != nil {
92
- return nil , err
93
- }
86
+ var err , e error
87
+ inst .inflightMetric , e = otelconv .NewSDKExporterLogInflight (m )
88
+ err = errors .Join (err , e )
89
+
90
+ inst .exportedMetric , e = otelconv .NewSDKExporterLogExported (m )
91
+ err = errors .Join (err , e )
92
+
93
+ inst .operationDurationMetric , e = otelconv .NewSDKExporterOperationDuration (m )
94
+ err = errors .Join (err , e )
94
95
95
- return selfObservability , nil
96
+ return inst , err
96
97
}
97
98
98
99
// Export exports log records to writer.
99
100
func (e * Exporter ) Export (ctx context.Context , records []log.Record ) error {
100
101
var err error
101
- if e .selfObservability != nil && x .SelfObservability .Enabled () {
102
+ if e .inst != nil && x .SelfObservability .Enabled () {
102
103
err = e .exportWithSelfObservability (ctx , records )
103
104
} else {
104
105
err = e .exportWithoutSelfObservability (ctx , records )
@@ -108,7 +109,7 @@ func (e *Exporter) Export(ctx context.Context, records []log.Record) error {
108
109
109
110
const bufferSize = 4
110
111
111
- var selfObservabilityBuffer = sync.Pool {
112
+ var attrPool = sync.Pool {
112
113
New : func () any {
113
114
buf := make ([]attribute.KeyValue , 0 , bufferSize )
114
115
return & buf
@@ -120,31 +121,34 @@ func (e *Exporter) exportWithSelfObservability(ctx context.Context, records []lo
120
121
count := int64 (len (records ))
121
122
start := time .Now ()
122
123
123
- e .selfObservability .inflightMetric .Add (ctx , count , e .selfObservability .attrs ... )
124
+ e .inst .inflightMetric .Add (ctx , count , e .inst .attrs ... )
124
125
126
+ bufPtrAny := attrPool .Get ()
127
+ bufPtr , ok := bufPtrAny .(* []attribute.KeyValue )
128
+ if ! ok || bufPtr == nil {
129
+ bufPtr = & []attribute.KeyValue {}
130
+ }
125
131
defer func () {
126
- bufPtrAny := selfObservabilityBuffer .Get ()
127
- bufPtr , ok := bufPtrAny .(* []attribute.KeyValue )
128
- if ! ok || bufPtr == nil {
129
- bufPtr = & []attribute.KeyValue {}
130
- }
132
+ * bufPtr = (* bufPtr )[:0 ]
133
+ attrPool .Put (bufPtr )
134
+ }()
131
135
136
+ defer func () {
132
137
addAttrs := (* bufPtr )[:0 ]
133
- addAttrs = append (addAttrs , e .selfObservability .attrs ... )
138
+ addAttrs = append (addAttrs , e .inst .attrs ... )
134
139
135
140
if err != nil {
136
141
addAttrs = append (addAttrs , semconv .ErrorType (err ))
137
142
}
138
- e .selfObservability .exportedMetric .Add (ctx , count , addAttrs ... )
139
- e .selfObservability .inflightMetric .Add (ctx , - count , e .selfObservability .attrs ... )
140
- e .selfObservability .operationDurationMetric .Record (ctx , time .Since (start ).Seconds (), addAttrs ... )
143
+ e .inst .exportedMetric .Add (ctx , count , addAttrs ... )
144
+ e .inst .inflightMetric .Add (ctx , - count , e .inst .attrs ... )
145
+ e .inst .operationDurationMetric .Record (ctx , time .Since (start ).Seconds (), addAttrs ... )
141
146
142
- * bufPtr = addAttrs [:0 ]
143
- selfObservabilityBuffer .Put (bufPtr )
147
+ * bufPtr = addAttrs
144
148
}()
145
149
146
150
err = e .exportWithoutSelfObservability (ctx , records )
147
- return
151
+ return err
148
152
}
149
153
150
154
// exportWithoutSelfObservability exports logs without self-observability metrics.
@@ -178,11 +182,3 @@ func (e *Exporter) Shutdown(context.Context) error {
178
182
func (* Exporter ) ForceFlush (context.Context ) error {
179
183
return nil
180
184
}
181
-
182
- var exporterIDCounter atomic.Int64
183
-
184
- // nextExporterID returns a new unique ID for an exporter.
185
- // the starting value is 0, and it increments by 1 for each call.
186
- func nextExporterID () int64 {
187
- return exporterIDCounter .Add (1 ) - 1
188
- }
0 commit comments