diff --git a/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt index e69de29bb2d..8b90281a056 100644 --- a/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +static OpenTelemetry.Trace.TracerProviderExtensions.ForceFlush(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt index e69de29bb2d..6779d236a29 100644 --- a/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +static OpenTelemetry.Trace.TracerProviderExtensions.ForceFlush(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool diff --git a/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt index e69de29bb2d..6779d236a29 100644 --- a/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +static OpenTelemetry.Trace.TracerProviderExtensions.ForceFlush(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2d..6779d236a29 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +static OpenTelemetry.Trace.TracerProviderExtensions.ForceFlush(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index a0b04e6c57e..e3770cadff8 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -9,6 +9,8 @@ please check the latest changes ## Unreleased +* Added `ForceFlush` to `TracerProvider`. ([#1837](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1837)) + ## 1.0.1 Released 2021-Feb-10 diff --git a/src/OpenTelemetry/Trace/TracerProviderExtensions.cs b/src/OpenTelemetry/Trace/TracerProviderExtensions.cs index 302f85d5173..cfa331e179d 100644 --- a/src/OpenTelemetry/Trace/TracerProviderExtensions.cs +++ b/src/OpenTelemetry/Trace/TracerProviderExtensions.cs @@ -43,6 +43,52 @@ public static TracerProvider AddProcessor(this TracerProvider provider, BaseProc return provider; } + /// + /// Flushes the all the processors at TracerProviderSdk, blocks the current thread until flush + /// completed, shutdown signaled or timed out. + /// + /// TracerProviderSdk instance on which ForceFlush will be called. + /// + /// The number of milliseconds to wait, or Timeout.Infinite to + /// wait indefinitely. + /// + /// + /// Returns true when force flush succeeded; otherwise, false. + /// + /// + /// Thrown when the timeoutMilliseconds is smaller than -1. + /// + /// + /// This function guarantees thread-safety. + /// + public static bool ForceFlush(this TracerProvider provider, int timeoutMilliseconds = Timeout.Infinite) + { + if (provider == null) + { + throw new ArgumentNullException(nameof(provider)); + } + + if (provider is TracerProviderSdk tracerProviderSdk) + { + if (timeoutMilliseconds < 0 && timeoutMilliseconds != Timeout.Infinite) + { + throw new ArgumentOutOfRangeException(nameof(timeoutMilliseconds), timeoutMilliseconds, "timeoutMilliseconds should be non-negative."); + } + + try + { + return tracerProviderSdk.OnForceFlush(timeoutMilliseconds); + } + catch (Exception ex) + { + OpenTelemetrySdkEventSource.Log.TracerProviderException(nameof(tracerProviderSdk.OnForceFlush), ex); + return false; + } + } + + return true; + } + /// /// Attempts to shutdown the TracerProviderSdk, blocks the current thread until /// shutdown completed or timed out. diff --git a/src/OpenTelemetry/Trace/TracerProviderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderSdk.cs index d0759533a5e..a2e6dff3ba4 100644 --- a/src/OpenTelemetry/Trace/TracerProviderSdk.cs +++ b/src/OpenTelemetry/Trace/TracerProviderSdk.cs @@ -207,6 +207,11 @@ internal TracerProviderSdk AddProcessor(BaseProcessor processor) return this; } + internal bool OnForceFlush(int timeoutMilliseconds) + { + return this.processor?.ForceFlush(timeoutMilliseconds) ?? true; + } + /// /// Called by Shutdown. This function should block the current /// thread until shutdown completed or timed out. diff --git a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs index e193cb9b5b6..64891ae7098 100644 --- a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs +++ b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs @@ -398,6 +398,21 @@ public void TracerProviderSdkBuildsWithSDKResource() Assert.Single(versionAttribute); } + [Fact] + public void TracerProviderSdkFlushesProcessorForcibly() + { + using TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddProcessor(testActivityProcessor) + .Build(); + + var isFlushed = tracerProvider.ForceFlush(); + + Assert.True(isFlushed); + Assert.True(testActivityProcessor.ForceFlushCalled); + } + public void Dispose() { GC.SuppressFinalize(this);