2020-03-24 07:41:10 +02:00
|
|
|
// Copyright The OpenTelemetry Authors
|
2019-10-01 22:50:51 +02:00
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2020-11-04 19:10:58 +02:00
|
|
|
package trace // import "go.opentelemetry.io/otel/sdk/trace"
|
2019-10-01 22:50:51 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2020-05-19 18:36:33 +02:00
|
|
|
"runtime"
|
2019-10-01 22:50:51 +02:00
|
|
|
"sync"
|
2020-03-05 23:41:00 +02:00
|
|
|
"sync/atomic"
|
2019-10-01 22:50:51 +02:00
|
|
|
"time"
|
2019-10-08 20:56:58 +02:00
|
|
|
|
2020-11-16 19:30:54 +02:00
|
|
|
"go.opentelemetry.io/otel"
|
2021-11-24 22:06:39 +02:00
|
|
|
"go.opentelemetry.io/otel/internal/global"
|
2022-02-07 17:57:44 +02:00
|
|
|
"go.opentelemetry.io/otel/sdk/internal/env"
|
2021-11-05 17:34:57 +02:00
|
|
|
"go.opentelemetry.io/otel/trace"
|
2019-10-01 22:50:51 +02:00
|
|
|
)
|
|
|
|
|
2021-06-08 19:10:01 +02:00
|
|
|
// Defaults for BatchSpanProcessorOptions.
|
2019-10-01 22:50:51 +02:00
|
|
|
const (
|
2020-05-19 18:36:33 +02:00
|
|
|
DefaultMaxQueueSize = 2048
|
2022-01-28 18:07:21 +02:00
|
|
|
DefaultScheduleDelay = 5000
|
|
|
|
DefaultExportTimeout = 30000
|
2020-05-19 18:36:33 +02:00
|
|
|
DefaultMaxExportBatchSize = 512
|
2019-10-01 22:50:51 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type BatchSpanProcessorOption func(o *BatchSpanProcessorOptions)
|
|
|
|
|
|
|
|
type BatchSpanProcessorOptions struct {
|
|
|
|
// MaxQueueSize is the maximum queue size to buffer spans for delayed processing. If the
|
|
|
|
// queue gets full it drops the spans. Use BlockOnQueueFull to change this behavior.
|
|
|
|
// The default value of MaxQueueSize is 2048.
|
|
|
|
MaxQueueSize int
|
|
|
|
|
2020-05-20 19:12:57 +02:00
|
|
|
// BatchTimeout is the maximum duration for constructing a batch. Processor
|
|
|
|
// forcefully sends available spans when timeout is reached.
|
|
|
|
// The default value of BatchTimeout is 5000 msec.
|
|
|
|
BatchTimeout time.Duration
|
2019-10-01 22:50:51 +02:00
|
|
|
|
2021-04-05 19:38:03 +02:00
|
|
|
// ExportTimeout specifies the maximum duration for exporting spans. If the timeout
|
|
|
|
// is reached, the export will be cancelled.
|
|
|
|
// The default value of ExportTimeout is 30000 msec.
|
|
|
|
ExportTimeout time.Duration
|
|
|
|
|
2019-10-01 22:50:51 +02:00
|
|
|
// MaxExportBatchSize is the maximum number of spans to process in a single batch.
|
|
|
|
// If there are more than one batch worth of spans then it processes multiple batches
|
|
|
|
// of spans one batch after the other without any delay.
|
|
|
|
// The default value of MaxExportBatchSize is 512.
|
|
|
|
MaxExportBatchSize int
|
|
|
|
|
|
|
|
// BlockOnQueueFull blocks onEnd() and onStart() method if the queue is full
|
|
|
|
// AND if BlockOnQueueFull is set to true.
|
|
|
|
// Blocking option should be used carefully as it can severely affect the performance of an
|
|
|
|
// application.
|
|
|
|
BlockOnQueueFull bool
|
|
|
|
}
|
|
|
|
|
2021-03-05 18:08:29 +02:00
|
|
|
// batchSpanProcessor is a SpanProcessor that batches asynchronously-received
|
2021-05-05 01:45:13 +02:00
|
|
|
// spans and sends them to a trace.Exporter when complete.
|
2021-03-05 18:08:29 +02:00
|
|
|
type batchSpanProcessor struct {
|
2021-04-07 17:03:43 +02:00
|
|
|
e SpanExporter
|
2019-10-08 20:56:58 +02:00
|
|
|
o BatchSpanProcessorOptions
|
2019-10-01 22:50:51 +02:00
|
|
|
|
2021-05-05 01:45:13 +02:00
|
|
|
queue chan ReadOnlySpan
|
2019-10-01 22:50:51 +02:00
|
|
|
dropped uint32
|
|
|
|
|
2021-05-05 01:45:13 +02:00
|
|
|
batch []ReadOnlySpan
|
2020-09-20 19:35:44 +02:00
|
|
|
batchMutex sync.Mutex
|
|
|
|
timer *time.Timer
|
|
|
|
stopWait sync.WaitGroup
|
|
|
|
stopOnce sync.Once
|
|
|
|
stopCh chan struct{}
|
2019-10-01 22:50:51 +02:00
|
|
|
}
|
|
|
|
|
2021-03-05 18:08:29 +02:00
|
|
|
var _ SpanProcessor = (*batchSpanProcessor)(nil)
|
2019-10-01 22:50:51 +02:00
|
|
|
|
2021-03-05 18:08:29 +02:00
|
|
|
// NewBatchSpanProcessor creates a new SpanProcessor that will send completed
|
|
|
|
// span batches to the exporter with the supplied options.
|
2020-09-09 19:19:03 +02:00
|
|
|
//
|
|
|
|
// If the exporter is nil, the span processor will preform no action.
|
2021-04-07 17:03:43 +02:00
|
|
|
func NewBatchSpanProcessor(exporter SpanExporter, options ...BatchSpanProcessorOption) SpanProcessor {
|
2022-02-07 17:57:44 +02:00
|
|
|
maxQueueSize := env.BatchSpanProcessorMaxQueueSize(DefaultMaxQueueSize)
|
|
|
|
maxExportBatchSize := env.BatchSpanProcessorMaxExportBatchSize(DefaultMaxExportBatchSize)
|
2022-01-28 18:07:21 +02:00
|
|
|
|
|
|
|
if maxExportBatchSize > maxQueueSize {
|
|
|
|
if DefaultMaxExportBatchSize > maxQueueSize {
|
|
|
|
maxExportBatchSize = maxQueueSize
|
|
|
|
} else {
|
|
|
|
maxExportBatchSize = DefaultMaxExportBatchSize
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-01 22:50:51 +02:00
|
|
|
o := BatchSpanProcessorOptions{
|
2022-02-07 17:57:44 +02:00
|
|
|
BatchTimeout: time.Duration(env.BatchSpanProcessorScheduleDelay(DefaultScheduleDelay)) * time.Millisecond,
|
|
|
|
ExportTimeout: time.Duration(env.BatchSpanProcessorExportTimeout(DefaultExportTimeout)) * time.Millisecond,
|
2022-01-28 18:07:21 +02:00
|
|
|
MaxQueueSize: maxQueueSize,
|
|
|
|
MaxExportBatchSize: maxExportBatchSize,
|
2019-10-01 22:50:51 +02:00
|
|
|
}
|
2020-09-09 19:19:03 +02:00
|
|
|
for _, opt := range options {
|
2019-10-01 22:50:51 +02:00
|
|
|
opt(&o)
|
|
|
|
}
|
2021-03-05 18:08:29 +02:00
|
|
|
bsp := &batchSpanProcessor{
|
2020-09-09 19:19:03 +02:00
|
|
|
e: exporter,
|
2020-05-19 18:36:33 +02:00
|
|
|
o: o,
|
2021-05-05 01:45:13 +02:00
|
|
|
batch: make([]ReadOnlySpan, 0, o.MaxExportBatchSize),
|
2020-05-20 19:12:57 +02:00
|
|
|
timer: time.NewTimer(o.BatchTimeout),
|
2021-05-05 01:45:13 +02:00
|
|
|
queue: make(chan ReadOnlySpan, o.MaxQueueSize),
|
2020-05-19 18:36:33 +02:00
|
|
|
stopCh: make(chan struct{}),
|
2019-10-01 22:50:51 +02:00
|
|
|
}
|
2020-05-19 18:36:33 +02:00
|
|
|
|
2020-06-10 00:20:48 +02:00
|
|
|
bsp.stopWait.Add(1)
|
2020-03-28 01:21:20 +02:00
|
|
|
go func() {
|
2020-06-10 00:20:48 +02:00
|
|
|
defer bsp.stopWait.Done()
|
2020-05-06 16:46:54 +02:00
|
|
|
bsp.processQueue()
|
2020-05-19 18:36:33 +02:00
|
|
|
bsp.drainQueue()
|
2020-03-28 01:21:20 +02:00
|
|
|
}()
|
2019-10-01 22:50:51 +02:00
|
|
|
|
2020-09-09 19:19:03 +02:00
|
|
|
return bsp
|
2019-10-01 22:50:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// OnStart method does nothing.
|
2021-03-05 18:08:29 +02:00
|
|
|
func (bsp *batchSpanProcessor) OnStart(parent context.Context, s ReadWriteSpan) {}
|
2019-10-01 22:50:51 +02:00
|
|
|
|
2020-12-11 07:15:44 +02:00
|
|
|
// OnEnd method enqueues a ReadOnlySpan for later processing.
|
2021-03-05 18:08:29 +02:00
|
|
|
func (bsp *batchSpanProcessor) OnEnd(s ReadOnlySpan) {
|
2020-09-09 19:19:03 +02:00
|
|
|
// Do not enqueue spans if we are just going to drop them.
|
|
|
|
if bsp.e == nil {
|
|
|
|
return
|
|
|
|
}
|
2021-05-05 01:45:13 +02:00
|
|
|
bsp.enqueue(s)
|
2019-10-01 22:50:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Shutdown flushes the queue and waits until all spans are processed.
|
|
|
|
// It only executes once. Subsequent call does nothing.
|
2021-03-05 18:08:29 +02:00
|
|
|
func (bsp *batchSpanProcessor) Shutdown(ctx context.Context) error {
|
2020-10-27 04:06:55 +02:00
|
|
|
var err error
|
2019-10-01 22:50:51 +02:00
|
|
|
bsp.stopOnce.Do(func() {
|
2020-10-27 04:06:55 +02:00
|
|
|
wait := make(chan struct{})
|
|
|
|
go func() {
|
|
|
|
close(bsp.stopCh)
|
|
|
|
bsp.stopWait.Wait()
|
2021-01-14 03:14:03 +02:00
|
|
|
if bsp.e != nil {
|
|
|
|
if err := bsp.e.Shutdown(ctx); err != nil {
|
|
|
|
otel.Handle(err)
|
|
|
|
}
|
|
|
|
}
|
2020-10-27 04:06:55 +02:00
|
|
|
close(wait)
|
|
|
|
}()
|
|
|
|
// Wait until the wait group is done or the context is cancelled
|
|
|
|
select {
|
|
|
|
case <-wait:
|
|
|
|
case <-ctx.Done():
|
|
|
|
err = ctx.Err()
|
|
|
|
}
|
2019-10-01 22:50:51 +02:00
|
|
|
})
|
2020-10-27 04:06:55 +02:00
|
|
|
return err
|
2019-10-01 22:50:51 +02:00
|
|
|
}
|
|
|
|
|
2021-11-05 17:34:57 +02:00
|
|
|
type forceFlushSpan struct {
|
|
|
|
ReadOnlySpan
|
|
|
|
flushed chan struct{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f forceFlushSpan) SpanContext() trace.SpanContext {
|
|
|
|
return trace.NewSpanContext(trace.SpanContextConfig{TraceFlags: trace.FlagsSampled})
|
|
|
|
}
|
|
|
|
|
2020-09-20 19:35:44 +02:00
|
|
|
// ForceFlush exports all ended spans that have not yet been exported.
|
2021-03-08 21:12:13 +02:00
|
|
|
func (bsp *batchSpanProcessor) ForceFlush(ctx context.Context) error {
|
2021-04-01 19:42:19 +02:00
|
|
|
var err error
|
|
|
|
if bsp.e != nil {
|
2021-11-05 17:34:57 +02:00
|
|
|
flushCh := make(chan struct{})
|
|
|
|
if bsp.enqueueBlockOnQueueFull(ctx, forceFlushSpan{flushed: flushCh}, true) {
|
|
|
|
select {
|
|
|
|
case <-flushCh:
|
|
|
|
// Processed any items in queue prior to ForceFlush being called
|
|
|
|
case <-ctx.Done():
|
|
|
|
return ctx.Err()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-29 18:42:11 +02:00
|
|
|
wait := make(chan error)
|
2021-04-01 19:42:19 +02:00
|
|
|
go func() {
|
2021-04-29 18:42:11 +02:00
|
|
|
wait <- bsp.exportSpans(ctx)
|
2021-04-01 19:42:19 +02:00
|
|
|
close(wait)
|
|
|
|
}()
|
|
|
|
// Wait until the export is finished or the context is cancelled/timed out
|
|
|
|
select {
|
2021-04-29 18:42:11 +02:00
|
|
|
case err = <-wait:
|
2021-04-01 19:42:19 +02:00
|
|
|
case <-ctx.Done():
|
|
|
|
err = ctx.Err()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return err
|
2020-09-20 19:35:44 +02:00
|
|
|
}
|
|
|
|
|
2019-10-01 22:50:51 +02:00
|
|
|
func WithMaxQueueSize(size int) BatchSpanProcessorOption {
|
|
|
|
return func(o *BatchSpanProcessorOptions) {
|
|
|
|
o.MaxQueueSize = size
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithMaxExportBatchSize(size int) BatchSpanProcessorOption {
|
|
|
|
return func(o *BatchSpanProcessorOptions) {
|
|
|
|
o.MaxExportBatchSize = size
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-20 19:12:57 +02:00
|
|
|
func WithBatchTimeout(delay time.Duration) BatchSpanProcessorOption {
|
2019-10-01 22:50:51 +02:00
|
|
|
return func(o *BatchSpanProcessorOptions) {
|
2020-05-20 19:12:57 +02:00
|
|
|
o.BatchTimeout = delay
|
2019-10-01 22:50:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-05 19:38:03 +02:00
|
|
|
func WithExportTimeout(timeout time.Duration) BatchSpanProcessorOption {
|
|
|
|
return func(o *BatchSpanProcessorOptions) {
|
|
|
|
o.ExportTimeout = timeout
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-01 22:50:51 +02:00
|
|
|
func WithBlocking() BatchSpanProcessorOption {
|
|
|
|
return func(o *BatchSpanProcessorOptions) {
|
|
|
|
o.BlockOnQueueFull = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-19 18:36:33 +02:00
|
|
|
// exportSpans is a subroutine of processing and draining the queue.
|
2021-03-08 21:12:13 +02:00
|
|
|
func (bsp *batchSpanProcessor) exportSpans(ctx context.Context) error {
|
2021-11-03 18:18:50 +02:00
|
|
|
|
2020-05-20 19:12:57 +02:00
|
|
|
bsp.timer.Reset(bsp.o.BatchTimeout)
|
2020-05-19 18:36:33 +02:00
|
|
|
|
2020-09-20 19:35:44 +02:00
|
|
|
bsp.batchMutex.Lock()
|
|
|
|
defer bsp.batchMutex.Unlock()
|
|
|
|
|
2021-04-05 19:38:03 +02:00
|
|
|
if bsp.o.ExportTimeout > 0 {
|
|
|
|
var cancel context.CancelFunc
|
|
|
|
ctx, cancel = context.WithTimeout(ctx, bsp.o.ExportTimeout)
|
|
|
|
defer cancel()
|
|
|
|
}
|
|
|
|
|
2021-04-29 18:42:11 +02:00
|
|
|
if l := len(bsp.batch); l > 0 {
|
2022-02-25 17:55:50 +02:00
|
|
|
global.Debug("exporting spans", "count", len(bsp.batch), "total_dropped", atomic.LoadUint32(&bsp.dropped))
|
2021-04-29 18:42:11 +02:00
|
|
|
err := bsp.e.ExportSpans(ctx, bsp.batch)
|
|
|
|
|
|
|
|
// A new batch is always created after exporting, even if the batch failed to be exported.
|
|
|
|
//
|
|
|
|
// It is up to the exporter to implement any type of retry logic if a batch is failing
|
|
|
|
// to be exported, since it is specific to the protocol and backend being sent to.
|
|
|
|
bsp.batch = bsp.batch[:0]
|
|
|
|
|
|
|
|
if err != nil {
|
2021-03-08 21:12:13 +02:00
|
|
|
return err
|
2020-09-09 19:19:03 +02:00
|
|
|
}
|
2020-05-19 18:36:33 +02:00
|
|
|
}
|
2021-03-08 21:12:13 +02:00
|
|
|
return nil
|
2020-05-19 18:36:33 +02:00
|
|
|
}
|
|
|
|
|
2020-05-06 16:46:54 +02:00
|
|
|
// processQueue removes spans from the `queue` channel until processor
|
|
|
|
// is shut down. It calls the exporter in batches of up to MaxExportBatchSize
|
2020-05-20 19:12:57 +02:00
|
|
|
// waiting up to BatchTimeout to form a batch.
|
2021-03-05 18:08:29 +02:00
|
|
|
func (bsp *batchSpanProcessor) processQueue() {
|
2020-05-19 18:36:33 +02:00
|
|
|
defer bsp.timer.Stop()
|
2020-05-06 16:46:54 +02:00
|
|
|
|
2021-03-08 21:12:13 +02:00
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
2019-10-01 22:50:51 +02:00
|
|
|
for {
|
2020-05-06 16:46:54 +02:00
|
|
|
select {
|
|
|
|
case <-bsp.stopCh:
|
2020-05-19 18:36:33 +02:00
|
|
|
return
|
|
|
|
case <-bsp.timer.C:
|
2021-03-08 21:12:13 +02:00
|
|
|
if err := bsp.exportSpans(ctx); err != nil {
|
|
|
|
otel.Handle(err)
|
|
|
|
}
|
2020-05-06 16:46:54 +02:00
|
|
|
case sd := <-bsp.queue:
|
2021-11-05 17:34:57 +02:00
|
|
|
if ffs, ok := sd.(forceFlushSpan); ok {
|
|
|
|
close(ffs.flushed)
|
|
|
|
continue
|
|
|
|
}
|
2020-09-20 19:35:44 +02:00
|
|
|
bsp.batchMutex.Lock()
|
2020-05-19 18:36:33 +02:00
|
|
|
bsp.batch = append(bsp.batch, sd)
|
2021-04-29 18:42:11 +02:00
|
|
|
shouldExport := len(bsp.batch) >= bsp.o.MaxExportBatchSize
|
2020-09-20 19:35:44 +02:00
|
|
|
bsp.batchMutex.Unlock()
|
|
|
|
if shouldExport {
|
2020-05-19 18:36:33 +02:00
|
|
|
if !bsp.timer.Stop() {
|
|
|
|
<-bsp.timer.C
|
2020-05-15 13:01:43 +02:00
|
|
|
}
|
2021-03-08 21:12:13 +02:00
|
|
|
if err := bsp.exportSpans(ctx); err != nil {
|
|
|
|
otel.Handle(err)
|
|
|
|
}
|
2019-10-01 22:50:51 +02:00
|
|
|
}
|
|
|
|
}
|
2020-05-06 16:46:54 +02:00
|
|
|
}
|
2020-05-16 09:19:46 +02:00
|
|
|
}
|
|
|
|
|
2020-05-19 18:36:33 +02:00
|
|
|
// drainQueue awaits the any caller that had added to bsp.stopWait
|
|
|
|
// to finish the enqueue, then exports the final batch.
|
2021-03-05 18:08:29 +02:00
|
|
|
func (bsp *batchSpanProcessor) drainQueue() {
|
2021-03-08 21:12:13 +02:00
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
2020-06-10 00:20:48 +02:00
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case sd := <-bsp.queue:
|
|
|
|
if sd == nil {
|
2021-03-08 21:12:13 +02:00
|
|
|
if err := bsp.exportSpans(ctx); err != nil {
|
|
|
|
otel.Handle(err)
|
|
|
|
}
|
2020-06-10 00:20:48 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-09-20 19:35:44 +02:00
|
|
|
bsp.batchMutex.Lock()
|
2020-06-10 00:20:48 +02:00
|
|
|
bsp.batch = append(bsp.batch, sd)
|
2020-09-20 19:35:44 +02:00
|
|
|
shouldExport := len(bsp.batch) == bsp.o.MaxExportBatchSize
|
|
|
|
bsp.batchMutex.Unlock()
|
|
|
|
|
|
|
|
if shouldExport {
|
2021-03-08 21:12:13 +02:00
|
|
|
if err := bsp.exportSpans(ctx); err != nil {
|
|
|
|
otel.Handle(err)
|
|
|
|
}
|
2020-06-10 00:20:48 +02:00
|
|
|
}
|
|
|
|
default:
|
|
|
|
close(bsp.queue)
|
2019-10-01 22:50:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-05 01:45:13 +02:00
|
|
|
func (bsp *batchSpanProcessor) enqueue(sd ReadOnlySpan) {
|
2021-11-05 17:34:57 +02:00
|
|
|
bsp.enqueueBlockOnQueueFull(context.TODO(), sd, bsp.o.BlockOnQueueFull)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bsp *batchSpanProcessor) enqueueBlockOnQueueFull(ctx context.Context, sd ReadOnlySpan, block bool) bool {
|
2021-05-05 01:45:13 +02:00
|
|
|
if !sd.SpanContext().IsSampled() {
|
2021-11-05 17:34:57 +02:00
|
|
|
return false
|
2020-05-14 13:26:28 +02:00
|
|
|
}
|
|
|
|
|
2020-05-19 18:36:33 +02:00
|
|
|
// This ensures the bsp.queue<- below does not panic as the
|
|
|
|
// processor shuts down.
|
|
|
|
defer func() {
|
|
|
|
x := recover()
|
|
|
|
switch err := x.(type) {
|
|
|
|
case nil:
|
|
|
|
return
|
|
|
|
case runtime.Error:
|
|
|
|
if err.Error() == "send on closed channel" {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
panic(x)
|
|
|
|
}()
|
2020-05-14 13:25:41 +02:00
|
|
|
|
2020-06-10 00:20:48 +02:00
|
|
|
select {
|
|
|
|
case <-bsp.stopCh:
|
2021-11-05 17:34:57 +02:00
|
|
|
return false
|
2020-06-10 00:20:48 +02:00
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
2021-11-05 17:34:57 +02:00
|
|
|
if block {
|
|
|
|
select {
|
|
|
|
case bsp.queue <- sd:
|
|
|
|
return true
|
|
|
|
case <-ctx.Done():
|
|
|
|
return false
|
|
|
|
}
|
2020-05-19 18:36:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case bsp.queue <- sd:
|
2021-11-05 17:34:57 +02:00
|
|
|
return true
|
2020-05-19 18:36:33 +02:00
|
|
|
default:
|
|
|
|
atomic.AddUint32(&bsp.dropped, 1)
|
2019-10-01 22:50:51 +02:00
|
|
|
}
|
2021-11-05 17:34:57 +02:00
|
|
|
return false
|
2019-10-01 22:50:51 +02:00
|
|
|
}
|
2022-01-11 02:58:01 +02:00
|
|
|
|
|
|
|
// MarshalLog is the marshaling function used by the logging system to represent this exporter.
|
|
|
|
func (bsp *batchSpanProcessor) MarshalLog() interface{} {
|
|
|
|
return struct {
|
|
|
|
Type string
|
|
|
|
SpanExporter SpanExporter
|
|
|
|
Config BatchSpanProcessorOptions
|
|
|
|
}{
|
|
|
|
Type: "BatchSpanProcessor",
|
|
|
|
SpanExporter: bsp.e,
|
|
|
|
Config: bsp.o,
|
|
|
|
}
|
|
|
|
}
|