diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt index e69de29bb2d..34e3029ac53 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.IOpenTelemetryBuilder +OpenTelemetry.IOpenTelemetryBuilder.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection! diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md index 25df4b8179a..721930376d4 100644 --- a/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Added `IOpenTelemetryBuilder` interface to support authoring extensions which + can configure multiple OpenTelemetry signals (tracing, metrics, and/or logs). + ([#5265](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5265)) + ## 1.7.0 Released 2023-Dec-08 diff --git a/src/OpenTelemetry.Api.ProviderBuilderExtensions/IOpenTelemetryBuilder.cs b/src/OpenTelemetry.Api.ProviderBuilderExtensions/IOpenTelemetryBuilder.cs new file mode 100644 index 00000000000..872eaf3975f --- /dev/null +++ b/src/OpenTelemetry.Api.ProviderBuilderExtensions/IOpenTelemetryBuilder.cs @@ -0,0 +1,19 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.DependencyInjection; + +namespace OpenTelemetry; + +/// +/// An interface for configuring OpenTelemetry inside an . +/// +public interface IOpenTelemetryBuilder +{ + /// + /// Gets the where OpenTelemetry services + /// are configured. + /// + IServiceCollection Services { get; } +} diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index ef7152a1205..97f90b4cf03 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* `OpenTelemetryBuilder` has been marked obsolete. Component authors using + `OpenTelemetryBuilder` for cross-cutting signal configuration extensions + should switch to targeting `IOpenTelemetryBuilder` instead. + ([#5265](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5265)) + ## 1.7.0 Released 2023-Dec-08 diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetry.Extensions.Hosting.csproj b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetry.Extensions.Hosting.csproj index 5e798a19f67..93cdb8cf92e 100644 --- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetry.Extensions.Hosting.csproj +++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetry.Extensions.Hosting.csproj @@ -10,7 +10,6 @@ - diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs index 3037f1f162c..2ddb9b50055 100644 --- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs +++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryBuilder.cs @@ -19,7 +19,8 @@ namespace OpenTelemetry; /// Contains methods for configuring the OpenTelemetry SDK inside an . /// -public sealed class OpenTelemetryBuilder +[Obsolete("Use IOpenTelemetryBuilder instead this class will be removed in a future version.")] +public sealed class OpenTelemetryBuilder : IOpenTelemetryBuilder { internal OpenTelemetryBuilder(IServiceCollection services) { @@ -30,9 +31,7 @@ internal OpenTelemetryBuilder(IServiceCollection services) this.Services = services; } - /// - /// Gets the behind the builder. - /// + /// public IServiceCollection Services { get; } /// @@ -50,17 +49,7 @@ internal OpenTelemetryBuilder(IServiceCollection services) public OpenTelemetryBuilder ConfigureResource( Action configure) { - Guard.ThrowIfNull(configure); - - this.Services.ConfigureOpenTelemetryMeterProvider( - builder => builder.ConfigureResource(configure)); - - this.Services.ConfigureOpenTelemetryTracerProvider( - builder => builder.ConfigureResource(configure)); - - this.Services.ConfigureOpenTelemetryLoggerProvider( - builder => builder.ConfigureResource(configure)); - + OpenTelemetryBuilderSdkExtensions.ConfigureResource(this, configure); return this; } @@ -93,10 +82,7 @@ public OpenTelemetryBuilder WithMetrics() /// calls. public OpenTelemetryBuilder WithMetrics(Action configure) { - OpenTelemetryMetricsBuilderExtensions.RegisterMetricsListener( - this.Services, - configure); - + OpenTelemetryBuilderSdkExtensions.WithMetrics(this, configure); return this; } @@ -123,12 +109,7 @@ public OpenTelemetryBuilder WithTracing() /// calls. public OpenTelemetryBuilder WithTracing(Action configure) { - Guard.ThrowIfNull(configure); - - var builder = new TracerProviderBuilderBase(this.Services); - - configure(builder); - + OpenTelemetryBuilderSdkExtensions.WithTracing(this, configure); return this; } @@ -240,8 +221,7 @@ OpenTelemetryBuilder WithLogging( Action? configureBuilder, Action? configureOptions) { - this.Services.AddLogging( - logging => logging.UseOpenTelemetry(configureBuilder, configureOptions)); + OpenTelemetryBuilderSdkExtensions.WithLogging(this, configureBuilder, configureOptions); return this; } diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs index a91d186ccbd..ac875dd4cc3 100644 --- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs @@ -36,7 +36,12 @@ public static class OpenTelemetryServicesExtensions /// . /// The supplied for chaining /// calls. +#pragma warning disable CS0618 // Type or member is obsolete + // Note: OpenTelemetryBuilder is obsolete because users should target + // IOpenTelemetryBuilder for extensions but this method is valid and + // expected to be called to obtain a root builder. public static OpenTelemetryBuilder AddOpenTelemetry(this IServiceCollection services) +#pragma warning restore CS0618 // Type or member is obsolete { Guard.ThrowIfNull(services); diff --git a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt index 822863b4660..16832495101 100644 --- a/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/Experimental/PublicAPI.Unshipped.txt @@ -32,6 +32,9 @@ static OpenTelemetry.Logs.LoggerProviderExtensions.AddProcessor(this OpenTelemet static OpenTelemetry.Logs.LoggerProviderExtensions.ForceFlush(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool static OpenTelemetry.Logs.LoggerProviderExtensions.Shutdown(this OpenTelemetry.Logs.LoggerProvider! provider, int timeoutMilliseconds = -1) -> bool static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetExemplarFilter(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.ExemplarFilter! exemplarFilter) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithLogging(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action? configureBuilder, System.Action? configureOptions) -> OpenTelemetry.IOpenTelemetryBuilder! static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.LoggerProviderBuilder! abstract OpenTelemetry.Metrics.ExemplarFilter.ShouldSample(double value, System.ReadOnlySpan> tags) -> bool abstract OpenTelemetry.Metrics.ExemplarFilter.ShouldSample(long value, System.ReadOnlySpan> tags) -> bool diff --git a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt index e69de29bb2d..d58a0903257 100644 --- a/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -0,0 +1,6 @@ +OpenTelemetry.OpenTelemetryBuilderSdkExtensions +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.ConfigureResource(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithMetrics(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithMetrics(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithTracing(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder! +static OpenTelemetry.OpenTelemetryBuilderSdkExtensions.WithTracing(this OpenTelemetry.IOpenTelemetryBuilder! builder, System.Action! configure) -> OpenTelemetry.IOpenTelemetryBuilder! diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 414dd3fb849..b2636f35de3 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -28,6 +28,16 @@ experimental Log Bridge API. [#5317](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5317) +* Added `OpenTelemetryBuilderSdkExtensions` class which contains extension + methods (`ConfigureResource`, `WithMetrics`, `WithTracing`, and experimental + `WithLogging`) for the `IOpenTelemetryBuilder` interface. + ([#5265](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5265)) + +* Added `Microsoft.Extensions.Diagnostics.Abstractions` dependency so that the + `IOpenTelemetryBuilder.WithMetrics` extension method can configure + [IMetricsListener](https://learn.microsoft.com/dotNet/api/microsoft.extensions.diagnostics.metrics.imetricslistener). + ([#5265](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5265)) + ## 1.7.0 Released 2023-Dec-08 diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryMetricsBuilderExtensions.cs b/src/OpenTelemetry/Metrics/IMetricsListener/OpenTelemetryMetricsBuilderExtensions.cs similarity index 100% rename from src/OpenTelemetry.Extensions.Hosting/OpenTelemetryMetricsBuilderExtensions.cs rename to src/OpenTelemetry/Metrics/IMetricsListener/OpenTelemetryMetricsBuilderExtensions.cs diff --git a/src/OpenTelemetry.Extensions.Hosting/Implementation/OpenTelemetryMetricsListener.cs b/src/OpenTelemetry/Metrics/IMetricsListener/OpenTelemetryMetricsListener.cs similarity index 100% rename from src/OpenTelemetry.Extensions.Hosting/Implementation/OpenTelemetryMetricsListener.cs rename to src/OpenTelemetry/Metrics/IMetricsListener/OpenTelemetryMetricsListener.cs diff --git a/src/OpenTelemetry/OpenTelemetry.csproj b/src/OpenTelemetry/OpenTelemetry.csproj index 45faafaec91..fb1cee1bcd3 100644 --- a/src/OpenTelemetry/OpenTelemetry.csproj +++ b/src/OpenTelemetry/OpenTelemetry.csproj @@ -6,6 +6,7 @@ + diff --git a/src/OpenTelemetry/OpenTelemetryBuilderSdkExtensions.cs b/src/OpenTelemetry/OpenTelemetryBuilderSdkExtensions.cs new file mode 100644 index 00000000000..4ae87d34078 --- /dev/null +++ b/src/OpenTelemetry/OpenTelemetryBuilderSdkExtensions.cs @@ -0,0 +1,254 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.Metrics; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Internal; +using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; + +namespace OpenTelemetry; + +/// +/// Contains methods for extending the interface. +/// +public static class OpenTelemetryBuilderSdkExtensions +{ + /// + /// Registers an action to configure the s used + /// by tracing, metrics, and logging. + /// + /// . + /// + /// Note: This is safe to be called multiple times and by library authors. + /// Each registered configuration action will be applied sequentially. + /// + /// configuration + /// action. + /// The supplied for chaining + /// calls. + public static IOpenTelemetryBuilder ConfigureResource( + this IOpenTelemetryBuilder builder, + Action configure) + { + Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(configure); + + builder.Services.ConfigureOpenTelemetryMeterProvider( + builder => builder.ConfigureResource(configure)); + + builder.Services.ConfigureOpenTelemetryTracerProvider( + builder => builder.ConfigureResource(configure)); + + builder.Services.ConfigureOpenTelemetryLoggerProvider( + builder => builder.ConfigureResource(configure)); + + return builder; + } + + /// + /// Adds metric services into the builder. + /// + /// . + /// + /// Notes: + /// + /// This is safe to be called multiple times and by library authors. + /// Only a single will be created for a given + /// . + /// This method automatically registers an named 'OpenTelemetry' into the . + /// + /// + /// The supplied for chaining + /// calls. + public static IOpenTelemetryBuilder WithMetrics( + this IOpenTelemetryBuilder builder) + => WithMetrics(builder, b => { }); + + /// + /// Adds metric services into the builder. + /// + /// + /// . + /// + /// configuration callback. + /// The supplied for chaining + /// calls. + public static IOpenTelemetryBuilder WithMetrics( + this IOpenTelemetryBuilder builder, + Action configure) + { + OpenTelemetryMetricsBuilderExtensions.RegisterMetricsListener( + builder.Services, + configure); + + return builder; + } + + /// + /// Adds tracing services into the builder. + /// + /// . + /// + /// Note: This is safe to be called multiple times and by library authors. + /// Only a single will be created for a given + /// . + /// + /// The supplied for chaining + /// calls. + public static IOpenTelemetryBuilder WithTracing(this IOpenTelemetryBuilder builder) + => WithTracing(builder, b => { }); + + /// + /// Adds tracing services into the builder. + /// + /// + /// . + /// + /// configuration callback. + /// The supplied for chaining + /// calls. + public static IOpenTelemetryBuilder WithTracing( + this IOpenTelemetryBuilder builder, + Action configure) + { + Guard.ThrowIfNull(configure); + + var tracerProviderBuilder = new TracerProviderBuilderBase(builder.Services); + + configure(tracerProviderBuilder); + + return builder; + } + +#if EXPOSE_EXPERIMENTAL_FEATURES + /// + /// Adds logging services into the builder. + /// + /// . + /// + /// WARNING: This is an experimental API which might change or + /// be removed in the future. Use at your own risk. + /// Notes: + /// + /// This is safe to be called multiple times and by library authors. + /// Only a single will be created for a given + /// . + /// This method automatically registers an named 'OpenTelemetry' into the . + /// + /// + /// The supplied for chaining + /// calls. +#if NET8_0_OR_GREATER + [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif + public +#else + /// + /// Adds logging services into the builder. + /// + /// . + /// + /// Notes: + /// + /// This is safe to be called multiple times and by library authors. + /// Only a single will be created for a given + /// . + /// This method automatically registers an named 'OpenTelemetry' into the . + /// + /// + /// The supplied for chaining + /// calls. + internal +#endif + static IOpenTelemetryBuilder WithLogging(this IOpenTelemetryBuilder builder) + => WithLogging(builder, configureBuilder: null, configureOptions: null); + +#if EXPOSE_EXPERIMENTAL_FEATURES + /// + /// Adds logging services into the builder. + /// + /// + /// . + /// + /// configuration callback. + /// The supplied for chaining + /// calls. +#if NET8_0_OR_GREATER + [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif + public +#else + /// + /// Adds logging services into the builder. + /// + /// + /// . + /// + /// configuration callback. + /// The supplied for chaining + /// calls. + internal +#endif + static IOpenTelemetryBuilder WithLogging( + this IOpenTelemetryBuilder builder, + Action configure) + { + Guard.ThrowIfNull(configure); + + return WithLogging(builder, configureBuilder: configure, configureOptions: null); + } + +#if EXPOSE_EXPERIMENTAL_FEATURES + /// + /// Adds logging services into the builder. + /// + /// + /// . + /// Optional configuration callback. + /// Optional configuration callback. + /// The supplied for chaining + /// calls. +#if NET8_0_OR_GREATER + [Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif + public +#else + /// + /// Adds logging services into the builder. + /// + /// + /// . + /// Optional configuration callback. + /// Optional configuration callback. + /// The supplied for chaining + /// calls. + internal +#endif + static IOpenTelemetryBuilder WithLogging( + this IOpenTelemetryBuilder builder, + Action? configureBuilder, + Action? configureOptions) + { + builder.Services.AddLogging( + logging => logging.UseOpenTelemetry(configureBuilder, configureOptions)); + + return builder; + } +}