...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package otlptrace
16
17 import (
18 "context"
19 "errors"
20 "fmt"
21 "sync"
22
23 "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform"
24 tracesdk "go.opentelemetry.io/otel/sdk/trace"
25 )
26
27 var errAlreadyStarted = errors.New("already started")
28
29
30 type Exporter struct {
31 client Client
32
33 mu sync.RWMutex
34 started bool
35
36 startOnce sync.Once
37 stopOnce sync.Once
38 }
39
40
41 func (e *Exporter) ExportSpans(ctx context.Context, ss []tracesdk.ReadOnlySpan) error {
42 protoSpans := tracetransform.Spans(ss)
43 if len(protoSpans) == 0 {
44 return nil
45 }
46
47 err := e.client.UploadTraces(ctx, protoSpans)
48 if err != nil {
49 return fmt.Errorf("traces export: %w", err)
50 }
51 return nil
52 }
53
54
55 func (e *Exporter) Start(ctx context.Context) error {
56 err := errAlreadyStarted
57 e.startOnce.Do(func() {
58 e.mu.Lock()
59 e.started = true
60 e.mu.Unlock()
61 err = e.client.Start(ctx)
62 })
63
64 return err
65 }
66
67
68 func (e *Exporter) Shutdown(ctx context.Context) error {
69 e.mu.RLock()
70 started := e.started
71 e.mu.RUnlock()
72
73 if !started {
74 return nil
75 }
76
77 var err error
78
79 e.stopOnce.Do(func() {
80 err = e.client.Stop(ctx)
81 e.mu.Lock()
82 e.started = false
83 e.mu.Unlock()
84 })
85
86 return err
87 }
88
89 var _ tracesdk.SpanExporter = (*Exporter)(nil)
90
91
92 func New(ctx context.Context, client Client) (*Exporter, error) {
93 exp := NewUnstarted(client)
94 if err := exp.Start(ctx); err != nil {
95 return nil, err
96 }
97 return exp, nil
98 }
99
100
101 func NewUnstarted(client Client) *Exporter {
102 return &Exporter{
103 client: client,
104 }
105 }
106
107
108 func (e *Exporter) MarshalLog() interface{} {
109 return struct {
110 Type string
111 Client Client
112 }{
113 Type: "otlptrace",
114 Client: e.client,
115 }
116 }
117
View as plain text