diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs index f69f9424953..c862379ca2e 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporter.cs @@ -25,6 +25,7 @@ public class InMemoryExporter : BaseExporter private readonly ICollection exportedItems; private readonly ExportFunc onExport; private bool disposed; + private string disposedStackTrace; public InMemoryExporter(ICollection exportedItems) { @@ -44,7 +45,9 @@ public override ExportResult Export(in Batch batch) if (this.disposed) { // Note: In-memory exporter is designed for testing purposes so this error is strategic to surface lifecycle management bugs during development. - throw new ObjectDisposedException(this.GetType().Name, "The in-memory exporter is still being invoked after it has been disposed. This could be the result of invalid lifecycle management of the OpenTelemetry .NET SDK."); + throw new ObjectDisposedException( + this.GetType().Name, + $"The in-memory exporter is still being invoked after it has been disposed. This could be the result of invalid lifecycle management of the OpenTelemetry .NET SDK. Dispose was called on the following stack trace:{Environment.NewLine}{this.disposedStackTrace}"); } return this.onExport(batch); @@ -55,6 +58,7 @@ protected override void Dispose(bool disposing) { if (!this.disposed) { + this.disposedStackTrace = Environment.StackTrace; this.disposed = true; } diff --git a/test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs b/test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs index 4a9e6ed3fd5..feb5834ab19 100644 --- a/test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs +++ b/test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs @@ -32,8 +32,9 @@ public void StateValuesAndScopeBufferingTest() List exportedItems = new(); - using var exporter = new BatchLogRecordExportProcessor( - new InMemoryExporter(exportedItems)); + using var processor = new BatchLogRecordExportProcessor( + new InMemoryExporter(exportedItems), + scheduledDelayMilliseconds: int.MaxValue); using var scope = scopeProvider.Push(exportedItems); @@ -44,7 +45,7 @@ public void StateValuesAndScopeBufferingTest() logRecord.ScopeProvider = scopeProvider; logRecord.StateValues = state; - exporter.OnEnd(logRecord); + processor.OnEnd(logRecord); state.Dispose(); @@ -70,6 +71,10 @@ public void StateValuesAndScopeBufferingTest() null); Assert.True(foundScope); + + processor.Shutdown(); + + Assert.Single(exportedItems); } [Fact] @@ -81,7 +86,7 @@ public void StateBufferingTest() // StateValues/ParseStateValues behavior. List exportedItems = new(); - using var exporter = new BatchLogRecordExportProcessor( + using var processor = new BatchLogRecordExportProcessor( new InMemoryExporter(exportedItems)); var logRecord = new LogRecord(); @@ -89,7 +94,8 @@ public void StateBufferingTest() var state = new LogRecordTest.DisposingState("Hello world"); logRecord.State = state; - exporter.OnEnd(logRecord); + processor.OnEnd(logRecord); + processor.Shutdown(); state.Dispose();