diff --git a/examples/MicroserviceExample/Utils/Messaging/MessageSender.cs b/examples/MicroserviceExample/Utils/Messaging/MessageSender.cs index d79655d814d..29a7fd20ec5 100644 --- a/examples/MicroserviceExample/Utils/Messaging/MessageSender.cs +++ b/examples/MicroserviceExample/Utils/Messaging/MessageSender.cs @@ -28,7 +28,7 @@ namespace Utils.Messaging public class MessageSender : IDisposable { private static readonly ActivitySource ActivitySource = new ActivitySource(nameof(MessageSender)); - private static readonly TextMapPropagator Propagator = new TraceContextPropagator(); + private static readonly TextMapPropagator Propagator = Propagators.DefaultTextMapPropagator; private readonly ILogger logger; private readonly IConnection connection; diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index 3792ecf50fc..52d89e2dded 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -15,6 +15,8 @@ to CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator and changed from interface to abstract class. ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427)) +* Added GlobalPropagators API via Propagators.DefaultTextMapPropagator. + ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1428)) ## 0.7.0-beta.1 diff --git a/src/OpenTelemetry.Api/Context/Propagation/NoopTextMapPropagator.cs b/src/OpenTelemetry.Api/Context/Propagation/NoopTextMapPropagator.cs new file mode 100644 index 00000000000..8060df2977e --- /dev/null +++ b/src/OpenTelemetry.Api/Context/Propagation/NoopTextMapPropagator.cs @@ -0,0 +1,37 @@ +// +// Copyright The OpenTelemetry Authors +// +// 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. +// + +using System; +using System.Collections.Generic; + +namespace OpenTelemetry.Context.Propagation +{ + internal class NoopTextMapPropagator : TextMapPropagator + { + private static readonly PropagationContext DefaultPropagationContext = default; + + public override ISet Fields => null; + + public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + { + return DefaultPropagationContext; + } + + public override void Inject(PropagationContext context, T carrier, Action setter) + { + } + } +} diff --git a/src/OpenTelemetry.Api/Context/Propagation/Propagators.cs b/src/OpenTelemetry.Api/Context/Propagation/Propagators.cs new file mode 100644 index 00000000000..645cd600bce --- /dev/null +++ b/src/OpenTelemetry.Api/Context/Propagation/Propagators.cs @@ -0,0 +1,39 @@ +// +// Copyright The OpenTelemetry Authors +// +// 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. +// + +namespace OpenTelemetry.Context.Propagation +{ + /// + /// Propagators allow setting the global default Propagators. + /// + public static class Propagators + { + private static readonly TextMapPropagator Noop = new NoopTextMapPropagator(); + + /// + /// Gets the Default TextMapPropagator to be used. + /// + /// + /// Setting this can be done only from Sdk. + /// + public static TextMapPropagator DefaultTextMapPropagator { get; internal set; } = Noop; + + internal static void Reset() + { + DefaultTextMapPropagator = Noop; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs index e53b92d6382..c0c97345e72 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs @@ -27,13 +27,10 @@ namespace OpenTelemetry.Instrumentation.AspNet public class AspNetInstrumentationOptions { /// - /// Gets or sets for context propagation. Default value: with & . + /// Gets or sets for context propagation. + /// By default, will be used. /// - public TextMapPropagator Propagator { get; set; } = new CompositeTextMapPropagator(new TextMapPropagator[] - { - new TraceContextPropagator(), - new BaggagePropagator(), - }); + public TextMapPropagator Propagator { get; set; } /// /// Gets or sets a Filter function to filter instrumentation for requests on a per request basis. diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 5bf0cc5b2ae..dd2c46a1853 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -6,6 +6,8 @@ to CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator and changed from interface to abstract class. ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427)) +* Propagators.DefaultTextMapPropagator will be used as the default Propagator + ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1428)) ## 0.7.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index d1e5c99f6e3..ac7d3636704 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -69,10 +69,11 @@ public override void OnStartActivity(Activity activity, object payload) var request = context.Request; var requestValues = request.Unvalidated; + var textMapPropagator = this.options.Propagator ?? Propagators.DefaultTextMapPropagator; - if (!(this.options.Propagator is TraceContextPropagator)) + if (!(textMapPropagator is TraceContextPropagator)) { - var ctx = this.options.Propagator.Extract(default, request, HttpRequestHeaderValuesGetter); + var ctx = textMapPropagator.Extract(default, request, HttpRequestHeaderValuesGetter); if (ctx.ActivityContext.IsValid() && ctx.ActivityContext != new ActivityContext(activity.TraceId, activity.ParentSpanId, activity.ActivityTraceFlags, activity.TraceStateString, true)) @@ -139,7 +140,8 @@ public override void OnStopActivity(Activity activity, object payload) Activity activityToEnrich = activity; Activity createdActivity = null; - bool isCustomPropagator = !(this.options.Propagator is TraceContextPropagator); + var textMapPropagator = this.options.Propagator ?? Propagators.DefaultTextMapPropagator; + bool isCustomPropagator = !(textMapPropagator is TraceContextPropagator); if (isCustomPropagator) { diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationOptions.cs index e07372fd60d..da3b9a908f0 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationOptions.cs @@ -27,13 +27,10 @@ namespace OpenTelemetry.Instrumentation.AspNetCore public class AspNetCoreInstrumentationOptions { /// - /// Gets or sets for context propagation. Default value: with & . + /// Gets or sets for context propagation. + /// By default, will be used. /// - public TextMapPropagator Propagator { get; set; } = new CompositeTextMapPropagator(new TextMapPropagator[] - { - new TraceContextPropagator(), - new BaggagePropagator(), - }); + public TextMapPropagator Propagator { get; set; } = Propagators.DefaultTextMapPropagator; /// /// Gets or sets a Filter function to filter instrumentation for requests on a per request basis. diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 973f95d0f2f..0de5b6a4869 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -14,6 +14,8 @@ to CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator and changed from interface to abstract class. ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427)) +* Propagators.DefaultTextMapPropagator will be used as the default Propagator + ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1428)) ## 0.7.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index e42f76fb8ec..0e4d8e4a630 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -10,6 +10,8 @@ to CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator and changed from interface to abstract class. ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427)) +* Propagators.DefaultTextMapPropagator will be used as the default Propagator + ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1428)) ## 0.7.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs index da4293c3b64..eaf8fd1dcf3 100644 --- a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs @@ -35,13 +35,10 @@ public class HttpClientInstrumentationOptions public bool SetHttpFlavor { get; set; } /// - /// Gets or sets for context propagation. Default value: with & . + /// Gets or sets for context propagation. + /// By default, will be used. /// - public TextMapPropagator Propagator { get; set; } = new CompositeTextMapPropagator(new TextMapPropagator[] - { - new TraceContextPropagator(), - new BaggagePropagator(), - }); + public TextMapPropagator Propagator { get; set; } = Propagators.DefaultTextMapPropagator; /// /// Gets or sets a Filter function to filter instrumentation for requests on a per request basis. diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs index 9c1799bee1b..abbc3e4103e 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs @@ -31,6 +31,13 @@ public class OpenTelemetryLoggerProvider : ILoggerProvider, ISupportExternalScop private bool disposed; private IExternalScopeProvider scopeProvider; + static OpenTelemetryLoggerProvider() + { + // Accessing Sdk class is just to trigger its static ctor, + // which sets default Propagators and default Activity Id format + _ = Sdk.SuppressInstrumentation; + } + public OpenTelemetryLoggerProvider(IOptionsMonitor options) : this(options?.CurrentValue) { diff --git a/src/OpenTelemetry/Sdk.cs b/src/OpenTelemetry/Sdk.cs index 30fc0e3a4e9..aa91e985150 100644 --- a/src/OpenTelemetry/Sdk.cs +++ b/src/OpenTelemetry/Sdk.cs @@ -14,6 +14,8 @@ // limitations under the License. // +using System.Diagnostics; +using OpenTelemetry.Context.Propagation; using OpenTelemetry.Metrics; using OpenTelemetry.Trace; @@ -24,11 +26,32 @@ namespace OpenTelemetry /// public static class Sdk { + static Sdk() + { + Propagators.DefaultTextMapPropagator = new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + new BaggagePropagator(), + }); + + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + Activity.ForceDefaultIdFormat = true; + } + /// /// Gets a value indicating whether instrumentation is suppressed (disabled). /// public static bool SuppressInstrumentation => SuppressInstrumentationScope.IsSuppressed; + /// + /// Sets the Default TextMapPropagator. + /// + /// TextMapPropagator to be set as default. + public static void SetDefaultTextMapPropagator(TextMapPropagator textMapPropagator) + { + Propagators.DefaultTextMapPropagator = textMapPropagator; + } + /// /// Creates MeterProviderBuilder which should be used to build MeterProvider. /// diff --git a/src/OpenTelemetry/Trace/TracerProviderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderSdk.cs index 3fdca25f7db..2ee6ad57ccb 100644 --- a/src/OpenTelemetry/Trace/TracerProviderSdk.cs +++ b/src/OpenTelemetry/Trace/TracerProviderSdk.cs @@ -34,12 +34,6 @@ internal class TracerProviderSdk : TracerProvider private readonly ActivitySourceAdapter adapter; private BaseProcessor processor; - static TracerProviderSdk() - { - Activity.DefaultIdFormat = ActivityIdFormat.W3C; - Activity.ForceDefaultIdFormat = true; - } - internal TracerProviderSdk( Resource resource, IEnumerable sources, diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index 66572aac705..b343af26f11 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -58,6 +58,21 @@ public void AddAspNetCoreInstrumentation_BadArgs() Assert.Throws(() => builder.AddAspNetCoreInstrumentation()); } + [Fact] + public void DefaultPropagatorIsFromPropagators() + { + var options = new AspNetCoreInstrumentationOptions(); + Assert.Same(Propagators.DefaultTextMapPropagator, options.Propagator); + } + + [Fact] + public void PropagatorSetDoesNotAffectGlobalPropagators() + { + var options = new AspNetCoreInstrumentationOptions(); + options.Propagator = new TraceContextPropagator(); + Assert.NotSame(Propagators.DefaultTextMapPropagator, options.Propagator); + } + [Fact] public async Task StatusIsUnsetOn200Response() { diff --git a/test/OpenTelemetry.Tests/Context/PropagatorsTest.cs b/test/OpenTelemetry.Tests/Context/PropagatorsTest.cs new file mode 100644 index 00000000000..c6765568a4e --- /dev/null +++ b/test/OpenTelemetry.Tests/Context/PropagatorsTest.cs @@ -0,0 +1,51 @@ +// +// Copyright The OpenTelemetry Authors +// +// 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. +// + +using System; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Context.Propagation.Tests; +using Xunit; + +namespace OpenTelemetry.Context.Tests +{ + public class PropagatorsTest : IDisposable + { + public PropagatorsTest() + { + Propagators.Reset(); + } + + [Fact] + public void DefaultTextMapPropagatorIsNoop() + { + Assert.IsType(Propagators.DefaultTextMapPropagator); + Assert.Same(Propagators.DefaultTextMapPropagator, Propagators.DefaultTextMapPropagator); + } + + [Fact] + public void CanSetPropagator() + { + var testPropagator = new TestPropagator(string.Empty, string.Empty); + Propagators.DefaultTextMapPropagator = testPropagator; + Assert.Same(testPropagator, Propagators.DefaultTextMapPropagator); + } + + public void Dispose() + { + Propagators.Reset(); + } + } +} diff --git a/test/OpenTelemetry.Tests/Trace/Propagation/TestPropagator.cs b/test/OpenTelemetry.Tests/Shared/TestPropagator.cs similarity index 100% rename from test/OpenTelemetry.Tests/Trace/Propagation/TestPropagator.cs rename to test/OpenTelemetry.Tests/Shared/TestPropagator.cs