2020-03-23 22:41:10 -07:00
|
|
|
// Copyright The OpenTelemetry Authors
|
2024-02-29 07:05:28 +01:00
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
2019-09-16 13:58:15 -07:00
|
|
|
|
2020-11-04 18:10:58 +01:00
|
|
|
package trace // import "go.opentelemetry.io/otel/sdk/trace"
|
2019-09-16 13:58:15 -07:00
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
import (
|
|
|
|
"context"
|
2021-03-08 17:50:15 +00:00
|
|
|
"sync"
|
2019-10-08 20:56:58 +02:00
|
|
|
|
2020-11-16 18:30:54 +01:00
|
|
|
"go.opentelemetry.io/otel"
|
2023-03-24 12:29:52 -03:00
|
|
|
"go.opentelemetry.io/otel/internal/global"
|
2019-10-08 20:56:58 +02:00
|
|
|
)
|
|
|
|
|
2021-03-05 16:08:29 +00:00
|
|
|
// simpleSpanProcessor is a SpanProcessor that synchronously sends all
|
2021-03-08 17:50:15 +00:00
|
|
|
// completed Spans to a trace.Exporter immediately.
|
2021-03-05 16:08:29 +00:00
|
|
|
type simpleSpanProcessor struct {
|
2023-04-14 19:53:47 +05:30
|
|
|
exporterMu sync.Mutex
|
2021-04-07 15:03:43 +00:00
|
|
|
exporter SpanExporter
|
2021-03-08 17:50:15 +00:00
|
|
|
stopOnce sync.Once
|
2019-09-16 13:58:15 -07:00
|
|
|
}
|
|
|
|
|
2021-03-05 16:08:29 +00:00
|
|
|
var _ SpanProcessor = (*simpleSpanProcessor)(nil)
|
2019-09-16 13:58:15 -07:00
|
|
|
|
2021-03-05 16:08:29 +00:00
|
|
|
// NewSimpleSpanProcessor returns a new SpanProcessor that will synchronously
|
|
|
|
// send completed spans to the exporter immediately.
|
2021-04-27 16:23:09 +00:00
|
|
|
//
|
|
|
|
// This SpanProcessor is not recommended for production use. The synchronous
|
2024-03-25 05:10:08 -07:00
|
|
|
// nature of this SpanProcessor makes it good for testing, debugging, or showing
|
|
|
|
// examples of other features, but it will be slow and have a high computation
|
|
|
|
// resource usage overhead. The BatchSpanProcessor is recommended for production
|
|
|
|
// use instead.
|
2021-04-07 15:03:43 +00:00
|
|
|
func NewSimpleSpanProcessor(exporter SpanExporter) SpanProcessor {
|
2021-03-05 16:08:29 +00:00
|
|
|
ssp := &simpleSpanProcessor{
|
2021-03-08 17:50:15 +00:00
|
|
|
exporter: exporter,
|
2019-09-16 13:58:15 -07:00
|
|
|
}
|
2023-03-24 12:29:52 -03:00
|
|
|
global.Warn("SimpleSpanProcessor is not recommended for production use, consider using BatchSpanProcessor instead.")
|
|
|
|
|
2019-09-16 13:58:15 -07:00
|
|
|
return ssp
|
|
|
|
}
|
|
|
|
|
2021-03-08 17:50:15 +00:00
|
|
|
// OnStart does nothing.
|
|
|
|
func (ssp *simpleSpanProcessor) OnStart(context.Context, ReadWriteSpan) {}
|
2019-09-16 13:58:15 -07:00
|
|
|
|
2021-03-08 17:50:15 +00:00
|
|
|
// OnEnd immediately exports a ReadOnlySpan.
|
2021-03-05 16:08:29 +00:00
|
|
|
func (ssp *simpleSpanProcessor) OnEnd(s ReadOnlySpan) {
|
2023-04-14 19:53:47 +05:30
|
|
|
ssp.exporterMu.Lock()
|
|
|
|
defer ssp.exporterMu.Unlock()
|
2021-03-08 17:50:15 +00:00
|
|
|
|
2021-04-05 13:21:42 -04:00
|
|
|
if ssp.exporter != nil && s.SpanContext().TraceFlags().IsSampled() {
|
2021-05-04 23:45:13 +00:00
|
|
|
if err := ssp.exporter.ExportSpans(context.Background(), []ReadOnlySpan{s}); err != nil {
|
2020-11-16 18:30:54 +01:00
|
|
|
otel.Handle(err)
|
2020-09-09 10:19:03 -07:00
|
|
|
}
|
2019-09-16 13:58:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-08 17:50:15 +00:00
|
|
|
// Shutdown shuts down the exporter this SimpleSpanProcessor exports to.
|
|
|
|
func (ssp *simpleSpanProcessor) Shutdown(ctx context.Context) error {
|
|
|
|
var err error
|
|
|
|
ssp.stopOnce.Do(func() {
|
2021-04-28 17:15:00 +00:00
|
|
|
stopFunc := func(exp SpanExporter) (<-chan error, func()) {
|
|
|
|
done := make(chan error)
|
|
|
|
return done, func() { done <- exp.Shutdown(ctx) }
|
|
|
|
}
|
|
|
|
|
|
|
|
// The exporter field of the simpleSpanProcessor needs to be zeroed to
|
|
|
|
// signal it is shut down, meaning all subsequent calls to OnEnd will
|
|
|
|
// be gracefully ignored. This needs to be done synchronously to avoid
|
|
|
|
// any race condition.
|
|
|
|
//
|
|
|
|
// A closure is used to keep reference to the exporter and then the
|
|
|
|
// field is zeroed. This ensures the simpleSpanProcessor is shut down
|
2024-03-25 05:10:08 -07:00
|
|
|
// before the exporter. This order is important as it avoids a potential
|
|
|
|
// deadlock. If the exporter shut down operation generates a span, that
|
|
|
|
// span would need to be exported. Meaning, OnEnd would be called and
|
|
|
|
// try acquiring the lock that is held here.
|
2021-03-08 17:50:15 +00:00
|
|
|
ssp.exporterMu.Lock()
|
2021-04-28 17:15:00 +00:00
|
|
|
done, shutdown := stopFunc(ssp.exporter)
|
2021-03-08 17:50:15 +00:00
|
|
|
ssp.exporter = nil
|
|
|
|
ssp.exporterMu.Unlock()
|
|
|
|
|
2021-04-28 17:15:00 +00:00
|
|
|
go shutdown()
|
|
|
|
|
2021-10-19 08:13:37 -07:00
|
|
|
// Wait for the exporter to shut down or the deadline to expire.
|
2021-04-28 17:15:00 +00:00
|
|
|
select {
|
|
|
|
case err = <-done:
|
|
|
|
case <-ctx.Done():
|
2024-03-25 05:10:08 -07:00
|
|
|
// It is possible for the exporter to have immediately shut down and
|
|
|
|
// the context to be done simultaneously. In that case this outer
|
|
|
|
// select statement will randomly choose a case. This will result in
|
|
|
|
// a different returned error for similar scenarios. Instead, double
|
|
|
|
// check if the exporter shut down at the same time and return that
|
|
|
|
// error if so. This will ensure consistency as well as ensure
|
|
|
|
// the caller knows the exporter shut down successfully (they can
|
|
|
|
// already determine if the deadline is expired given they passed
|
|
|
|
// the context).
|
2021-10-19 08:13:37 -07:00
|
|
|
select {
|
|
|
|
case err = <-done:
|
|
|
|
default:
|
|
|
|
err = ctx.Err()
|
|
|
|
}
|
2021-04-28 17:15:00 +00:00
|
|
|
}
|
2021-03-08 17:50:15 +00:00
|
|
|
})
|
|
|
|
return err
|
2019-09-16 13:58:15 -07:00
|
|
|
}
|
2020-09-20 13:35:44 -04:00
|
|
|
|
|
|
|
// ForceFlush does nothing as there is no data to flush.
|
2021-03-08 19:12:13 +00:00
|
|
|
func (ssp *simpleSpanProcessor) ForceFlush(context.Context) error {
|
|
|
|
return nil
|
2020-09-20 13:35:44 -04:00
|
|
|
}
|
2022-01-10 18:58:01 -06:00
|
|
|
|
2024-03-25 05:10:08 -07:00
|
|
|
// MarshalLog is the marshaling function used by the logging system to represent
|
|
|
|
// this Span Processor.
|
2022-01-10 18:58:01 -06:00
|
|
|
func (ssp *simpleSpanProcessor) MarshalLog() interface{} {
|
|
|
|
return struct {
|
|
|
|
Type string
|
|
|
|
Exporter SpanExporter
|
|
|
|
}{
|
|
|
|
Type: "SimpleSpanProcessor",
|
|
|
|
Exporter: ssp.exporter,
|
|
|
|
}
|
|
|
|
}
|