1// Copyright The OpenTelemetry Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package trace // import "go.opentelemetry.io/otel/sdk/trace" 16 17import ( 18 "context" 19 "sync" 20 21 "go.opentelemetry.io/otel" 22 export "go.opentelemetry.io/otel/sdk/export/trace" 23) 24 25// simpleSpanProcessor is a SpanProcessor that synchronously sends all 26// completed Spans to a trace.Exporter immediately. 27type simpleSpanProcessor struct { 28 exporterMu sync.RWMutex 29 exporter export.SpanExporter 30 stopOnce sync.Once 31} 32 33var _ SpanProcessor = (*simpleSpanProcessor)(nil) 34 35// NewSimpleSpanProcessor returns a new SpanProcessor that will synchronously 36// send completed spans to the exporter immediately. 37func NewSimpleSpanProcessor(exporter export.SpanExporter) SpanProcessor { 38 ssp := &simpleSpanProcessor{ 39 exporter: exporter, 40 } 41 return ssp 42} 43 44// OnStart does nothing. 45func (ssp *simpleSpanProcessor) OnStart(context.Context, ReadWriteSpan) {} 46 47// OnEnd immediately exports a ReadOnlySpan. 48func (ssp *simpleSpanProcessor) OnEnd(s ReadOnlySpan) { 49 ssp.exporterMu.RLock() 50 defer ssp.exporterMu.RUnlock() 51 52 if ssp.exporter != nil && s.SpanContext().IsSampled() { 53 ss := s.Snapshot() 54 if err := ssp.exporter.ExportSpans(context.Background(), []*export.SpanSnapshot{ss}); err != nil { 55 otel.Handle(err) 56 } 57 } 58} 59 60// Shutdown shuts down the exporter this SimpleSpanProcessor exports to. 61func (ssp *simpleSpanProcessor) Shutdown(ctx context.Context) error { 62 var err error 63 ssp.stopOnce.Do(func() { 64 ssp.exporterMu.Lock() 65 exporter := ssp.exporter 66 // Set exporter to nil so subsequent calls to OnEnd are ignored 67 // gracefully. 68 ssp.exporter = nil 69 ssp.exporterMu.Unlock() 70 71 // Clear the ssp.exporter prior to shutting it down so if that creates 72 // a span that needs to be exported there is no deadlock. 73 err = exporter.Shutdown(ctx) 74 }) 75 return err 76} 77 78// ForceFlush does nothing as there is no data to flush. 79func (ssp *simpleSpanProcessor) ForceFlush(context.Context) error { 80 return nil 81} 82