diff --git a/build/Common.props b/build/Common.props index 03ac93b08fb..012cececbc5 100644 --- a/build/Common.props +++ b/build/Common.props @@ -31,6 +31,7 @@ [2.1.1,6.0) [3.3.3] [17.3.0] + [3.1.0,) [2.1.0,) [3.1.0,) [3.1.0,) diff --git a/src/OpenTelemetry/OpenTelemetry.csproj b/src/OpenTelemetry/OpenTelemetry.csproj index 542fcc9e407..b7f6e7fa3f7 100644 --- a/src/OpenTelemetry/OpenTelemetry.csproj +++ b/src/OpenTelemetry/OpenTelemetry.csproj @@ -19,6 +19,7 @@ + diff --git a/src/OpenTelemetry/SdkOptions.cs b/src/OpenTelemetry/SdkOptions.cs new file mode 100644 index 00000000000..9697d20f6b4 --- /dev/null +++ b/src/OpenTelemetry/SdkOptions.cs @@ -0,0 +1,68 @@ +// +// 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. +// + +#nullable enable + +using System; +using System.Diagnostics; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; + +namespace OpenTelemetry +{ + public sealed class SdkOptions + { + private static Action? globalConfigureCallbacks; + + public bool TracingEnabled { get; set; } = true; + + public bool MetricsEnabled { get; set; } = true; + + public bool LoggingEnabled { get; set; } = true; + + public static void RegisterConfigureCallback(Action configure) + { + globalConfigureCallbacks += configure ?? throw new ArgumentNullException(nameof(configure)); + } + + internal sealed class ConfigureSdkOptions : IConfigureOptions + { + private readonly IConfiguration configuration; + + public ConfigureSdkOptions(IConfiguration configuration) + { + Debug.Assert(configuration != null, "configuration was null"); + + this.configuration = configuration!; + } + + public void Configure(SdkOptions options) + { + Debug.Assert(options != null, "options was null"); + + var globalDisableFlagValue = this.configuration.GetValue("OTEL_SDK_DISABLED", false); + if (globalDisableFlagValue) + { + options!.TracingEnabled = false; + options.MetricsEnabled = false; + options.LoggingEnabled = false; + } + + globalConfigureCallbacks?.Invoke(options!); + } + } + } +} diff --git a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs index a747395308c..c337e65d65d 100644 --- a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs +++ b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs @@ -18,6 +18,7 @@ using System; using System.Diagnostics; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; @@ -51,8 +52,15 @@ internal TracerProviderBuilderBase(IServiceCollection services) { Guard.ThrowIfNull(services); - services.AddOptions(); - services.TryAddSingleton(sp => new TracerProviderSdk(sp, ownsServiceProvider: false)); + RegisterSharedServices(services); + + services.TryAddSingleton(sp => + { + var sdkOptions = sp.GetRequiredService>().Value; + return !sdkOptions.TracingEnabled + ? new NoopTracerProvider() + : new TracerProviderSdk(sp, ownsServiceProvider: false); + }); this.services = services; this.ownsServices = false; @@ -64,7 +72,7 @@ protected TracerProviderBuilderBase() { var services = new ServiceCollection(); - services.AddOptions(); + RegisterSharedServices(services); this.services = services; this.ownsServices = true; @@ -266,7 +274,24 @@ protected TracerProvider Build() #endif var serviceProvider = services.BuildServiceProvider(validateScopes); - return new TracerProviderSdk(serviceProvider, ownsServiceProvider: true); + var sdkOptions = serviceProvider.GetRequiredService>().Value; + if (!sdkOptions.TracingEnabled) + { + serviceProvider.Dispose(); + + return new NoopTracerProvider(); + } + else + { + return new TracerProviderSdk(serviceProvider, ownsServiceProvider: true); + } + } + + private static void RegisterSharedServices(IServiceCollection services) + { + services.AddOptions(); + services.TryAddSingleton(sp => new ConfigurationBuilder().AddEnvironmentVariables().Build()); + services.TryAddSingleton, SdkOptions.ConfigureSdkOptions>(); } private static BaseProcessor BuildExportProcessor( diff --git a/src/OpenTelemetry/Trace/NoopTracerProvider.cs b/src/OpenTelemetry/Trace/NoopTracerProvider.cs new file mode 100644 index 00000000000..ce1884f1def --- /dev/null +++ b/src/OpenTelemetry/Trace/NoopTracerProvider.cs @@ -0,0 +1,24 @@ +// +// 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. +// + +#nullable enable + +namespace OpenTelemetry.Trace +{ + internal sealed class NoopTracerProvider : TracerProvider + { + } +}