From 982f3db766365195fe61809375ff8f4393c6905e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 9 Sep 2022 11:37:45 -0700 Subject: [PATCH 01/11] Mirror TracerProviderBuilder dependency injection API onto MeterProviderBuilder. --- .../CHANGELOG.md | 4 + .../MeterProviderBuilderHosting.cs | 62 ---- .../Metrics/MeterProviderBuilderExtensions.cs | 75 +---- .../OpenTelemetryServicesExtensions.cs | 91 +++--- src/OpenTelemetry/CHANGELOG.md | 4 + .../Builder/MeterProviderBuilderBase.cs | 301 ++++++++++++++++++ .../MeterProviderBuilderExtensions.cs | 177 ++++++---- .../{ => Builder}/MeterProviderBuilderSdk.cs | 25 +- ...viderBuilderServiceCollectionExtensions.cs | 77 +++++ ...rProviderBuilderServiceCollectionHelper.cs | 81 +++++ .../Builder/MeterProviderBuilderState.cs | 127 ++++++++ .../Metrics/MeterProviderBuilderBase.cs | 169 ---------- src/OpenTelemetry/Metrics/MeterProviderSdk.cs | 81 +++-- .../Metrics/MetricReaderOptions.cs | 16 +- .../Metrics/MetricAPITest.cs | 12 +- 15 files changed, 844 insertions(+), 458 deletions(-) delete mode 100644 src/OpenTelemetry.Extensions.Hosting/Implementation/MeterProviderBuilderHosting.cs create mode 100644 src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs rename src/OpenTelemetry/Metrics/{ => Builder}/MeterProviderBuilderExtensions.cs (62%) rename src/OpenTelemetry/Metrics/{ => Builder}/MeterProviderBuilderSdk.cs (80%) create mode 100644 src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionExtensions.cs create mode 100644 src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs create mode 100644 src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs delete mode 100644 src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index bb3df948aad..51c2ee164de 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -6,6 +6,10 @@ `TracerProvider` has been moved into the SDK. ([#3533](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3533)) +* Dependency injection support when configuring + `MeterProvider` has been moved into the SDK. + ([#XXXX](https://github.com/open-telemetry/opentelemetry-dotnet/pull/XXXX)) + ## 1.0.0-rc9.6 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Extensions.Hosting/Implementation/MeterProviderBuilderHosting.cs b/src/OpenTelemetry.Extensions.Hosting/Implementation/MeterProviderBuilderHosting.cs deleted file mode 100644 index 583ace09454..00000000000 --- a/src/OpenTelemetry.Extensions.Hosting/Implementation/MeterProviderBuilderHosting.cs +++ /dev/null @@ -1,62 +0,0 @@ -// -// 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; -using Microsoft.Extensions.DependencyInjection; -using OpenTelemetry.Internal; - -namespace OpenTelemetry.Metrics -{ - /// - /// A with support for deferred initialization using for dependency injection. - /// - internal sealed class MeterProviderBuilderHosting : MeterProviderBuilderBase, IDeferredMeterProviderBuilder - { - private readonly List> configurationActions = new(); - - public MeterProviderBuilderHosting(IServiceCollection services) - { - Guard.ThrowIfNull(services); - - this.Services = services; - } - - public IServiceCollection Services { get; } - - public MeterProviderBuilder Configure(Action configure) - { - Guard.ThrowIfNull(configure); - - this.configurationActions.Add(configure); - return this; - } - - public MeterProvider Build(IServiceProvider serviceProvider) - { - Guard.ThrowIfNull(serviceProvider); - - // Note: Not using a foreach loop because additional actions can be - // added during each call. - for (int i = 0; i < this.configurationActions.Count; i++) - { - this.configurationActions[i](serviceProvider, this); - } - - return this.Build(); - } - } -} diff --git a/src/OpenTelemetry.Extensions.Hosting/Metrics/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/Metrics/MeterProviderBuilderExtensions.cs index 30dd08f4198..d0056b28467 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Metrics/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Metrics/MeterProviderBuilderExtensions.cs @@ -24,42 +24,6 @@ namespace OpenTelemetry.Metrics /// public static class MeterProviderBuilderExtensions { - /// - /// Adds instrumentation to the provider. - /// - /// Instrumentation type. - /// . - /// The supplied for chaining. - public static MeterProviderBuilder AddInstrumentation(this MeterProviderBuilder meterProviderBuilder) - where T : class - { - if (meterProviderBuilder is MeterProviderBuilderHosting meterProviderBuilderHosting) - { - meterProviderBuilderHosting.Configure((sp, builder) => builder - .AddInstrumentation(() => sp.GetRequiredService())); - } - - return meterProviderBuilder; - } - - /// - /// Adds a reader to the provider. - /// - /// Reader type. - /// . - /// The supplied for chaining. - public static MeterProviderBuilder AddReader(this MeterProviderBuilder meterProviderBuilder) - where T : MetricReader - { - if (meterProviderBuilder is MeterProviderBuilderHosting meterProviderBuilderHosting) - { - meterProviderBuilderHosting.Configure((sp, builder) => builder - .AddReader(sp.GetRequiredService())); - } - - return meterProviderBuilder; - } - /// /// Register a callback action to configure the once the application (this MeterProviderBuilder meterP /// . /// Configuration callback. /// The supplied for chaining. + [Obsolete("Call ConfigureBuilder instead this method will be removed in a future version.")] public static MeterProviderBuilder Configure(this MeterProviderBuilder meterProviderBuilder, Action configure) { - if (meterProviderBuilder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) - { - deferredMeterProviderBuilder.Configure(configure); - } - - return meterProviderBuilder; + return meterProviderBuilder.ConfigureBuilder(configure); } /// @@ -85,35 +45,12 @@ public static MeterProviderBuilder Configure(this MeterProviderBuilder meterProv /// . /// or /// if services are unavailable. + [Obsolete("Call ConfigureServices instead this method will be removed in a future version.")] public static IServiceCollection GetServices(this MeterProviderBuilder meterProviderBuilder) { - if (meterProviderBuilder is MeterProviderBuilderHosting meterProviderBuilderHosting) - { - return meterProviderBuilderHosting.Services; - } - - return null; - } - - /// - /// Run the configured actions to initialize the . - /// - /// . - /// . - /// . - public static MeterProvider Build(this MeterProviderBuilder meterProviderBuilder, IServiceProvider serviceProvider) - { - if (meterProviderBuilder is MeterProviderBuilderHosting meterProviderBuilderHosting) - { - return meterProviderBuilderHosting.Build(serviceProvider); - } - - if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) - { - return meterProviderBuilderBase.Build(); - } - - return null; + IServiceCollection services = null; + meterProviderBuilder.ConfigureServices(s => services = s); + return services; } } } diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs index 44a41e1e5c2..73b11544d23 100644 --- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs @@ -15,10 +15,8 @@ // using System; -using System.Diagnostics; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; -using OpenTelemetry; using OpenTelemetry.Extensions.Hosting.Implementation; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; @@ -27,7 +25,8 @@ namespace Microsoft.Extensions.DependencyInjection { /// - /// Extension methods for setting up OpenTelemetry services in an . + /// Extension methods for setting up OpenTelemetry services in an . /// public static class OpenTelemetryServicesExtensions { @@ -37,24 +36,29 @@ public static class OpenTelemetryServicesExtensions /// cref="IServiceCollection" />. /// /// - /// Note: This is safe to be called multiple times and by library authors. - /// Only a single will be created for a given - /// . + /// Note: This is safe to be called multiple times and by library + /// authors. Only a single will be created + /// for a given . /// /// . - /// Supplied for chaining calls. + /// Supplied for chaining + /// calls. public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection services) - => AddOpenTelemetryTracing(services, (b) => { }); + => AddOpenTelemetryTracing(services, b => { }); /// /// Configure OpenTelemetry and register a /// to automatically start tracing services in the supplied . /// - /// + /// /// . - /// Callback action to configure the . - /// Supplied for chaining calls. + /// Callback action to configure the . + /// Supplied for chaining + /// calls. public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection services, Action configure) { Guard.ThrowIfNull(services); @@ -67,54 +71,41 @@ public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection } /// - /// Adds OpenTelemetry MeterProvider to the specified . + /// Configure OpenTelemetry and register a + /// to automatically start metric services in the supplied . /// - /// The to add services to. - /// The so that additional calls can be chained. + /// + /// Note: This is safe to be called multiple times and by library + /// authors. Only a single will be created + /// for a given . + /// + /// . + /// Supplied for chaining + /// calls. public static IServiceCollection AddOpenTelemetryMetrics(this IServiceCollection services) - { - return services.AddOpenTelemetryMetrics(builder => { }); - } + => AddOpenTelemetryMetrics(services, b => { }); /// - /// Adds OpenTelemetry MeterProvider to the specified . + /// Configure OpenTelemetry and register a + /// to automatically start metric services in the supplied . /// - /// The to add services to. - /// Callback action to configure the . - /// The so that additional calls can be chained. + /// + /// . + /// Callback action to configure the . + /// Supplied for chaining + /// calls. public static IServiceCollection AddOpenTelemetryMetrics(this IServiceCollection services, Action configure) { - Guard.ThrowIfNull(configure); - - var builder = new MeterProviderBuilderHosting(services); - configure(builder); - return services.AddOpenTelemetryMetrics(sp => builder.Build(sp)); - } - - /// - /// Adds OpenTelemetry MeterProvider to the specified . - /// - /// The to add services to. - /// A delegate that provides the tracer provider to be registered. - /// The so that additional calls can be chained. - private static IServiceCollection AddOpenTelemetryMetrics(this IServiceCollection services, Func createMeterProvider) - { - Debug.Assert(services != null, $"{nameof(services)} must not be null"); - Debug.Assert(createMeterProvider != null, $"{nameof(createMeterProvider)} must not be null"); + Guard.ThrowIfNull(services); - // Accessing Sdk class is just to trigger its static ctor, - // which sets default Propagators and default Activity Id format - _ = Sdk.SuppressInstrumentation; + services.ConfigureOpenTelemetryMetrics(configure); - try - { - services.TryAddEnumerable(ServiceDescriptor.Singleton()); - return services.AddSingleton(s => createMeterProvider(s)); - } - catch (Exception ex) - { - HostingExtensionsEventSource.Log.FailedInitialize(ex); - } + services.TryAddEnumerable(ServiceDescriptor.Singleton()); return services; } diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 8090c32012a..6e9eadce47b 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -15,6 +15,10 @@ the `OpenTelemetryLoggerProvider` dependency injection scenarios ([#3596](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3596)) +* Added support for dependency injection scenarios when configuring + `MeterProvider` + ([#XXXX](https://github.com/open-telemetry/opentelemetry-dotnet/pull/XXXX)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs new file mode 100644 index 00000000000..1ddd03dd310 --- /dev/null +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs @@ -0,0 +1,301 @@ +// +// 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 System.Diagnostics.Metrics; +using System.Text.RegularExpressions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using OpenTelemetry.Internal; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Metrics +{ + /// + /// Contains methods for building instances. + /// + public abstract class MeterProviderBuilderBase : MeterProviderBuilder, IDeferredMeterProviderBuilder + { + internal readonly MeterProviderBuilderState? State; + + private readonly bool ownsServices; + private IServiceCollection? services; + + // This ctor is for a builder created from MeterProviderBuilderState which + // happens after the service provider has been created. + internal MeterProviderBuilderBase(MeterProviderBuilderState state) + { + Debug.Assert(state != null, "state was null"); + + this.State = state; + } + + // This ctor is for AddOpenTelemetryTracing scenario where the builder + // is bound to an external service collection. + internal MeterProviderBuilderBase(IServiceCollection services) + { + Guard.ThrowIfNull(services); + + services.AddOptions(); + services.TryAddSingleton(sp => new MeterProviderSdk(sp, ownsServiceProvider: false)); + + this.services = services; + this.ownsServices = false; + } + + // This ctor is for Sdk.CreateMeterProviderBuilder where the builder + // owns its services and service provider. + protected MeterProviderBuilderBase() + { + var services = new ServiceCollection(); + + services.AddOptions(); + + this.services = services; + this.ownsServices = true; + } + + /// + public override MeterProviderBuilder AddInstrumentation(Func instrumentationFactory) + { + Guard.ThrowIfNull(instrumentationFactory); + + return this.AddInstrumentation((sp) => instrumentationFactory()); + } + + /// + public override MeterProviderBuilder AddMeter(params string[] names) + { + Guard.ThrowIfNull(names); + + return this.ConfigureState((sp, state) => state.AddMeter(names)); + } + + /// + MeterProviderBuilder IDeferredMeterProviderBuilder.Configure( + Action configure) + { + Guard.ThrowIfNull(configure); + + if (this.State != null) + { + configure(this.State.ServiceProvider, this); + } + else + { + this.ConfigureServices(services + => MeterProviderBuilderServiceCollectionHelper.RegisterConfigureBuilderCallback(services, configure)); + } + + return this; + } + + internal MeterProviderBuilder AddInstrumentation() + where T : class + { + this.TryAddSingleton(); + this.AddInstrumentation((sp) => sp.GetRequiredService()); + + return this; + } + + internal MeterProviderBuilder AddReader() + where T : MetricReader + { + this.TryAddSingleton(); + this.ConfigureState((sp, state) => state.AddReader(sp.GetRequiredService())); + + return this; + } + + internal MeterProviderBuilder AddReader(MetricReader reader) + { + Guard.ThrowIfNull(reader); + + return this.ConfigureState((sp, state) => state.AddReader(reader)); + } + + internal MeterProviderBuilder AddView(string instrumentName, string name) + { + if (!MeterProviderBuilderSdk.IsValidInstrumentName(name)) + { + throw new ArgumentException($"Custom view name {name} is invalid.", nameof(name)); + } + + if (instrumentName.IndexOf('*') != -1) + { + throw new ArgumentException( + $"Instrument selection criteria is invalid. Instrument name '{instrumentName}' " + + $"contains a wildcard character. This is not allowed when using a view to " + + $"rename a metric stream as it would lead to conflicting metric stream names.", + nameof(instrumentName)); + } + + return this.AddView( + instrumentName, + new MetricStreamConfiguration + { + Name = name, + }); + } + + internal MeterProviderBuilder AddView(string instrumentName, MetricStreamConfiguration metricStreamConfiguration) + { + Guard.ThrowIfNullOrWhitespace(instrumentName); + Guard.ThrowIfNull(metricStreamConfiguration); + + if (metricStreamConfiguration.Name != null && instrumentName.IndexOf('*') != -1) + { + throw new ArgumentException( + $"Instrument selection criteria is invalid. Instrument name '{instrumentName}' " + + $"contains a wildcard character. This is not allowed when using a view to " + + $"rename a metric stream as it would lead to conflicting metric stream names.", + nameof(instrumentName)); + } + + if (instrumentName.IndexOf('*') != -1) + { + var pattern = '^' + Regex.Escape(instrumentName).Replace("\\*", ".*"); + var regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); + return this.AddView(instrument => regex.IsMatch(instrument.Name) ? metricStreamConfiguration : null); + } + else + { + return this.AddView(instrument => instrument.Name.Equals(instrumentName, StringComparison.OrdinalIgnoreCase) ? metricStreamConfiguration : null); + } + } + + internal MeterProviderBuilder AddView(Func viewConfig) + { + Guard.ThrowIfNull(viewConfig); + + this.ConfigureState((sp, state) => state.AddView(viewConfig)); + + return this; + } + + internal MeterProviderBuilder ConfigureResource(Action configure) + { + Guard.ThrowIfNull(configure); + + return this.ConfigureState((sp, state) => state.ConfigureResource(configure)); + } + + internal MeterProviderBuilder ConfigureServices(Action configure) + { + Guard.ThrowIfNull(configure); + + var services = this.services; + + if (services == null) + { + throw new NotSupportedException("Services cannot be configured after ServiceProvider has been created."); + } + + configure(services); + + return this; + } + + internal MeterProvider InvokeBuild() + => this.Build(); + + internal MeterProviderBuilder SetMaxMetricStreams(int maxMetricStreams) + { + Guard.ThrowIfOutOfRange(maxMetricStreams, min: 1); + + return this.ConfigureState((sp, state) => state.MaxMetricStreams = maxMetricStreams); + } + + internal MeterProviderBuilder SetMaxMetricPointsPerMetricStream(int maxMetricPointsPerMetricStream) + { + Guard.ThrowIfOutOfRange(maxMetricPointsPerMetricStream, min: 1); + + return this.ConfigureState((sp, state) => state.MaxMetricPointsPerMetricStream = maxMetricPointsPerMetricStream); + } + + internal MeterProviderBuilder SetResourceBuilder(ResourceBuilder resourceBuilder) + { + Guard.ThrowIfNull(resourceBuilder); + + return this.ConfigureState((sp, state) => state.SetResourceBuilder(resourceBuilder)); + } + + /// + /// Run the configured actions to initialize the . + /// + /// . + protected MeterProvider Build() + { + if (!this.ownsServices || this.State != null) + { + throw new NotSupportedException("Build cannot be called directly on MeterProviderBuilder tied to external services."); + } + + var services = this.services; + + if (services == null) + { + throw new NotSupportedException("MeterProviderBuilder build method cannot be called multiple times."); + } + + this.services = null; + + var serviceProvider = services.BuildServiceProvider(); + + return new MeterProviderSdk(serviceProvider, ownsServiceProvider: true); + } + + private MeterProviderBuilder AddInstrumentation(Func instrumentationFactory) + where T : class + { + this.ConfigureState((sp, state) + => state.AddInstrumentation( + typeof(T).Name, + "semver:" + typeof(T).Assembly.GetName().Version, + instrumentationFactory(sp))); + + return this; + } + + private MeterProviderBuilder ConfigureState(Action configure) + { + Debug.Assert(configure != null, "configure was null"); + + if (this.State != null) + { + configure!(this.State.ServiceProvider, this.State); + } + else + { + this.ConfigureServices(services => MeterProviderBuilderServiceCollectionHelper.RegisterConfigureStateCallback(services, configure!)); + } + + return this; + } + + private void TryAddSingleton() + where T : class + { + var services = this.services; + + services?.TryAddSingleton(); + } + } +} diff --git a/src/OpenTelemetry/Metrics/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs similarity index 62% rename from src/OpenTelemetry/Metrics/MeterProviderBuilderExtensions.cs rename to src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs index cd47974872c..00a9ca13358 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs @@ -14,10 +14,13 @@ // limitations under the License. // +#nullable enable + using System; using System.Diagnostics.Metrics; -using OpenTelemetry.Internal; +using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Resources; +using OpenTelemetry.Trace; namespace OpenTelemetry.Metrics { @@ -26,17 +29,59 @@ namespace OpenTelemetry.Metrics /// public static class MeterProviderBuilderExtensions { + /// + /// Adds instrumentation to the provider. + /// + /// + /// Note: The type specified by will be + /// registered as a singleton service into application services. + /// + /// Instrumentation type. + /// . + /// The supplied for chaining. + public static MeterProviderBuilder AddInstrumentation(this MeterProviderBuilder meterProviderBuilder) + where T : class + { + if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) + { + meterProviderBuilderBase.AddInstrumentation(); + } + + return meterProviderBuilder; + } + /// /// Adds a reader to the provider. /// /// . /// . - /// . + /// The supplied for chaining. public static MeterProviderBuilder AddReader(this MeterProviderBuilder meterProviderBuilder, MetricReader reader) { if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - return meterProviderBuilderBase.AddReader(reader); + meterProviderBuilderBase.AddReader(reader); + } + + return meterProviderBuilder; + } + + /// + /// Adds a reader to the provider. + /// + /// + /// Note: The type specified by will be + /// registered as a singleton service into application services. + /// + /// Reader type. + /// . + /// The supplied for chaining. + public static MeterProviderBuilder AddReader(this MeterProviderBuilder meterProviderBuilder) + where T : MetricReader + { + if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) + { + meterProviderBuilderBase.AddReader(); } return meterProviderBuilder; @@ -46,30 +91,16 @@ public static MeterProviderBuilder AddReader(this MeterProviderBuilder meterProv /// Add metric view, which can be used to customize the Metrics outputted /// from the SDK. The views are applied in the order they are added. /// + /// See View specification here : https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view. /// . /// Name of the instrument, to be used as part of Instrument selection criteria. /// Name of the view. This will be used as name of resulting metrics stream. - /// . - /// See View specification here : https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view. + /// The supplied for chaining. public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) { - if (!MeterProviderBuilderSdk.IsValidInstrumentName(name)) - { - throw new ArgumentException($"Custom view name {name} is invalid.", nameof(name)); - } - - if (instrumentName.IndexOf('*') != -1) - { - throw new ArgumentException( - $"Instrument selection criteria is invalid. Instrument name '{instrumentName}' " + - $"contains a wildcard character. This is not allowed when using a view to " + - $"rename a metric stream as it would lead to conflicting metric stream names.", - nameof(instrumentName)); - } - if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - return meterProviderBuilderBase.AddView(instrumentName, name); + meterProviderBuilderBase.AddView(instrumentName, name); } return meterProviderBuilder; @@ -79,27 +110,16 @@ public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProvid /// Add metric view, which can be used to customize the Metrics outputted /// from the SDK. The views are applied in the order they are added. /// + /// See View specification here : https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view. /// . /// Name of the instrument, to be used as part of Instrument selection criteria. /// Aggregation configuration used to produce metrics stream. - /// . - /// See View specification here : https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view. + /// The supplied for chaining. public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProviderBuilder, string instrumentName, MetricStreamConfiguration metricStreamConfiguration) { - Guard.ThrowIfNull(metricStreamConfiguration); - - if (metricStreamConfiguration.Name != null && instrumentName.IndexOf('*') != -1) - { - throw new ArgumentException( - $"Instrument selection criteria is invalid. Instrument name '{instrumentName}' " + - $"contains a wildcard character. This is not allowed when using a view to " + - $"rename a metric stream as it would lead to conflicting metric stream names.", - nameof(instrumentName)); - } - if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - return meterProviderBuilderBase.AddView(instrumentName, metricStreamConfiguration); + meterProviderBuilderBase.AddView(instrumentName, metricStreamConfiguration); } return meterProviderBuilder; @@ -109,9 +129,6 @@ public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProvid /// Add metric view, which can be used to customize the Metrics outputted /// from the SDK. The views are applied in the order they are added. /// - /// . - /// Function to configure aggregation based on the instrument. - /// . /// /// /// Note: An invalid @@ -121,13 +138,14 @@ public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProvid /// See View specification here : https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view. /// /// - public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProviderBuilder, Func viewConfig) + /// . + /// Function to configure aggregation based on the instrument. + /// The supplied for chaining. + public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProviderBuilder, Func viewConfig) { - Guard.ThrowIfNull(viewConfig); - if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - return meterProviderBuilderBase.AddView(viewConfig); + meterProviderBuilderBase.AddView(viewConfig); } return meterProviderBuilder; @@ -140,13 +158,13 @@ public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProvid /// When Views are configured, a single instrument can result in multiple metric streams, /// so this control the number of streams. /// - /// MeterProviderBuilder instance. - /// Maximum number of metric streams allowed. - /// Returns for chaining. /// /// If an instrument is created, but disposed later, this will still be contributing to the limit. /// This may change in the future. /// + /// . + /// Maximum number of metric streams allowed. + /// The supplied for chaining. public static MeterProviderBuilder SetMaxMetricStreams(this MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) { if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) @@ -162,14 +180,14 @@ public static MeterProviderBuilder SetMaxMetricStreams(this MeterProviderBuilder /// This limits the number of unique combinations of key/value pairs used /// for reporting measurements. /// - /// MeterProviderBuilder instance. - /// Maximum maximum number of metric points allowed per metric stream. - /// Returns for chaining. /// /// If a particular key/value pair combination is used at least once, /// it will contribute to the limit for the life of the process. /// This may change in the future. See: https://github.com/open-telemetry/opentelemetry-dotnet/issues/2360. /// + /// . + /// Maximum maximum number of metric points allowed per metric stream. + /// The supplied for chaining. public static MeterProviderBuilder SetMaxMetricPointsPerMetricStream(this MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) { if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) @@ -186,14 +204,14 @@ public static MeterProviderBuilder SetMaxMetricPointsPerMetricStream(this MeterP /// You should usually use instead /// (call if desired). /// - /// MeterProviderBuilder instance. + /// . /// from which Resource will be built. - /// Returns for chaining. + /// The supplied for chaining. public static MeterProviderBuilder SetResourceBuilder(this MeterProviderBuilder meterProviderBuilder, ResourceBuilder resourceBuilder) { if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - meterProviderBuilderBase.ResourceBuilder = resourceBuilder; + meterProviderBuilderBase.SetResourceBuilder(resourceBuilder); } return meterProviderBuilder; @@ -203,37 +221,72 @@ public static MeterProviderBuilder SetResourceBuilder(this MeterProviderBuilder /// Modify the from which the Resource associated with /// this provider is built from in-place. /// - /// MeterProviderBuilder instance. + /// . /// An action which modifies the provided in-place. - /// Returns for chaining. + /// The supplied for chaining. public static MeterProviderBuilder ConfigureResource(this MeterProviderBuilder meterProviderBuilder, Action configure) { - Guard.ThrowIfNull(meterProviderBuilder, nameof(meterProviderBuilder)); - Guard.ThrowIfNull(configure, nameof(configure)); + if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) + { + meterProviderBuilderBase.ConfigureResource(configure); + } + return meterProviderBuilder; + } + + /// + /// Register a callback action to configure the where metric services are configured. + /// + /// + /// Note: Metric services are only available during the application + /// configuration phase. + /// + /// . + /// Configuration callback. + /// The supplied for chaining. + public static MeterProviderBuilder ConfigureServices( + this MeterProviderBuilder meterProviderBuilder, + Action configure) + { if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - configure(meterProviderBuilderBase.ResourceBuilder); + meterProviderBuilderBase.ConfigureServices(configure); } return meterProviderBuilder; } /// - /// Run the given actions to initialize the . + /// Register a callback action to configure the once the application is available. /// /// . - /// . - public static MeterProvider Build(this MeterProviderBuilder meterProviderBuilder) + /// Configuration callback. + /// The supplied for chaining. + public static MeterProviderBuilder ConfigureBuilder( + this MeterProviderBuilder meterProviderBuilder, + Action configure) { - if (meterProviderBuilder is IDeferredMeterProviderBuilder) + if (meterProviderBuilder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) { - throw new NotSupportedException("DeferredMeterProviderBuilder requires a ServiceProvider to build."); + deferredMeterProviderBuilder.Configure(configure); } - if (meterProviderBuilder is MeterProviderBuilderSdk meterProviderBuilderSdk) + return meterProviderBuilder; + } + + /// + /// Run the given actions to initialize the . + /// + /// . + /// . + public static MeterProvider? Build(this MeterProviderBuilder meterProviderBuilder) + { + if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - return meterProviderBuilderSdk.BuildSdk(); + return meterProviderBuilderBase.InvokeBuild(); } return null; diff --git a/src/OpenTelemetry/Metrics/MeterProviderBuilderSdk.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs similarity index 80% rename from src/OpenTelemetry/Metrics/MeterProviderBuilderSdk.cs rename to src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs index 8646e37156c..641b4957242 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderBuilderSdk.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs @@ -14,22 +14,39 @@ // limitations under the License. // +#nullable enable + using System.Text.RegularExpressions; +using Microsoft.Extensions.DependencyInjection; namespace OpenTelemetry.Metrics { - internal class MeterProviderBuilderSdk : MeterProviderBuilderBase + internal sealed class MeterProviderBuilderSdk : MeterProviderBuilderBase { private static readonly Regex InstrumentNameRegex = new( @"^[a-zA-Z][-.\w]{0,62}$", RegexOptions.IgnoreCase | RegexOptions.Compiled); + public MeterProviderBuilderSdk() + { + } + + public MeterProviderBuilderSdk(IServiceCollection services) + : base(services) + { + } + + public MeterProviderBuilderSdk(MeterProviderBuilderState state) + : base(state) + { + } + /// /// Returns whether the given instrument name is valid according to the specification. /// /// See specification: . /// The instrument name. /// Boolean indicating if the instrument is valid. - internal static bool IsValidInstrumentName(string instrumentName) + public static bool IsValidInstrumentName(string instrumentName) { if (string.IsNullOrWhiteSpace(instrumentName)) { @@ -45,7 +62,7 @@ internal static bool IsValidInstrumentName(string instrumentName) /// See specification: . /// The view name. /// Boolean indicating if the instrument is valid. - internal static bool IsValidViewName(string customViewName) + public static bool IsValidViewName(string customViewName) { // Only validate the view name in case it's not null. In case it's null, the view name will be the instrument name as per the spec. if (customViewName == null) @@ -55,7 +72,5 @@ internal static bool IsValidViewName(string customViewName) return InstrumentNameRegex.IsMatch(customViewName); } - - internal MeterProvider BuildSdk() => this.Build(); } } diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionExtensions.cs new file mode 100644 index 00000000000..8e34bd4b5a3 --- /dev/null +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionExtensions.cs @@ -0,0 +1,77 @@ +// +// 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 OpenTelemetry; +using OpenTelemetry.Internal; +using OpenTelemetry.Metrics; + +namespace Microsoft.Extensions.DependencyInjection; + +/// +/// Extension methods for setting up OpenTelemetry Metrics services in an . +/// +public static class MeterProviderBuilderServiceCollectionExtensions +{ + /// + /// Configures OpenTelemetry Metrics services in the supplied . + /// + /// + /// Notes: + /// + /// A will not be created automatically + /// using this method. Either use the + /// IServiceCollection.AddOpenTelemetryMetrics extension in the + /// OpenTelemetry.Extensions.Hosting package or access the through the application to begin collecting traces. + /// This is safe to be called multiple times and by library authors. + /// Only a single will be created for a given + /// . + /// + /// + /// The to add services to. + /// The so that additional calls can be chained. + public static IServiceCollection ConfigureOpenTelemetryMetrics(this IServiceCollection services) + => ConfigureOpenTelemetryMetrics(services, (b) => { }); + + /// + /// Configures OpenTelemetry Metrics services in the supplied . + /// + /// + /// The to add services to. + /// Callback action to configure the . + /// The so that additional calls can be chained. + public static IServiceCollection ConfigureOpenTelemetryMetrics(this IServiceCollection services, Action configure) + { + Guard.ThrowIfNull(services); + Guard.ThrowIfNull(configure); + + // Accessing Sdk class is just to trigger its static ctor, + // which sets default Propagators and default Activity Id format + _ = Sdk.SuppressInstrumentation; + + // Note: We need to create a builder even if there is no configure + // because the builder will register services + var builder = new MeterProviderBuilderSdk(services); + + configure(builder); + + return services; + } +} diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs new file mode 100644 index 00000000000..e53f412828d --- /dev/null +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs @@ -0,0 +1,81 @@ +// +// 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.DependencyInjection; + +namespace OpenTelemetry.Metrics; + +internal static class MeterProviderBuilderServiceCollectionHelper +{ + internal static IServiceCollection RegisterConfigureBuilderCallback( + IServiceCollection services, + Action configure) + { + Debug.Assert(configure != null, "configure was null"); + + return RegisterConfigureStateCallback( + services, + (sp, state) => configure!(sp, state.Builder)); + } + + internal static IServiceCollection RegisterConfigureStateCallback( + IServiceCollection services, + Action configure) + { + Debug.Assert(services != null, "services was null"); + Debug.Assert(configure != null, "configure was null"); + + return services.AddSingleton(new ConfigureMeterProviderBuilderStateCallbackRegistration(configure!)); + } + + internal static void InvokeRegisteredConfigureStateCallbacks( + IServiceProvider serviceProvider, + MeterProviderBuilderState state) + { + Debug.Assert(serviceProvider != null, "serviceProvider was null"); + Debug.Assert(state != null, "state was null"); + + var callbackRegistrations = serviceProvider.GetServices(); + + foreach (var callbackRegistration in callbackRegistrations) + { + callbackRegistration.Configure(serviceProvider!, state!); + } + } + + private sealed class ConfigureMeterProviderBuilderStateCallbackRegistration + { + private readonly Action configure; + + public ConfigureMeterProviderBuilderStateCallbackRegistration( + Action configure) + { + this.configure = configure; + } + + public void Configure(IServiceProvider serviceProvider, MeterProviderBuilderState state) + { + Debug.Assert(serviceProvider != null, "serviceProvider was null"); + Debug.Assert(state != null, "state was null"); + + this.configure(serviceProvider!, state!); + } + } +} diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs new file mode 100644 index 00000000000..ffb6db0a4de --- /dev/null +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs @@ -0,0 +1,127 @@ +// +// 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.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.Metrics; +using OpenTelemetry.Internal; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Metrics +{ + /// + /// Stores state used to build a . + /// + internal sealed class MeterProviderBuilderState + { + internal const int MaxMetricsDefault = 1000; + internal const int MaxMetricPointsPerMetricDefault = 2000; + internal readonly IServiceProvider ServiceProvider; + internal readonly List Instrumentation = new(); + internal readonly List Readers = new(); + internal readonly List MeterSources = new(); + internal readonly List> ViewConfigs = new(); + internal ResourceBuilder? ResourceBuilder; + internal int MaxMetricStreams = MaxMetricsDefault; + internal int MaxMetricPointsPerMetricStream = MaxMetricPointsPerMetricDefault; + + private MeterProviderBuilderSdk? builder; + + public MeterProviderBuilderState(IServiceProvider serviceProvider) + { + Debug.Assert(serviceProvider != null, "serviceProvider was null"); + + this.ServiceProvider = serviceProvider!; + } + + public MeterProviderBuilderSdk Builder => this.builder ??= new MeterProviderBuilderSdk(this); + + public void AddInstrumentation( + string instrumentationName, + string instrumentationVersion, + object instrumentation) + { + Debug.Assert(!string.IsNullOrWhiteSpace(instrumentationName), "instrumentationName was null or whitespace"); + Debug.Assert(!string.IsNullOrWhiteSpace(instrumentationVersion), "instrumentationVersion was null or whitespace"); + Debug.Assert(instrumentation != null, "instrumentation was null"); + + this.Instrumentation.Add( + new InstrumentationRegistration( + instrumentationName, + instrumentationVersion, + instrumentation!)); + } + + public void AddMeter(params string[] names) + { + Debug.Assert(names != null, "names was null"); + + foreach (var name in names!) + { + Guard.ThrowIfNullOrWhitespace(name); + + this.MeterSources.Add(name); + } + } + + public void AddReader(MetricReader reader) + { + Debug.Assert(reader != null, "reader was null"); + + this.Readers.Add(reader!); + } + + public void AddView(Func viewConfig) + { + Debug.Assert(viewConfig != null, "viewConfig was null"); + + this.ViewConfigs.Add(viewConfig); + } + + public void ConfigureResource(Action configure) + { + Debug.Assert(configure != null, "configure was null"); + + var resourceBuilder = this.ResourceBuilder ??= ResourceBuilder.CreateDefault(); + + configure!(resourceBuilder); + } + + public void SetResourceBuilder(ResourceBuilder resourceBuilder) + { + Debug.Assert(resourceBuilder != null, "resourceBuilder was null"); + + this.ResourceBuilder = resourceBuilder; + } + + internal readonly struct InstrumentationRegistration + { + public readonly string Name; + public readonly string Version; + public readonly object Instance; + + internal InstrumentationRegistration(string name, string version, object instance) + { + this.Name = name; + this.Version = version; + this.Instance = instance; + } + } + } +} diff --git a/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs b/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs deleted file mode 100644 index aa5a5ace8e5..00000000000 --- a/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs +++ /dev/null @@ -1,169 +0,0 @@ -// -// 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; -using System.Diagnostics; -using System.Diagnostics.Metrics; -using System.Text.RegularExpressions; -using OpenTelemetry.Internal; -using OpenTelemetry.Resources; - -namespace OpenTelemetry.Metrics -{ - /// - /// Build MeterProvider with Instrumentations, Meters, - /// Resource, Readers, and Views. - /// - public abstract class MeterProviderBuilderBase : MeterProviderBuilder - { - internal const int MaxMetricsDefault = 1000; - internal const int MaxMetricPointsPerMetricDefault = 2000; - private readonly List instrumentationFactories = new(); - private readonly List meterSources = new(); - private readonly List> viewConfigs = new(); - private ResourceBuilder resourceBuilder = ResourceBuilder.CreateDefault(); - private int maxMetricStreams = MaxMetricsDefault; - private int maxMetricPointsPerMetricStream = MaxMetricPointsPerMetricDefault; - - protected MeterProviderBuilderBase() - { - } - - internal List MetricReaders { get; } = new List(); - - internal ResourceBuilder ResourceBuilder - { - get => this.resourceBuilder; - set - { - Debug.Assert(value != null, $"{nameof(this.ResourceBuilder)} must not be set to null"); - this.resourceBuilder = value; - } - } - - /// - public override MeterProviderBuilder AddInstrumentation(Func instrumentationFactory) - { - Guard.ThrowIfNull(instrumentationFactory); - - this.instrumentationFactories.Add( - new InstrumentationFactory( - typeof(TInstrumentation).Name, - "semver:" + typeof(TInstrumentation).Assembly.GetName().Version, - instrumentationFactory)); - - return this; - } - - /// - public override MeterProviderBuilder AddMeter(params string[] names) - { - Guard.ThrowIfNull(names); - - foreach (var name in names) - { - Guard.ThrowIfNullOrWhitespace(name); - - this.meterSources.Add(name); - } - - return this; - } - - internal MeterProviderBuilder AddReader(MetricReader reader) - { - this.MetricReaders.Add(reader); - return this; - } - - internal MeterProviderBuilder AddView(string instrumentName, string name) - { - return this.AddView( - instrumentName, - new MetricStreamConfiguration - { - Name = name, - }); - } - - internal MeterProviderBuilder AddView(string instrumentName, MetricStreamConfiguration metricStreamConfiguration) - { - if (instrumentName.IndexOf('*') != -1) - { - var pattern = '^' + Regex.Escape(instrumentName).Replace("\\*", ".*"); - var regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); - return this.AddView(instrument => regex.IsMatch(instrument.Name) ? metricStreamConfiguration : null); - } - else - { - return this.AddView(instrument => instrument.Name.Equals(instrumentName, StringComparison.OrdinalIgnoreCase) ? metricStreamConfiguration : null); - } - } - - internal MeterProviderBuilder AddView(Func viewConfig) - { - this.viewConfigs.Add(viewConfig); - return this; - } - - internal MeterProviderBuilder SetMaxMetricStreams(int maxMetricStreams) - { - Guard.ThrowIfOutOfRange(maxMetricStreams, min: 1); - - this.maxMetricStreams = maxMetricStreams; - return this; - } - - internal MeterProviderBuilder SetMaxMetricPointsPerMetricStream(int maxMetricPointsPerMetricStream) - { - Guard.ThrowIfOutOfRange(maxMetricPointsPerMetricStream, min: 1); - - this.maxMetricPointsPerMetricStream = maxMetricPointsPerMetricStream; - return this; - } - - /// - /// Run the configured actions to initialize the . - /// - /// . - protected MeterProvider Build() - { - return new MeterProviderSdk( - this.resourceBuilder.Build(), - this.meterSources, - this.instrumentationFactories, - this.viewConfigs, - this.maxMetricStreams, - this.maxMetricPointsPerMetricStream, - this.MetricReaders.ToArray()); - } - - internal readonly struct InstrumentationFactory - { - public readonly string Name; - public readonly string Version; - public readonly Func Factory; - - internal InstrumentationFactory(string name, string version, Func factory) - { - this.Name = name; - this.Version = version; - this.Factory = factory; - } - } - } -} diff --git a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs index 437685f32a4..a108d64a396 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; @@ -27,39 +29,48 @@ namespace OpenTelemetry.Metrics { internal sealed class MeterProviderSdk : MeterProvider { + internal readonly IDisposable? OwnedServiceProvider; internal int ShutdownCount; + private readonly List instrumentations = new(); - private readonly List> viewConfigs; + private readonly List> viewConfigs; private readonly object collectLock = new(); private readonly MeterListener listener; - private readonly MetricReader reader; - private readonly CompositeMetricReader compositeMetricReader; + private readonly MetricReader? reader; + private readonly CompositeMetricReader? compositeMetricReader; private bool disposed; internal MeterProviderSdk( - Resource resource, - IEnumerable meterSources, - List instrumentationFactories, - List> viewConfigs, - int maxMetricStreams, - int maxMetricPointsPerMetricStream, - IEnumerable readers) + IServiceProvider serviceProvider, + bool ownsServiceProvider) { + if (ownsServiceProvider) + { + this.OwnedServiceProvider = serviceProvider as IDisposable; + Debug.Assert(this.OwnedServiceProvider != null, "serviceProvider was not IDisposable"); + } + OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent("Building MeterProvider."); + var state = new MeterProviderBuilderState(serviceProvider); + + MeterProviderBuilderServiceCollectionHelper.InvokeRegisteredConfigureStateCallbacks( + serviceProvider, + state); + StringBuilder exportersAdded = new StringBuilder(); StringBuilder instrumentationFactoriesAdded = new StringBuilder(); - this.Resource = resource; - this.viewConfigs = viewConfigs; + this.Resource = (state.ResourceBuilder ?? ResourceBuilder.CreateDefault()).Build(); + this.viewConfigs = state.ViewConfigs; - foreach (var reader in readers) + foreach (var reader in state.Readers) { Guard.ThrowIfNull(reader); reader.SetParentProvider(this); - reader.SetMaxMetricStreams(maxMetricStreams); - reader.SetMaxMetricPointsPerMetricStream(maxMetricPointsPerMetricStream); + reader.SetMaxMetricStreams(state.MaxMetricStreams); + reader.SetMaxMetricPointsPerMetricStream(state.MaxMetricPointsPerMetricStream); if (this.reader == null) { @@ -98,12 +109,12 @@ internal MeterProviderSdk( this.compositeMetricReader = this.reader as CompositeMetricReader; - if (instrumentationFactories.Any()) + if (state.Instrumentation.Any()) { - foreach (var instrumentationFactory in instrumentationFactories) + foreach (var instrumentation in state.Instrumentation) { - this.instrumentations.Add(instrumentationFactory.Factory()); - instrumentationFactoriesAdded.Append(instrumentationFactory.Name); + this.instrumentations.Add(instrumentation.Instance); + instrumentationFactoriesAdded.Append(instrumentation.Name); instrumentationFactoriesAdded.Append(';'); } } @@ -116,18 +127,18 @@ internal MeterProviderSdk( // Setup Listener Func shouldListenTo = instrument => false; - if (meterSources.Any(s => WildcardHelper.ContainsWildcard(s))) + if (state.MeterSources.Any(s => WildcardHelper.ContainsWildcard(s))) { - var regex = WildcardHelper.GetWildcardRegex(meterSources); + var regex = WildcardHelper.GetWildcardRegex(state.MeterSources); shouldListenTo = instrument => regex.IsMatch(instrument.Meter.Name); } - else if (meterSources.Any()) + else if (state.MeterSources.Any()) { - var meterSourcesToSubscribe = new HashSet(meterSources, StringComparer.OrdinalIgnoreCase); + var meterSourcesToSubscribe = new HashSet(state.MeterSources, StringComparer.OrdinalIgnoreCase); shouldListenTo = instrument => meterSourcesToSubscribe.Contains(instrument.Meter.Name); } - OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Listening to following meters = \"{string.Join(";", meterSources)}\"."); + OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Listening to following meters = \"{string.Join(";", state.MeterSources)}\"."); this.listener = new MeterListener(); var viewConfigCount = this.viewConfigs.Count; @@ -154,11 +165,11 @@ internal MeterProviderSdk( // possible size, to avoid any array resize/copy internally. // There may be excess space wasted, but it'll eligible for // GC right after this method. - var metricStreamConfigs = new List(viewConfigCount); + var metricStreamConfigs = new List(viewConfigCount); for (var i = 0; i < viewConfigCount; ++i) { var viewConfig = this.viewConfigs[i]; - MetricStreamConfiguration metricStreamConfig = null; + MetricStreamConfiguration? metricStreamConfig = null; try { @@ -320,7 +331,7 @@ internal MeterProviderSdk( internal List Instrumentations => this.instrumentations; - internal MetricReader Reader => this.reader; + internal MetricReader? Reader => this.reader; internal void MeasurementsCompletedSingleStream(Instrument instrument, object state) { @@ -334,7 +345,7 @@ internal void MeasurementsCompletedSingleStream(Instrument instrument, object st return; } - this.reader.CompleteSingleStreamMeasurement(metric); + this.reader?.CompleteSingleStreamMeasurement(metric); } else { @@ -360,7 +371,7 @@ internal void MeasurementsCompleted(Instrument instrument, object state) return; } - this.reader.CompleteMeasurement(metrics); + this.reader?.CompleteMeasurement(metrics); } else { @@ -386,7 +397,7 @@ internal void MeasurementRecordedDouble(Instrument instrument, double value, Rea return; } - this.reader.RecordDoubleMeasurement(metrics, value, tagsRos); + this.reader?.RecordDoubleMeasurement(metrics, value, tagsRos); } else { @@ -412,7 +423,7 @@ internal void MeasurementRecordedLong(Instrument instrument, long value, ReadOnl return; } - this.reader.RecordLongMeasurement(metrics, value, tagsRos); + this.reader?.RecordLongMeasurement(metrics, value, tagsRos); } else { @@ -438,7 +449,7 @@ internal void MeasurementRecordedLongSingleStream(Instrument instrument, long va return; } - this.reader.RecordSingleStreamLongMeasurement(metric, value, tagsRos); + this.reader?.RecordSingleStreamLongMeasurement(metric, value, tagsRos); } else { @@ -464,7 +475,7 @@ internal void MeasurementRecordedDoubleSingleStream(Instrument instrument, doubl return; } - this.reader.RecordSingleStreamDoubleMeasurement(metric, value, tagsRos); + this.reader?.RecordSingleStreamDoubleMeasurement(metric, value, tagsRos); } else { @@ -563,7 +574,9 @@ protected override void Dispose(bool disposing) this.reader?.Dispose(); this.compositeMetricReader?.Dispose(); - this.listener.Dispose(); + this.listener?.Dispose(); + + this.OwnedServiceProvider?.Dispose(); } this.disposed = true; diff --git a/src/OpenTelemetry/Metrics/MetricReaderOptions.cs b/src/OpenTelemetry/Metrics/MetricReaderOptions.cs index 1e1cde9d315..0c0101b7cd3 100644 --- a/src/OpenTelemetry/Metrics/MetricReaderOptions.cs +++ b/src/OpenTelemetry/Metrics/MetricReaderOptions.cs @@ -14,6 +14,10 @@ // limitations under the License. // +#nullable enable + +using OpenTelemetry.Internal; + namespace OpenTelemetry.Metrics; /// @@ -21,6 +25,8 @@ namespace OpenTelemetry.Metrics; /// public class MetricReaderOptions { + private PeriodicExportingMetricReaderOptions periodicExportingMetricReaderOptions = new(); + /// /// Gets or sets the . /// @@ -29,5 +35,13 @@ public class MetricReaderOptions /// /// Gets or sets the . /// - public PeriodicExportingMetricReaderOptions PeriodicExportingMetricReaderOptions { get; set; } = new PeriodicExportingMetricReaderOptions(); + public PeriodicExportingMetricReaderOptions PeriodicExportingMetricReaderOptions + { + get => this.periodicExportingMetricReaderOptions; + set + { + Guard.ThrowIfNull(value); + this.periodicExportingMetricReaderOptions = value; + } + } } diff --git a/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs b/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs index 25dc7500087..83d64bd7932 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs @@ -1356,26 +1356,26 @@ int MetricPointCount() // for no tag point! // This may be changed later. counterLong.Add(10); - for (int i = 0; i < MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault + 1; i++) + for (int i = 0; i < MeterProviderBuilderState.MaxMetricPointsPerMetricDefault + 1; i++) { counterLong.Add(10, new KeyValuePair("key", "value" + i)); } meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.Equal(MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault, MetricPointCount()); + Assert.Equal(MeterProviderBuilderState.MaxMetricPointsPerMetricDefault, MetricPointCount()); exportedItems.Clear(); counterLong.Add(10); - for (int i = 0; i < MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault + 1; i++) + for (int i = 0; i < MeterProviderBuilderState.MaxMetricPointsPerMetricDefault + 1; i++) { counterLong.Add(10, new KeyValuePair("key", "value" + i)); } meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.Equal(MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault, MetricPointCount()); + Assert.Equal(MeterProviderBuilderState.MaxMetricPointsPerMetricDefault, MetricPointCount()); counterLong.Add(10); - for (int i = 0; i < MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault + 1; i++) + for (int i = 0; i < MeterProviderBuilderState.MaxMetricPointsPerMetricDefault + 1; i++) { counterLong.Add(10, new KeyValuePair("key", "value" + i)); } @@ -1386,7 +1386,7 @@ int MetricPointCount() counterLong.Add(10, new KeyValuePair("key", "valueC")); exportedItems.Clear(); meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.Equal(MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault, MetricPointCount()); + Assert.Equal(MeterProviderBuilderState.MaxMetricPointsPerMetricDefault, MetricPointCount()); } [Fact] From 11ba0da9ac5a0566ca0eaa6d2bf353cd40267693 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 9 Sep 2022 11:39:44 -0700 Subject: [PATCH 02/11] Nullable annotations. --- .../.publicApi/net462/PublicAPI.Shipped.txt | 26 +++++++++---------- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 +- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 26 +++++++++---------- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 +- .../netstandard2.0/PublicAPI.Shipped.txt | 26 +++++++++---------- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 +- .../netstandard2.1/PublicAPI.Shipped.txt | 26 +++++++++---------- .../netstandard2.1/PublicAPI.Unshipped.txt | 2 +- 8 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt index 663e45228b0..782248e7e3a 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt @@ -21,15 +21,15 @@ OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generi ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.get -> System.Func ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.set -> void -~OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider +OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider! ~OpenTelemetry.Metrics.Metric.Description.get -> string ~OpenTelemetry.Metrics.Metric.MeterName.get -> string ~OpenTelemetry.Metrics.Metric.MeterVersion.get -> string ~OpenTelemetry.Metrics.Metric.Name.get -> string ~OpenTelemetry.Metrics.Metric.Unit.get -> string ~OpenTelemetry.Metrics.MetricPoint.GetHistogramBuckets() -> OpenTelemetry.Metrics.HistogramBuckets -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions! +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.get -> string ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.get -> string @@ -63,8 +63,8 @@ OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.Tra override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void ~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! +override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string![]! names) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool @@ -74,14 +74,14 @@ override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string![ override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! ~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Func viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.MetricReader! reader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration! metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, string! name) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider? +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~static OpenTelemetry.Metrics.MeterProviderExtensions.ForceFlush(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MeterProviderExtensions.Shutdown(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MetricStreamConfiguration.Drop.get -> OpenTelemetry.Metrics.MetricStreamConfiguration diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt index 5d438fc9dc9..d6fc1b34ed1 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt @@ -58,7 +58,7 @@ static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTe static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt index 663e45228b0..782248e7e3a 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -21,15 +21,15 @@ OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generi ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.get -> System.Func ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.set -> void -~OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider +OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider! ~OpenTelemetry.Metrics.Metric.Description.get -> string ~OpenTelemetry.Metrics.Metric.MeterName.get -> string ~OpenTelemetry.Metrics.Metric.MeterVersion.get -> string ~OpenTelemetry.Metrics.Metric.Name.get -> string ~OpenTelemetry.Metrics.Metric.Unit.get -> string ~OpenTelemetry.Metrics.MetricPoint.GetHistogramBuckets() -> OpenTelemetry.Metrics.HistogramBuckets -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions! +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.get -> string ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.get -> string @@ -63,8 +63,8 @@ OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.Tra override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void ~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! +override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string![]! names) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool @@ -74,14 +74,14 @@ override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string![ override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! ~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Func viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.MetricReader! reader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration! metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, string! name) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider? +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~static OpenTelemetry.Metrics.MeterProviderExtensions.ForceFlush(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MeterProviderExtensions.Shutdown(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MetricStreamConfiguration.Drop.get -> OpenTelemetry.Metrics.MetricStreamConfiguration diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt index 5d438fc9dc9..d6fc1b34ed1 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -58,7 +58,7 @@ static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTe static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index 663e45228b0..782248e7e3a 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -21,15 +21,15 @@ OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generi ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.get -> System.Func ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.set -> void -~OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider +OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider! ~OpenTelemetry.Metrics.Metric.Description.get -> string ~OpenTelemetry.Metrics.Metric.MeterName.get -> string ~OpenTelemetry.Metrics.Metric.MeterVersion.get -> string ~OpenTelemetry.Metrics.Metric.Name.get -> string ~OpenTelemetry.Metrics.Metric.Unit.get -> string ~OpenTelemetry.Metrics.MetricPoint.GetHistogramBuckets() -> OpenTelemetry.Metrics.HistogramBuckets -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions! +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.get -> string ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.get -> string @@ -63,8 +63,8 @@ OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.Tra override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void ~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! +override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string![]! names) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool @@ -74,14 +74,14 @@ override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string![ override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! ~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Func viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.MetricReader! reader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration! metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, string! name) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider? +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~static OpenTelemetry.Metrics.MeterProviderExtensions.ForceFlush(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MeterProviderExtensions.Shutdown(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MetricStreamConfiguration.Drop.get -> OpenTelemetry.Metrics.MetricStreamConfiguration diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 7f9f3ed4692..814aa4d9025 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -58,7 +58,7 @@ static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTe static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt index 663e45228b0..782248e7e3a 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt @@ -21,15 +21,15 @@ OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generi ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.get -> System.Func ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.set -> void -~OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider +OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider! ~OpenTelemetry.Metrics.Metric.Description.get -> string ~OpenTelemetry.Metrics.Metric.MeterName.get -> string ~OpenTelemetry.Metrics.Metric.MeterVersion.get -> string ~OpenTelemetry.Metrics.Metric.Name.get -> string ~OpenTelemetry.Metrics.Metric.Unit.get -> string ~OpenTelemetry.Metrics.MetricPoint.GetHistogramBuckets() -> OpenTelemetry.Metrics.HistogramBuckets -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions! +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.get -> string ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.get -> string @@ -63,8 +63,8 @@ OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.Tra override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void ~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! +override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string![]! names) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool @@ -74,14 +74,14 @@ override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string![ override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! ~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Func viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.MetricReader! reader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration! metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, string! name) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider? +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~static OpenTelemetry.Metrics.MeterProviderExtensions.ForceFlush(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MeterProviderExtensions.Shutdown(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MetricStreamConfiguration.Drop.get -> OpenTelemetry.Metrics.MetricStreamConfiguration diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 5d438fc9dc9..d6fc1b34ed1 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -58,7 +58,7 @@ static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTe static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType From 3cf4c6ade699623bb0ed85cd46738f34c84a1b67 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 9 Sep 2022 11:42:32 -0700 Subject: [PATCH 03/11] Warning cleanup. --- src/OpenTelemetry/Metrics/MeterProviderSdk.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs index a108d64a396..1037742584c 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs @@ -333,7 +333,7 @@ internal MeterProviderSdk( internal MetricReader? Reader => this.reader; - internal void MeasurementsCompletedSingleStream(Instrument instrument, object state) + internal void MeasurementsCompletedSingleStream(Instrument instrument, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); @@ -359,7 +359,7 @@ internal void MeasurementsCompletedSingleStream(Instrument instrument, object st } } - internal void MeasurementsCompleted(Instrument instrument, object state) + internal void MeasurementsCompleted(Instrument instrument, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); @@ -385,7 +385,7 @@ internal void MeasurementsCompleted(Instrument instrument, object state) } } - internal void MeasurementRecordedDouble(Instrument instrument, double value, ReadOnlySpan> tagsRos, object state) + internal void MeasurementRecordedDouble(Instrument instrument, double value, ReadOnlySpan> tagsRos, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); @@ -411,7 +411,7 @@ internal void MeasurementRecordedDouble(Instrument instrument, double value, Rea } } - internal void MeasurementRecordedLong(Instrument instrument, long value, ReadOnlySpan> tagsRos, object state) + internal void MeasurementRecordedLong(Instrument instrument, long value, ReadOnlySpan> tagsRos, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); @@ -437,7 +437,7 @@ internal void MeasurementRecordedLong(Instrument instrument, long value, ReadOnl } } - internal void MeasurementRecordedLongSingleStream(Instrument instrument, long value, ReadOnlySpan> tagsRos, object state) + internal void MeasurementRecordedLongSingleStream(Instrument instrument, long value, ReadOnlySpan> tagsRos, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); @@ -463,7 +463,7 @@ internal void MeasurementRecordedLongSingleStream(Instrument instrument, long va } } - internal void MeasurementRecordedDoubleSingleStream(Instrument instrument, double value, ReadOnlySpan> tagsRos, object state) + internal void MeasurementRecordedDoubleSingleStream(Instrument instrument, double value, ReadOnlySpan> tagsRos, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); From 458ef8ab958c052c252f357c10d07d75d25a3049 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 9 Sep 2022 11:43:17 -0700 Subject: [PATCH 04/11] Warning cleanup. --- src/OpenTelemetry/Metrics/MeterProviderSdk.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs index 1037742584c..93458110742 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs @@ -393,7 +393,7 @@ internal void MeasurementRecordedDouble(Instrument instrument, double value, Rea { if (state is not List metrics) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } @@ -403,7 +403,7 @@ internal void MeasurementRecordedDouble(Instrument instrument, double value, Rea { if (state is not List> metricsSuperList) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } @@ -419,7 +419,7 @@ internal void MeasurementRecordedLong(Instrument instrument, long value, ReadOnl { if (state is not List metrics) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } @@ -429,7 +429,7 @@ internal void MeasurementRecordedLong(Instrument instrument, long value, ReadOnl { if (state is not List> metricsSuperList) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } @@ -445,7 +445,7 @@ internal void MeasurementRecordedLongSingleStream(Instrument instrument, long va { if (state is not Metric metric) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } @@ -455,7 +455,7 @@ internal void MeasurementRecordedLongSingleStream(Instrument instrument, long va { if (state is not List metrics) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } @@ -471,7 +471,7 @@ internal void MeasurementRecordedDoubleSingleStream(Instrument instrument, doubl { if (state is not Metric metric) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } @@ -481,7 +481,7 @@ internal void MeasurementRecordedDoubleSingleStream(Instrument instrument, doubl { if (state is not List metrics) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } From a8a9e7d411d35e95e204a9dc8aa982e00cb180ac Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 9 Sep 2022 11:45:16 -0700 Subject: [PATCH 05/11] Public API updates. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 7 +++++++ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 7 +++++++ .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 7 +++++++ .../.publicApi/netstandard2.1/PublicAPI.Unshipped.txt | 7 +++++++ .../Metrics/Builder/MeterProviderBuilderExtensions.cs | 1 - 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt index d6fc1b34ed1..5b0e8c6e33b 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,3 +1,4 @@ +Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions.BatchExportLogRecordProcessorOptions() -> void @@ -31,6 +32,12 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt index d6fc1b34ed1..5b0e8c6e33b 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,3 +1,4 @@ +Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions.BatchExportLogRecordProcessorOptions() -> void @@ -31,6 +32,12 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 814aa4d9025..54869f362f2 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,3 +1,4 @@ +Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions.BatchExportLogRecordProcessorOptions() -> void @@ -31,6 +32,12 @@ OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BasePr OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index d6fc1b34ed1..5b0e8c6e33b 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,3 +1,4 @@ +Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions.BatchExportLogRecordProcessorOptions() -> void @@ -31,6 +32,12 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs index 00a9ca13358..7342a734a07 100644 --- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs @@ -20,7 +20,6 @@ using System.Diagnostics.Metrics; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Resources; -using OpenTelemetry.Trace; namespace OpenTelemetry.Metrics { From 275d43028b9ee4868d3e62bb677967616fa1c681 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 9 Sep 2022 11:45:48 -0700 Subject: [PATCH 06/11] Warning cleanup. --- src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs index ffb6db0a4de..5518ae1e9e3 100644 --- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs @@ -91,7 +91,7 @@ public void AddView(Func viewConfig) { Debug.Assert(viewConfig != null, "viewConfig was null"); - this.ViewConfigs.Add(viewConfig); + this.ViewConfigs.Add(viewConfig!); } public void ConfigureResource(Action configure) From 7adb71b5e7d39e13eb408abd1b466f3e2ea19eb3 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 9 Sep 2022 11:46:51 -0700 Subject: [PATCH 07/11] Public API updates. --- .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 93835864ab7..63141a61d05 100644 --- a/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -5,9 +5,6 @@ static Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions. static Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions.AddOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection static Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions.AddOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection static Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions.AddOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.IServiceProvider serviceProvider) -> OpenTelemetry.Metrics.MeterProvider static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Configure(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.GetServices(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> Microsoft.Extensions.DependencyInjection.IServiceCollection static OpenTelemetry.Trace.TracerProviderBuilderExtensions.Configure(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder From b7f02dd485342f5dbc7289804a019b81a23f8220 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 9 Sep 2022 11:52:31 -0700 Subject: [PATCH 08/11] CHANGELOG updates. --- src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md | 2 +- src/OpenTelemetry/CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index 51c2ee164de..81287c29079 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -8,7 +8,7 @@ * Dependency injection support when configuring `MeterProvider` has been moved into the SDK. - ([#XXXX](https://github.com/open-telemetry/opentelemetry-dotnet/pull/XXXX)) + ([#3646](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3646)) ## 1.0.0-rc9.6 diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 6e9eadce47b..2f972e92228 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -17,7 +17,7 @@ * Added support for dependency injection scenarios when configuring `MeterProvider` - ([#XXXX](https://github.com/open-telemetry/opentelemetry-dotnet/pull/XXXX)) + ([#3646](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3646)) ## 1.4.0-alpha.2 From 579232eb480516a7fab9097116bb36a5a51c363a Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 9 Sep 2022 13:01:04 -0700 Subject: [PATCH 09/11] Warning cleanup. --- .../HostingMeterExtensionTests.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs index 9ed9e3a1f75..da084b65763 100644 --- a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs +++ b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs @@ -21,6 +21,7 @@ using Microsoft.Extensions.Hosting; using OpenTelemetry.Metrics; using Xunit; +using static OpenTelemetry.Extensions.Hosting.Tests.HostingTracerExtensionTests; namespace OpenTelemetry.Extensions.Hosting.Tests { @@ -90,7 +91,7 @@ public void AddOpenTelemetryMeterProvider_ServiceProviderArgument_ServicesRegist services.AddSingleton(testInstrumentation); services.AddOpenTelemetryMetrics(builder => { - builder.Configure( + builder.ConfigureBuilder( (sp, b) => b.AddInstrumentation(() => sp.GetRequiredService())); }); @@ -114,7 +115,7 @@ public void AddOpenTelemetryMeterProvider_BadArgs_NullServiceCollection() Assert.Throws(() => services.AddOpenTelemetryMetrics(builder => { - builder.Configure( + builder.ConfigureBuilder( (sp, b) => b.AddInstrumentation(() => sp.GetRequiredService())); })); } @@ -138,10 +139,10 @@ public void AddOpenTelemetryMeterProvider_NestedConfigureCallbacks() int configureCalls = 0; var services = new ServiceCollection(); services.AddOpenTelemetryMetrics(builder => builder - .Configure((sp1, builder1) => + .ConfigureBuilder((sp1, builder1) => { configureCalls++; - builder1.Configure((sp2, builder2) => + builder1.ConfigureBuilder((sp2, builder2) => { configureCalls++; }); @@ -163,7 +164,7 @@ public void AddOpenTelemetryMeterProvider_ConfigureCallbacksUsingExtensions() services.AddSingleton(); services.AddOpenTelemetryMetrics(builder => builder - .Configure((sp1, builder1) => + .ConfigureBuilder((sp1, builder1) => { builder1 .AddInstrumentation() @@ -210,8 +211,7 @@ public void AddOpenTelemetryMeterProvider_Idempotent() private static MeterProviderBuilder AddMyFeature(MeterProviderBuilder meterProviderBuilder) { - (meterProviderBuilder.GetServices() ?? throw new NotSupportedException("MyFeature requires a hosting MeterProviderBuilder instance.")) - .AddSingleton(); + meterProviderBuilder.ConfigureServices(services => services.AddSingleton()); return meterProviderBuilder.AddReader(); } From 37bca2b3e7523027a4182d610a412db3e1f31ad4 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 9 Sep 2022 13:26:51 -0700 Subject: [PATCH 10/11] Fixes. --- src/OpenTelemetry/Metrics/MetricReaderOptions.cs | 4 ++-- .../OtlpMetricsExporterTests.cs | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry/Metrics/MetricReaderOptions.cs b/src/OpenTelemetry/Metrics/MetricReaderOptions.cs index 0c0101b7cd3..69f9e12dc9b 100644 --- a/src/OpenTelemetry/Metrics/MetricReaderOptions.cs +++ b/src/OpenTelemetry/Metrics/MetricReaderOptions.cs @@ -25,7 +25,7 @@ namespace OpenTelemetry.Metrics; /// public class MetricReaderOptions { - private PeriodicExportingMetricReaderOptions periodicExportingMetricReaderOptions = new(); + private PeriodicExportingMetricReaderOptions? periodicExportingMetricReaderOptions; /// /// Gets or sets the . @@ -37,7 +37,7 @@ public class MetricReaderOptions /// public PeriodicExportingMetricReaderOptions PeriodicExportingMetricReaderOptions { - get => this.periodicExportingMetricReaderOptions; + get => this.periodicExportingMetricReaderOptions ??= new(); set { Guard.ThrowIfNull(value); diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs index 0830cf71cdd..8553b419dfa 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs @@ -52,10 +52,7 @@ public void TestAddOtlpExporter_SetsCorrectMetricReaderDefaults() meterProvider.Dispose(); meterProvider = Sdk.CreateMeterProviderBuilder() - .AddOtlpExporter((exporterOptions, metricReaderOptions) => - { - metricReaderOptions.PeriodicExportingMetricReaderOptions = null; - }) + .AddOtlpExporter() .Build(); CheckMetricReaderDefaults(); From 88b20cf58a60e33dd6e505a0b59751ab98f2d932 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 9 Sep 2022 13:55:31 -0700 Subject: [PATCH 11/11] Tests. --- .../Metrics/CompositeMetricReader.cs | 14 +- .../Metrics/CompositeMetricReaderExt.cs | 16 +- src/OpenTelemetry/Metrics/MeterProviderSdk.cs | 6 +- .../HostingMeterExtensionTests.cs | 30 +- .../MeterProviderBuilderExtensionsTests.cs | 293 ++++++++++++++++++ 5 files changed, 319 insertions(+), 40 deletions(-) create mode 100644 test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs diff --git a/src/OpenTelemetry/Metrics/CompositeMetricReader.cs b/src/OpenTelemetry/Metrics/CompositeMetricReader.cs index b584001e31f..4e9e5d2597f 100644 --- a/src/OpenTelemetry/Metrics/CompositeMetricReader.cs +++ b/src/OpenTelemetry/Metrics/CompositeMetricReader.cs @@ -27,7 +27,7 @@ namespace OpenTelemetry.Metrics /// internal sealed partial class CompositeMetricReader : MetricReader { - private readonly DoublyLinkedListNode head; + public readonly DoublyLinkedListNode Head; private DoublyLinkedListNode tail; private bool disposed; private int count; @@ -42,8 +42,8 @@ public CompositeMetricReader(IEnumerable readers) throw new ArgumentException($"'{iter}' is null or empty", nameof(iter)); } - this.head = new DoublyLinkedListNode(iter.Current); - this.tail = this.head; + this.Head = new DoublyLinkedListNode(iter.Current); + this.tail = this.Head; this.count++; while (iter.MoveNext()) @@ -67,7 +67,7 @@ public CompositeMetricReader AddReader(MetricReader reader) return this; } - public Enumerator GetEnumerator() => new(this.head); + public Enumerator GetEnumerator() => new(this.Head); /// internal override bool ProcessMetrics(in Batch metrics, int timeoutMilliseconds) @@ -85,7 +85,7 @@ protected override bool OnCollect(int timeoutMilliseconds = Timeout.Infinite) ? null : Stopwatch.StartNew(); - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (sw == null) { @@ -111,7 +111,7 @@ protected override bool OnShutdown(int timeoutMilliseconds) ? null : Stopwatch.StartNew(); - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (sw == null) { @@ -135,7 +135,7 @@ protected override void Dispose(bool disposing) { if (disposing) { - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { try { diff --git a/src/OpenTelemetry/Metrics/CompositeMetricReaderExt.cs b/src/OpenTelemetry/Metrics/CompositeMetricReaderExt.cs index 11693017fb9..20b0b681664 100644 --- a/src/OpenTelemetry/Metrics/CompositeMetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/CompositeMetricReaderExt.cs @@ -29,7 +29,7 @@ internal sealed partial class CompositeMetricReader internal List AddMetricsWithNoViews(Instrument instrument) { var metrics = new List(this.count); - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { var metric = cur.Value.AddMetricWithNoViews(instrument); metrics.Add(metric); @@ -43,7 +43,7 @@ internal void RecordSingleStreamLongMeasurements(List metrics, long valu Debug.Assert(metrics.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metrics[index] != null) { @@ -59,7 +59,7 @@ internal void RecordSingleStreamDoubleMeasurements(List metrics, double Debug.Assert(metrics.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metrics[index] != null) { @@ -73,7 +73,7 @@ internal void RecordSingleStreamDoubleMeasurements(List metrics, double internal List> AddMetricsSuperListWithViews(Instrument instrument, List metricStreamConfigs) { var metricsSuperList = new List>(this.count); - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { var metrics = cur.Value.AddMetricsListWithViews(instrument, metricStreamConfigs); metricsSuperList.Add(metrics); @@ -87,7 +87,7 @@ internal void RecordLongMeasurements(List> metricsSuperList, long v Debug.Assert(metricsSuperList.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metricsSuperList[index].Count > 0) { @@ -103,7 +103,7 @@ internal void RecordDoubleMeasurements(List> metricsSuperList, doub Debug.Assert(metricsSuperList.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metricsSuperList[index].Count > 0) { @@ -119,7 +119,7 @@ internal void CompleteSingleStreamMeasurements(List metrics) Debug.Assert(metrics.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metrics[index] != null) { @@ -135,7 +135,7 @@ internal void CompleteMesaurements(List> metricsSuperList) Debug.Assert(metricsSuperList.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metricsSuperList[index].Count > 0) { diff --git a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs index 93458110742..223290a210e 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs @@ -31,6 +31,7 @@ internal sealed class MeterProviderSdk : MeterProvider { internal readonly IDisposable? OwnedServiceProvider; internal int ShutdownCount; + internal bool Disposed; private readonly List instrumentations = new(); private readonly List> viewConfigs; @@ -38,7 +39,6 @@ internal sealed class MeterProviderSdk : MeterProvider private readonly MeterListener listener; private readonly MetricReader? reader; private readonly CompositeMetricReader? compositeMetricReader; - private bool disposed; internal MeterProviderSdk( IServiceProvider serviceProvider, @@ -555,7 +555,7 @@ internal bool OnShutdown(int timeoutMilliseconds) protected override void Dispose(bool disposing) { OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"{nameof(MeterProviderSdk)}.{nameof(this.Dispose)} started."); - if (!this.disposed) + if (!this.Disposed) { if (disposing) { @@ -579,7 +579,7 @@ protected override void Dispose(bool disposing) this.OwnedServiceProvider?.Dispose(); } - this.disposed = true; + this.Disposed = true; OpenTelemetrySdkEventSource.Log.ProviderDisposed(nameof(MeterProvider)); } diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs index da084b65763..f4acf44b4e2 100644 --- a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs +++ b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs @@ -179,34 +179,20 @@ public void AddOpenTelemetryMeterProvider_ConfigureCallbacksUsingExtensions() Assert.True(meterProvider.Reader is TestReader); } - [Fact(Skip = "Known limitation. See issue 1215.")] - public void AddOpenTelemetryMeterProvider_Idempotent() + [Fact] + public void AddOpenTelemetryMetrics_MultipleCallsConfigureSingleProvider() { - var testInstrumentation1 = new TestInstrumentation(); - var testInstrumentation2 = new TestInstrumentation(); - var services = new ServiceCollection(); - services.AddSingleton(testInstrumentation1); - services.AddOpenTelemetryMetrics(builder => - { - builder.AddInstrumentation(() => testInstrumentation1); - }); - services.AddOpenTelemetryMetrics(builder => - { - builder.AddInstrumentation(() => testInstrumentation2); - }); + services.AddOpenTelemetryMetrics(builder => builder.AddMeter("TestSourceBuilder1")); + services.AddOpenTelemetryMetrics(); + services.AddOpenTelemetryMetrics(builder => builder.AddMeter("TestSourceBuilder2")); - var serviceProvider = services.BuildServiceProvider(); + using var serviceProvider = services.BuildServiceProvider(); - var meterFactory = serviceProvider.GetRequiredService(); - Assert.NotNull(meterFactory); + var providers = serviceProvider.GetServices(); - Assert.False(testInstrumentation1.Disposed); - Assert.False(testInstrumentation2.Disposed); - serviceProvider.Dispose(); - Assert.True(testInstrumentation1.Disposed); - Assert.True(testInstrumentation2.Disposed); + Assert.Single(providers); } private static MeterProviderBuilder AddMyFeature(MeterProviderBuilder meterProviderBuilder) diff --git a/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs new file mode 100644 index 00000000000..b4c96f2cc7c --- /dev/null +++ b/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs @@ -0,0 +1,293 @@ +// +// 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; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.Metrics.Tests +{ + public class MeterProviderBuilderExtensionsTests + { + [Fact] + public void ServiceLifecycleAvailableToSDKBuilderTest() + { + var builder = Sdk.CreateMeterProviderBuilder(); + + builder.ConfigureServices(services => services.AddSingleton()); + + MyInstrumentation myInstrumentation = null; + + RunBuilderServiceLifecycleTest( + builder, + () => + { + var provider = builder.Build() as MeterProviderSdk; + + // Note: Build can only be called once + Assert.Throws(() => builder.Build()); + + Assert.NotNull(provider); + Assert.NotNull(provider.OwnedServiceProvider); + + myInstrumentation = ((IServiceProvider)provider.OwnedServiceProvider).GetRequiredService(); + + return provider; + }, + provider => + { + provider.Dispose(); + }); + + Assert.NotNull(myInstrumentation); + Assert.True(myInstrumentation.Disposed); + } + + [Fact] + public void ServiceLifecycleAvailableToServicesBuilderTest() + { + var services = new ServiceCollection(); + + bool testRun = false; + + ServiceProvider serviceProvider = null; + MeterProviderSdk provider = null; + + services.ConfigureOpenTelemetryMetrics(builder => + { + testRun = true; + + RunBuilderServiceLifecycleTest( + builder, + () => + { + // Note: Build can't be called directly on builder tied to external services + Assert.Throws(() => builder.Build()); + + serviceProvider = services.BuildServiceProvider(); + + provider = serviceProvider.GetRequiredService() as MeterProviderSdk; + + Assert.NotNull(provider); + Assert.Null(provider.OwnedServiceProvider); + + return provider; + }, + (provider) => { }); + }); + + Assert.True(testRun); + + Assert.NotNull(serviceProvider); + Assert.NotNull(provider); + + Assert.False(provider.Disposed); + + serviceProvider.Dispose(); + + Assert.True(provider.Disposed); + } + + [Fact] + public void SingleProviderForServiceCollectionTest() + { + var services = new ServiceCollection(); + + services.ConfigureOpenTelemetryMetrics(builder => + { + builder.AddInstrumentation(() => new()); + }); + + services.ConfigureOpenTelemetryMetrics(builder => + { + builder.AddInstrumentation(() => new()); + }); + + using var serviceProvider = services.BuildServiceProvider(); + + Assert.NotNull(serviceProvider); + + var meterProviders = serviceProvider.GetServices(); + + Assert.Single(meterProviders); + + var provider = meterProviders.First() as MeterProviderSdk; + + Assert.NotNull(provider); + + Assert.Equal(2, provider.Instrumentations.Count); + } + + [Fact] + public void AddReaderUsingDependencyInjectionTest() + { + var builder = Sdk.CreateMeterProviderBuilder(); + + builder.AddReader(); + builder.AddReader(); + + using var provider = builder.Build() as MeterProviderSdk; + + Assert.NotNull(provider); + + var readers = ((IServiceProvider)provider.OwnedServiceProvider).GetServices(); + + // Note: Two "Add" calls but it is a singleton so only a single registration is produced + Assert.Single(readers); + + var reader = provider.Reader as CompositeMetricReader; + + Assert.NotNull(reader); + + // Note: Two "Add" calls due yield two readers added to provider, even though they are the same + Assert.True(reader.Head.Value is MyReader); + Assert.True(reader.Head.Next?.Value is MyReader); + } + + [Fact] + public void SetAndConfigureResourceTest() + { + var builder = Sdk.CreateMeterProviderBuilder(); + + int configureInvocations = 0; + + builder.SetResourceBuilder(ResourceBuilder.CreateEmpty().AddService("Test")); + builder.ConfigureResource(builder => + { + configureInvocations++; + + Assert.Single(builder.Resources); + + builder.AddAttributes(new Dictionary() { ["key1"] = "value1" }); + + Assert.Equal(2, builder.Resources.Count); + }); + builder.SetResourceBuilder(ResourceBuilder.CreateEmpty()); + builder.ConfigureResource(builder => + { + configureInvocations++; + + Assert.Empty(builder.Resources); + + builder.AddAttributes(new Dictionary() { ["key2"] = "value2" }); + + Assert.Single(builder.Resources); + }); + + using var provider = builder.Build() as MeterProviderSdk; + + Assert.Equal(2, configureInvocations); + + Assert.Single(provider.Resource.Attributes); + Assert.Contains(provider.Resource.Attributes, kvp => kvp.Key == "key2" && (string)kvp.Value == "value2"); + } + + private static void RunBuilderServiceLifecycleTest( + MeterProviderBuilder builder, + Func buildFunc, + Action postAction) + { + var baseBuilder = builder as MeterProviderBuilderBase; + Assert.Null(baseBuilder.State); + + builder.AddMeter("TestSource"); + + bool configureServicesCalled = false; + builder.ConfigureServices(services => + { + configureServicesCalled = true; + + Assert.NotNull(services); + + services.TryAddSingleton(); + + services.ConfigureOpenTelemetryMetrics(b => + { + // Note: This is strange to call ConfigureOpenTelemetryMetrics here, but supported + b.AddInstrumentation(); + }); + }); + + int configureBuilderInvocations = 0; + builder.ConfigureBuilder((sp, builder) => + { + configureBuilderInvocations++; + + var baseBuilder = builder as MeterProviderBuilderBase; + Assert.NotNull(baseBuilder?.State); + + builder.AddMeter("TestSource2"); + + Assert.Contains(baseBuilder.State.MeterSources, s => s == "TestSource"); + Assert.Contains(baseBuilder.State.MeterSources, s => s == "TestSource2"); + + // Note: Services can't be configured at this stage + Assert.Throws( + () => builder.ConfigureServices(services => services.TryAddSingleton())); + + builder.AddReader(sp.GetRequiredService()); + + builder.ConfigureBuilder((_, b) => + { + // Note: ConfigureBuilder calls can be nested, this is supported + configureBuilderInvocations++; + + b.ConfigureBuilder((_, _) => + { + configureBuilderInvocations++; + }); + }); + }); + + var provider = buildFunc(); + + Assert.True(configureServicesCalled); + Assert.Equal(3, configureBuilderInvocations); + + Assert.Single(provider.Instrumentations); + Assert.True(provider.Instrumentations[0] is MyInstrumentation); + Assert.True(provider.Reader is MyReader); + + postAction(provider); + } + + private sealed class MyInstrumentation : IDisposable + { + internal bool Disposed; + + public void Dispose() + { + this.Disposed = true; + } + } + + private sealed class MyReader : MetricReader + { + } + + private sealed class MyExporter : BaseExporter + { + public override ExportResult Export(in Batch batch) + { + return ExportResult.Success; + } + } + } +}