diff --git a/CHANGELOG.md b/CHANGELOG.md index e50b85df197..e02f3b0ecca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Remove Metric export functionality related to quantiles and summary data points: this is not specified (#1412) - Remove DDSketch metric aggregator; our intention is to re-introduce this as an option of the histogram aggregator after [new OTLP histogram data types](https://github.com/open-telemetry/opentelemetry-proto/pull/226) are released (#1412) +### Fixed + +- `BatchSpanProcessor.Shutdown()` will now shutdown underlying `export.SpanExporter`. (#1443) + ## [0.15.0] - 2020-12-10 ### Added diff --git a/sdk/trace/batch_span_processor.go b/sdk/trace/batch_span_processor.go index ad4ee29e7c9..302c4559dea 100644 --- a/sdk/trace/batch_span_processor.go +++ b/sdk/trace/batch_span_processor.go @@ -132,6 +132,11 @@ func (bsp *BatchSpanProcessor) Shutdown(ctx context.Context) error { go func() { close(bsp.stopCh) bsp.stopWait.Wait() + if bsp.e != nil { + if err := bsp.e.Shutdown(ctx); err != nil { + otel.Handle(err) + } + } close(wait) }() // Wait until the wait group is done or the context is cancelled diff --git a/sdk/trace/batch_span_processor_test.go b/sdk/trace/batch_span_processor_test.go index 6675484885b..263d8dbad3f 100644 --- a/sdk/trace/batch_span_processor_test.go +++ b/sdk/trace/batch_span_processor_test.go @@ -21,6 +21,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/otel/trace" export "go.opentelemetry.io/otel/sdk/export/trace" @@ -28,10 +30,11 @@ import ( ) type testBatchExporter struct { - mu sync.Mutex - spans []*export.SpanSnapshot - sizes []int - batchCount int + mu sync.Mutex + spans []*export.SpanSnapshot + sizes []int + batchCount int + shutdownCount int } func (t *testBatchExporter) ExportSpans(ctx context.Context, ss []*export.SpanSnapshot) error { @@ -44,7 +47,10 @@ func (t *testBatchExporter) ExportSpans(ctx context.Context, ss []*export.SpanSn return nil } -func (t *testBatchExporter) Shutdown(context.Context) error { return nil } +func (t *testBatchExporter) Shutdown(context.Context) error { + t.shutdownCount++ + return nil +} func (t *testBatchExporter) len() int { t.mu.Lock() @@ -231,16 +237,19 @@ func getSpanContext() trace.SpanContext { } func TestBatchSpanProcessorShutdown(t *testing.T) { - bsp := sdktrace.NewBatchSpanProcessor(&testBatchExporter{}) + var bp testBatchExporter + bsp := sdktrace.NewBatchSpanProcessor(&bp) err := bsp.Shutdown(context.Background()) if err != nil { t.Error("Error shutting the BatchSpanProcessor down\n") } + assert.Equal(t, 1, bp.shutdownCount, "shutdown from span exporter not called") // Multiple call to Shutdown() should not panic. err = bsp.Shutdown(context.Background()) if err != nil { t.Error("Error shutting the BatchSpanProcessor down\n") } + assert.Equal(t, 1, bp.shutdownCount) }