summaryrefslogtreecommitdiff
path: root/vendor/go.opentelemetry.io/otel/sdk/trace
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2023-05-12 14:33:40 +0200
committerLibravatar GitHub <noreply@github.com>2023-05-12 14:33:40 +0200
commitec325fee141c1e9757144a0a4094061b56839b78 (patch)
tree2948ab4ef5702cc8478ab2be841340b946bdb867 /vendor/go.opentelemetry.io/otel/sdk/trace
parent[frogend/bugfix] fix dynamicSpoiler elements (#1771) (diff)
downloadgotosocial-ec325fee141c1e9757144a0a4094061b56839b78.tar.xz
[chore] Update a bunch of database dependencies (#1772)
* [chore] Update a bunch of database dependencies * fix lil thing
Diffstat (limited to 'vendor/go.opentelemetry.io/otel/sdk/trace')
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go2
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/trace/provider.go99
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go9
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/trace/span.go4
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go2
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go4
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go2
7 files changed, 82 insertions, 40 deletions
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go
index a2d7db490..43d5b0423 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go
@@ -91,7 +91,7 @@ var _ SpanProcessor = (*batchSpanProcessor)(nil)
// NewBatchSpanProcessor creates a new SpanProcessor that will send completed
// span batches to the exporter with the supplied options.
//
-// If the exporter is nil, the span processor will preform no action.
+// If the exporter is nil, the span processor will perform no action.
func NewBatchSpanProcessor(exporter SpanExporter, options ...BatchSpanProcessorOption) SpanProcessor {
maxQueueSize := env.BatchSpanProcessorMaxQueueSize(DefaultMaxQueueSize)
maxExportBatchSize := env.BatchSpanProcessorMaxExportBatchSize(DefaultMaxExportBatchSize)
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
index 201c17817..0a018c14d 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
@@ -75,8 +75,9 @@ func (cfg tracerProviderConfig) MarshalLog() interface{} {
type TracerProvider struct {
mu sync.Mutex
namedTracer map[instrumentation.Scope]*tracer
- spanProcessors atomic.Value
- isShutdown bool
+ spanProcessors atomic.Pointer[spanProcessorStates]
+
+ isShutdown atomic.Bool
// These fields are not protected by the lock mu. They are assumed to be
// immutable after creation of the TracerProvider.
@@ -119,11 +120,11 @@ func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider {
}
global.Info("TracerProvider created", "config", o)
- spss := spanProcessorStates{}
+ spss := make(spanProcessorStates, 0, len(o.processors))
for _, sp := range o.processors {
spss = append(spss, newSpanProcessorState(sp))
}
- tp.spanProcessors.Store(spss)
+ tp.spanProcessors.Store(&spss)
return tp
}
@@ -136,10 +137,11 @@ func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider {
//
// This method is safe to be called concurrently.
func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
+ // This check happens before the mutex is acquired to avoid deadlocking if Tracer() is called from within Shutdown().
+ if p.isShutdown.Load() {
+ return trace.NewNoopTracerProvider().Tracer(name, opts...)
+ }
c := trace.NewTracerConfig(opts...)
-
- p.mu.Lock()
- defer p.mu.Unlock()
if name == "" {
name = defaultTracerName
}
@@ -148,44 +150,74 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
Version: c.InstrumentationVersion(),
SchemaURL: c.SchemaURL(),
}
- t, ok := p.namedTracer[is]
- if !ok {
- t = &tracer{
- provider: p,
- instrumentationScope: is,
+
+ t, ok := func() (trace.Tracer, bool) {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ // Must check the flag after acquiring the mutex to avoid returning a valid tracer if Shutdown() ran
+ // after the first check above but before we acquired the mutex.
+ if p.isShutdown.Load() {
+ return trace.NewNoopTracerProvider().Tracer(name, opts...), true
+ }
+ t, ok := p.namedTracer[is]
+ if !ok {
+ t = &tracer{
+ provider: p,
+ instrumentationScope: is,
+ }
+ p.namedTracer[is] = t
}
- p.namedTracer[is] = t
- global.Info("Tracer created", "name", name, "version", c.InstrumentationVersion(), "schemaURL", c.SchemaURL())
+ return t, ok
+ }()
+ if !ok {
+ // This code is outside the mutex to not hold the lock while calling third party logging code:
+ // - That code may do slow things like I/O, which would prolong the duration the lock is held,
+ // slowing down all tracing consumers.
+ // - Logging code may be instrumented with tracing and deadlock because it could try
+ // acquiring the same non-reentrant mutex.
+ global.Info("Tracer created", "name", name, "version", is.Version, "schemaURL", is.SchemaURL)
}
return t
}
// RegisterSpanProcessor adds the given SpanProcessor to the list of SpanProcessors.
func (p *TracerProvider) RegisterSpanProcessor(sp SpanProcessor) {
+ // This check prevents calls during a shutdown.
+ if p.isShutdown.Load() {
+ return
+ }
p.mu.Lock()
defer p.mu.Unlock()
- if p.isShutdown {
+ // This check prevents calls after a shutdown.
+ if p.isShutdown.Load() {
return
}
- newSPS := spanProcessorStates{}
- newSPS = append(newSPS, p.spanProcessors.Load().(spanProcessorStates)...)
+
+ current := p.getSpanProcessors()
+ newSPS := make(spanProcessorStates, 0, len(current)+1)
+ newSPS = append(newSPS, current...)
newSPS = append(newSPS, newSpanProcessorState(sp))
- p.spanProcessors.Store(newSPS)
+ p.spanProcessors.Store(&newSPS)
}
// UnregisterSpanProcessor removes the given SpanProcessor from the list of SpanProcessors.
func (p *TracerProvider) UnregisterSpanProcessor(sp SpanProcessor) {
+ // This check prevents calls during a shutdown.
+ if p.isShutdown.Load() {
+ return
+ }
p.mu.Lock()
defer p.mu.Unlock()
- if p.isShutdown {
+ // This check prevents calls after a shutdown.
+ if p.isShutdown.Load() {
return
}
- old := p.spanProcessors.Load().(spanProcessorStates)
+ old := p.getSpanProcessors()
if len(old) == 0 {
return
}
- spss := spanProcessorStates{}
- spss = append(spss, old...)
+ spss := make(spanProcessorStates, len(old))
+ copy(spss, old)
// stop the span processor if it is started and remove it from the list
var stopOnce *spanProcessorState
@@ -209,13 +241,13 @@ func (p *TracerProvider) UnregisterSpanProcessor(sp SpanProcessor) {
spss[len(spss)-1] = nil
spss = spss[:len(spss)-1]
- p.spanProcessors.Store(spss)
+ p.spanProcessors.Store(&spss)
}
// ForceFlush immediately exports all spans that have not yet been exported for
// all the registered span processors.
func (p *TracerProvider) ForceFlush(ctx context.Context) error {
- spss := p.spanProcessors.Load().(spanProcessorStates)
+ spss := p.getSpanProcessors()
if len(spss) == 0 {
return nil
}
@@ -236,18 +268,21 @@ func (p *TracerProvider) ForceFlush(ctx context.Context) error {
// Shutdown shuts down TracerProvider. All registered span processors are shut down
// in the order they were registered and any held computational resources are released.
+// After Shutdown is called, all methods are no-ops.
func (p *TracerProvider) Shutdown(ctx context.Context) error {
- spss := p.spanProcessors.Load().(spanProcessorStates)
- if len(spss) == 0 {
+ // This check prevents deadlocks in case of recursive shutdown.
+ if p.isShutdown.Load() {
return nil
}
-
p.mu.Lock()
defer p.mu.Unlock()
- p.isShutdown = true
+ // This check prevents calls after a shutdown has already been done concurrently.
+ if !p.isShutdown.CompareAndSwap(false, true) { // did toggle?
+ return nil
+ }
var retErr error
- for _, sps := range spss {
+ for _, sps := range p.getSpanProcessors() {
select {
case <-ctx.Done():
return ctx.Err()
@@ -267,10 +302,14 @@ func (p *TracerProvider) Shutdown(ctx context.Context) error {
}
}
}
- p.spanProcessors.Store(spanProcessorStates{})
+ p.spanProcessors.Store(&spanProcessorStates{})
return retErr
}
+func (p *TracerProvider) getSpanProcessors() spanProcessorStates {
+ return *(p.spanProcessors.Load())
+}
+
// TracerProviderOption configures a TracerProvider.
type TracerProviderOption interface {
apply(tracerProviderConfig) tracerProviderConfig
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go
index e8530a959..f8770fff7 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go
@@ -19,12 +19,13 @@ import (
"sync"
"go.opentelemetry.io/otel"
+ "go.opentelemetry.io/otel/internal/global"
)
// simpleSpanProcessor is a SpanProcessor that synchronously sends all
// completed Spans to a trace.Exporter immediately.
type simpleSpanProcessor struct {
- exporterMu sync.RWMutex
+ exporterMu sync.Mutex
exporter SpanExporter
stopOnce sync.Once
}
@@ -43,6 +44,8 @@ func NewSimpleSpanProcessor(exporter SpanExporter) SpanProcessor {
ssp := &simpleSpanProcessor{
exporter: exporter,
}
+ global.Warn("SimpleSpanProcessor is not recommended for production use, consider using BatchSpanProcessor instead.")
+
return ssp
}
@@ -51,8 +54,8 @@ func (ssp *simpleSpanProcessor) OnStart(context.Context, ReadWriteSpan) {}
// OnEnd immediately exports a ReadOnlySpan.
func (ssp *simpleSpanProcessor) OnEnd(s ReadOnlySpan) {
- ssp.exporterMu.RLock()
- defer ssp.exporterMu.RUnlock()
+ ssp.exporterMu.Lock()
+ defer ssp.exporterMu.Unlock()
if ssp.exporter != nil && s.SpanContext().TraceFlags().IsSampled() {
if err := ssp.exporter.ExportSpans(context.Background(), []ReadOnlySpan{s}); err != nil {
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span.go
index 9fb483a99..4fcca26e0 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/span.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span.go
@@ -302,7 +302,7 @@ func (s *recordingSpan) addOverCapAttrs(limit int, attrs []attribute.KeyValue) {
// most a length of limit. Each string slice value is truncated in this fashion
// (the slice length itself is unaffected).
//
-// No truncation is perfromed for a negative limit.
+// No truncation is performed for a negative limit.
func truncateAttr(limit int, attr attribute.KeyValue) attribute.KeyValue {
if limit < 0 {
return attr
@@ -410,7 +410,7 @@ func (s *recordingSpan) End(options ...trace.SpanEndOption) {
}
s.mu.Unlock()
- sps := s.tracer.provider.spanProcessors.Load().(spanProcessorStates)
+ sps := s.tracer.provider.getSpanProcessors()
if len(sps) == 0 {
return
}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go
index 9fb3d6eac..c9bd52f7a 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go
@@ -38,7 +38,7 @@ type SpanExporter interface {
// must never be done outside of a new major release.
// Shutdown notifies the exporter of a pending halt to operations. The
- // exporter is expected to preform any cleanup or synchronization it
+ // exporter is expected to perform any cleanup or synchronization it
// requires while honoring all timeouts and cancellations contained in
// the passed context.
Shutdown(ctx context.Context) error
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go
index e6ae19352..9c53657a7 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go
@@ -62,11 +62,11 @@ type SpanProcessor interface {
type spanProcessorState struct {
sp SpanProcessor
- state *sync.Once
+ state sync.Once
}
func newSpanProcessorState(sp SpanProcessor) *spanProcessorState {
- return &spanProcessorState{sp: sp, state: &sync.Once{}}
+ return &spanProcessorState{sp: sp}
}
type spanProcessorStates []*spanProcessorState
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go b/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go
index f17d924b8..85a71227f 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go
@@ -51,7 +51,7 @@ func (tr *tracer) Start(ctx context.Context, name string, options ...trace.SpanS
s := tr.newSpan(ctx, name, &config)
if rw, ok := s.(ReadWriteSpan); ok && s.IsRecording() {
- sps := tr.provider.spanProcessors.Load().(spanProcessorStates)
+ sps := tr.provider.getSpanProcessors()
for _, sp := range sps {
sp.sp.OnStart(ctx, rw)
}