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) 23 24// simpleSpanProcessor is a SpanProcessor that synchronously sends all 25// completed Spans to a trace.Exporter immediately. 26type simpleSpanProcessor struct { 27 exporterMu sync.RWMutex 28 exporter SpanExporter 29 stopOnce sync.Once 30} 31 32var _ SpanProcessor = (*simpleSpanProcessor)(nil) 33 34// NewSimpleSpanProcessor returns a new SpanProcessor that will synchronously 35// send completed spans to the exporter immediately. 36func NewSimpleSpanProcessor(exporter SpanExporter) SpanProcessor { 37 ssp := &simpleSpanProcessor{ 38 exporter: exporter, 39 } 40 return ssp 41} 42 43// OnStart does nothing. 44func (ssp *simpleSpanProcessor) OnStart(context.Context, ReadWriteSpan) {} 45 46// OnEnd immediately exports a ReadOnlySpan. 47func (ssp *simpleSpanProcessor) OnEnd(s ReadOnlySpan) { 48 ssp.exporterMu.RLock() 49 defer ssp.exporterMu.RUnlock() 50 51 if ssp.exporter != nil && s.SpanContext().TraceFlags().IsSampled() { 52 ss := s.Snapshot() 53 if err := ssp.exporter.ExportSpans(context.Background(), []*SpanSnapshot{ss}); err != nil { 54 otel.Handle(err) 55 } 56 } 57} 58 59// Shutdown shuts down the exporter this SimpleSpanProcessor exports to. 60func (ssp *simpleSpanProcessor) Shutdown(ctx context.Context) error { 61 var err error 62 ssp.stopOnce.Do(func() { 63 ssp.exporterMu.Lock() 64 exporter := ssp.exporter 65 // Set exporter to nil so subsequent calls to OnEnd are ignored 66 // gracefully. 67 ssp.exporter = nil 68 ssp.exporterMu.Unlock() 69 70 // Clear the ssp.exporter prior to shutting it down so if that creates 71 // a span that needs to be exported there is no deadlock. 72 err = exporter.Shutdown(ctx) 73 }) 74 return err 75} 76 77// ForceFlush does nothing as there is no data to flush. 78func (ssp *simpleSpanProcessor) ForceFlush(context.Context) error { 79 return nil 80} 81