From 8d9bb6c7888a407a6dfac2c4c5c2c8ca86374ee3 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 28 Jul 2022 17:00:07 -0700 Subject: [PATCH 01/31] Support dependency injection in logging. Add AddOpenTelemetryEventSourceLogEmitter extension. --- examples/LoggingExtensions/Program.cs | 2 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + .../netstandard2.1/PublicAPI.Unshipped.txt | 2 + ...yEventSourceServiceCollectionExtensions.cs | 80 ++++++++++++ .../README.md | 33 ++++- .../README.md | 2 +- .../.publicApi/net462/PublicAPI.Unshipped.txt | 9 +- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 7 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 7 +- .../netstandard2.1/PublicAPI.Unshipped.txt | 7 +- .../Logs/OpenTelemetryLoggerOptions.cs | 59 ++++++++- .../Logs/OpenTelemetryLoggerProvider.cs | 118 +++++++++++++++--- .../Logs/OpenTelemetryLoggingExtensions.cs | 18 +++ ...OpenTelemetryEventSourceLogEmitterTests.cs | 47 +++---- .../OpenTelemetrySerilogSinkTests.cs | 47 +++---- .../Logs/LogEmitterTests.cs | 8 +- .../Logs/OpenTelemetryLoggerProviderTests.cs | 2 +- 17 files changed, 357 insertions(+), 93 deletions(-) create mode 100644 src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceServiceCollectionExtensions.cs diff --git a/examples/LoggingExtensions/Program.cs b/examples/LoggingExtensions/Program.cs index 24ec26eadbf..7ab7259a49b 100644 --- a/examples/LoggingExtensions/Program.cs +++ b/examples/LoggingExtensions/Program.cs @@ -22,7 +22,7 @@ var resourceBuilder = ResourceBuilder.CreateDefault().AddService("Examples.LoggingExtensions"); -var openTelemetryLoggerProvider = new OpenTelemetryLoggerProvider(options => +var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.IncludeFormattedMessage = true; options diff --git a/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 32c7f36aea5..a888e2bf8c6 100644 --- a/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,4 +1,6 @@ #nullable enable OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter.OpenTelemetryEventSourceLogEmitter(OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, System.Func! shouldListenToFunc, bool disposeProvider = true) -> void +OpenTelemetry.Logs.OpenTelemetryEventSourceServiceCollectionExtensions override OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter.Dispose() -> void +static OpenTelemetry.Logs.OpenTelemetryEventSourceServiceCollectionExtensions.AddOpenTelemetryEventSourceLogEmitter(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! shouldListenToFunc) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! diff --git a/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 32c7f36aea5..a888e2bf8c6 100644 --- a/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,4 +1,6 @@ #nullable enable OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter.OpenTelemetryEventSourceLogEmitter(OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, System.Func! shouldListenToFunc, bool disposeProvider = true) -> void +OpenTelemetry.Logs.OpenTelemetryEventSourceServiceCollectionExtensions override OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter.Dispose() -> void +static OpenTelemetry.Logs.OpenTelemetryEventSourceServiceCollectionExtensions.AddOpenTelemetryEventSourceLogEmitter(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! shouldListenToFunc) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! diff --git a/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceServiceCollectionExtensions.cs b/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceServiceCollectionExtensions.cs new file mode 100644 index 00000000000..5224f0daf2e --- /dev/null +++ b/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceServiceCollectionExtensions.cs @@ -0,0 +1,80 @@ +// +// 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.Tracing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Logs +{ + /// + /// Contains extension methods for registering OpenTelemetry EventSource utilities into application services. + /// + public static class OpenTelemetryEventSourceServiceCollectionExtensions + { + /// + /// Registers into application services an + /// which will convert events into + /// OpenTelemetry logs. + /// + /// . + /// Callback function used to decide if + /// events should be captured for a given . Return if no + /// events should be captured. + /// Supplied for chaining calls. + public static IServiceCollection AddOpenTelemetryEventSourceLogEmitter( + this IServiceCollection services, + Func shouldListenToFunc) + { + Guard.ThrowIfNull(services); + Guard.ThrowIfNull(shouldListenToFunc); + + services.TryAddSingleton(); + + services.Configure(options => + { + options.Configure((sp, provider) => + { + var manager = sp.GetRequiredService(); + + manager.Emitters.Add( + new OpenTelemetryEventSourceLogEmitter(provider, shouldListenToFunc, disposeProvider: false)); + }); + }); + + return services; + } + + internal sealed class EventSourceManager : IDisposable + { + public List Emitters { get; } = new(); + + public void Dispose() + { + foreach (var emitter in this.Emitters) + { + emitter.Dispose(); + } + + this.Emitters.Clear(); + } + } + } +} diff --git a/src/OpenTelemetry.Extensions.EventSource/README.md b/src/OpenTelemetry.Extensions.EventSource/README.md index 5259aae3425..994523416d4 100644 --- a/src/OpenTelemetry.Extensions.EventSource/README.md +++ b/src/OpenTelemetry.Extensions.EventSource/README.md @@ -17,9 +17,38 @@ dotnet add package OpenTelemetry.Extensions.EventSource --prerelease ## Usage Example +### Configured using dependency injection + +```csharp +IHost host = Host.CreateDefaultBuilder(args) + .ConfigureLogging(builder => + { + builder.ClearProviders(); + + // Step 1: Configure OpenTelemetry logging... + builder.AddOpenTelemetry(options => + { + options + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyService")) + .AddConsoleExporter(); + }); + }) + .ConfigureServices((hostContext, services) => + { + // Step 2: Register OpenTelemetryEventSourceLogEmitter to listen to events... + services.AddOpenTelemetryEventSourceLogEmitter( + (name) => name == MyEventSource.Name ? EventLevel.Informational : null); + }) + .Build(); + + host.Run(); +``` + +### Configured manually + ```csharp // Step 1: Configure OpenTelemetryLoggerProvider... -var openTelemetryLoggerProvider = new OpenTelemetryLoggerProvider(options => +var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyService")) @@ -29,7 +58,7 @@ var openTelemetryLoggerProvider = new OpenTelemetryLoggerProvider(options => // Step 2: Create OpenTelemetryEventSourceLogEmitter to listen to events... using var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( openTelemetryLoggerProvider, - (name) => name.StartsWith("OpenTelemetry") ? EventLevel.LogAlways : null, + (name) => name == MyEventSource.Name ? EventLevel.Informational : null, disposeProvider: true); ``` diff --git a/src/OpenTelemetry.Extensions.Serilog/README.md b/src/OpenTelemetry.Extensions.Serilog/README.md index 39372b4e142..c7ec8a020b6 100644 --- a/src/OpenTelemetry.Extensions.Serilog/README.md +++ b/src/OpenTelemetry.Extensions.Serilog/README.md @@ -17,7 +17,7 @@ dotnet add package OpenTelemetry.Extensions.Serilog --prerelease ```csharp // Step 1: Configure OpenTelemetryLoggerProvider... -var openTelemetryLoggerProvider = new OpenTelemetryLoggerProvider(options => +var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyService")) diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt index 791e1c4f84a..7bfaa9b40a2 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt @@ -7,14 +7,19 @@ OpenTelemetry.Logs.LogRecord.Timestamp.set -> void OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Configure(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection? +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.Action! configure) -> void -OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! +static OpenTelemetry.Logs.OpenTelemetryLoggerProvider.Create(System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! ~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 diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt index a045a0ffba5..7bfaa9b40a2 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -7,14 +7,19 @@ OpenTelemetry.Logs.LogRecord.Timestamp.set -> void OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Configure(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection? +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.Action! configure) -> void *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! +static OpenTelemetry.Logs.OpenTelemetryLoggerProvider.Create(System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! ~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 diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 791e1c4f84a..9d750830015 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -7,14 +7,19 @@ OpenTelemetry.Logs.LogRecord.Timestamp.set -> void OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Configure(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection? +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.Action! configure) -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! +static OpenTelemetry.Logs.OpenTelemetryLoggerProvider.Create(System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! ~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 diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index a045a0ffba5..7bfaa9b40a2 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -7,14 +7,19 @@ OpenTelemetry.Logs.LogRecord.Timestamp.set -> void OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Configure(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection? +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.Action! configure) -> void *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! +static OpenTelemetry.Logs.OpenTelemetryLoggerProvider.Create(System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! ~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 diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs index d20fcce2b47..2ec92718eea 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Internal; using OpenTelemetry.Resources; @@ -30,6 +31,13 @@ public class OpenTelemetryLoggerOptions { internal readonly List> Processors = new(); internal ResourceBuilder ResourceBuilder = ResourceBuilder.CreateDefault(); + internal List>? ConfigurationActions = new(); + + /// + /// Gets the where Logging services are + /// configured. + /// + public IServiceCollection? Services { get; internal set; } /// /// Gets or sets a value indicating whether or not log scopes should be @@ -60,6 +68,12 @@ public class OpenTelemetryLoggerOptions /// /// Adds processor to the options. /// + /// + /// Note: The supplied will be + /// automatically disposed when then the final built from the options is + /// disposed. + /// /// Log processor to add. /// Returns for chaining. public OpenTelemetryLoggerOptions AddProcessor(BaseProcessor processor) @@ -72,26 +86,39 @@ public OpenTelemetryLoggerOptions AddProcessor(BaseProcessor processo } /// - /// Sets the from which the Resource associated with + /// Adds a processor to the options which will be retrieved using dependency injection. + /// + /// Processor type. + /// The supplied for chaining. + public OpenTelemetryLoggerOptions AddProcessor() + where T : BaseProcessor + { + return this.Configure((sp, provider) => + { + provider.AddProcessor(sp.GetRequiredService()); + }); + } + + /// + /// Sets the from which the Resource associated with /// this provider is built from. Overwrites currently set ResourceBuilder. /// You should usually use instead /// (call if desired). /// - /// from which Resource will be built. + /// from which Resource will be built. /// Returns for chaining. public OpenTelemetryLoggerOptions SetResourceBuilder(ResourceBuilder resourceBuilder) { Guard.ThrowIfNull(resourceBuilder); - this.ResourceBuilder = resourceBuilder; return this; } /// - /// Modify the from which the Resource associated with + /// Modify the from which the Resource associated with /// this provider is built from in-place. /// - /// An action which modifies the provided in-place. + /// An action which modifies the provided in-place. /// Returns for chaining. public OpenTelemetryLoggerOptions ConfigureResource(Action configure) { @@ -99,5 +126,27 @@ public OpenTelemetryLoggerOptions ConfigureResource(Action conf configure(this.ResourceBuilder); return this; } + + /// + /// Register a callback action to configure the once the application is available. + /// + /// Configuration callback. + /// The supplied for chaining. + public OpenTelemetryLoggerOptions Configure(Action configure) + { + Guard.ThrowIfNull(configure); + + var configurationActions = this.ConfigurationActions; + if (configurationActions == null) + { + throw new InvalidOperationException("Configuration actions cannot be registered on options after OpenTelemetryLoggerProvider has been created."); + } + + configurationActions.Add(configure); + + return this; + } } } diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs index d94769b7f59..79952603b91 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs @@ -19,6 +19,7 @@ using System; using System.Collections; using System.Threading; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenTelemetry.Internal; @@ -37,6 +38,7 @@ public class OpenTelemetryLoggerProvider : BaseProvider, ILoggerProvider, ISuppo internal readonly bool ParseStateValues; internal BaseProcessor? Processor; internal Resource Resource; + private readonly ServiceProvider? ownedServiceProvider; private readonly Hashtable loggers = new(); private ILogRecordPool? threadStaticPool = LogRecordThreadStaticPool.Instance; private bool disposed; @@ -51,18 +53,22 @@ static OpenTelemetryLoggerProvider() /// /// Initializes a new instance of the class. /// - /// . - public OpenTelemetryLoggerProvider(IOptionsMonitor options) - : this(options?.CurrentValue ?? throw new ArgumentNullException(nameof(options))) + /// . + public OpenTelemetryLoggerProvider(IServiceProvider serviceProvider) + : this( + serviceProvider?.GetRequiredService>().Value ?? throw new ArgumentNullException(nameof(serviceProvider)), + serviceProvider, + ownsServiceProvider: false) { } /// /// Initializes a new instance of the class. /// - /// configuration callback. - public OpenTelemetryLoggerProvider(Action configure) - : this(BuildOptions(configure ?? throw new ArgumentNullException(nameof(configure)))) + /// . + [Obsolete("Call the OpenTelemetryLoggerProvider constructor which accepts IServiceProvider")] + public OpenTelemetryLoggerProvider(IOptionsMonitor options) + : this(options?.CurrentValue ?? throw new ArgumentNullException(nameof(options)), serviceProvider: null, ownsServiceProvider: false) { } @@ -70,11 +76,17 @@ public OpenTelemetryLoggerProvider(Action configure) /// Initializes a new instance of the class. /// public OpenTelemetryLoggerProvider() - : this(BuildOptions(configure: null)) + : this(new(), serviceProvider: null, ownsServiceProvider: false) { } + // Note: This is only for tests. Options will be missing ServiceCollection & ServiceProvider features will be unavailable. internal OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options) + : this(options, serviceProvider: null, ownsServiceProvider: false) + { + } + + private OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IServiceProvider? serviceProvider, bool ownsServiceProvider) { Guard.ThrowIfNull(options); @@ -82,18 +94,81 @@ internal OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options) this.IncludeFormattedMessage = options.IncludeFormattedMessage; this.ParseStateValues = options.ParseStateValues; + if (ownsServiceProvider) + { + this.ownedServiceProvider = serviceProvider as ServiceProvider; + } + this.Resource = options.ResourceBuilder.Build(); + // Step 1: Add any processors added to options. + foreach (var processor in options.Processors) { this.AddProcessor(processor); } + + var configurationActions = options.ConfigurationActions; + if (configurationActions?.Count > 0) + { + // Step 2: Execute any configuration actions. + + if (serviceProvider == null) + { + throw new InvalidOperationException("Configuration actions were registered on options but no service provider was supplied."); + } + + // Note: Not using a foreach loop because additional actions can be + // added during each call. + for (int i = 0; i < configurationActions.Count; i++) + { + configurationActions[i](serviceProvider, this); + } + + options.ConfigurationActions = null; + } + + if (serviceProvider != null) + { + // Step 3: Look for any processors registered directly with the service provider. + + var registeredProcessors = serviceProvider.GetServices>(); + foreach (BaseProcessor processor in registeredProcessors) + { + this.AddProcessor(processor); + } + } } internal IExternalScopeProvider? ScopeProvider { get; private set; } internal ILogRecordPool LogRecordPool => this.threadStaticPool ?? LogRecordSharedPool.Current; + /// + /// Create a instance. + /// + /// Configuration callback. + /// . + public static OpenTelemetryLoggerProvider Create(Action? configure = null) + { + OpenTelemetryLoggerOptions options = new(); + + if (configure != null) + { + ServiceCollection services = new ServiceCollection(); + + options.Services = services; + + configure.Invoke(options); + + IServiceProvider serviceProvider = services.BuildServiceProvider(); + + return new OpenTelemetryLoggerProvider(options, serviceProvider, ownsServiceProvider: true); + } + + return new OpenTelemetryLoggerProvider(options, serviceProvider: null, ownsServiceProvider: false); + } + /// void ISupportExternalScope.SetScopeProvider(IExternalScopeProvider scopeProvider) { @@ -158,12 +233,16 @@ public bool ForceFlush(int timeoutMilliseconds = Timeout.Infinite) } /// - /// Create a . + /// Add a processor to the . /// - /// . - internal LogEmitter CreateEmitter() => new(this); - - internal OpenTelemetryLoggerProvider AddProcessor(BaseProcessor processor) + /// + /// Note: The supplied will be + /// automatically disposed when then the is disposed. + /// + /// Log processor to add. + /// The supplied for chaining. + public OpenTelemetryLoggerProvider AddProcessor(BaseProcessor processor) { Guard.ThrowIfNull(processor); @@ -196,6 +275,12 @@ internal OpenTelemetryLoggerProvider AddProcessor(BaseProcessor proce return this; } + /// + /// Create a . + /// + /// . + internal LogEmitter CreateEmitter() => new(this); + internal bool ContainsBatchProcessor(BaseProcessor processor) { if (processor is BatchExportProcessor) @@ -229,6 +314,8 @@ protected override void Dispose(bool disposing) // Wait for up to 5 seconds grace period this.Processor?.Shutdown(5000); this.Processor?.Dispose(); + + this.ownedServiceProvider?.Dispose(); } this.disposed = true; @@ -237,12 +324,5 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - - private static OpenTelemetryLoggerOptions BuildOptions(Action? configure) - { - OpenTelemetryLoggerOptions options = new(); - configure?.Invoke(options); - return options; - } } } diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs index 9687d32eb1b..0f27df11c3d 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs @@ -21,6 +21,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Configuration; +using Microsoft.Extensions.Options; using OpenTelemetry.Internal; using OpenTelemetry.Logs; @@ -51,6 +52,8 @@ public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder, Act builder.AddConfiguration(); builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton>( + new DefaultOpenTelemetryLoggerOptionsConfigureOptions(builder.Services))); if (configure != null) { @@ -106,5 +109,20 @@ public static ILoggingBuilder AddOpenTelemetry( return builder; } + + private sealed class DefaultOpenTelemetryLoggerOptionsConfigureOptions : IConfigureOptions + { + private readonly IServiceCollection services; + + public DefaultOpenTelemetryLoggerOptionsConfigureOptions(IServiceCollection services) + { + this.services = services; + } + + public void Configure(OpenTelemetryLoggerOptions options) + { + options.Services = this.services; + } + } } } diff --git a/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs index e6a53aa6387..0f58e4c5459 100644 --- a/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs +++ b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs @@ -32,30 +32,28 @@ public class OpenTelemetryEventSourceLogEmitterTests [InlineData(false)] public void OpenTelemetryEventSourceLogEmitterDisposesProviderTests(bool dispose) { - List exportedItems = new(); - #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new WrappedOpenTelemetryLoggerProvider(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var disposeTrackingProcessor = new DisposeTrackingProcessor(); #pragma warning restore CA2000 // Dispose objects before losing scope - using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( - openTelemetryLoggerProvider, - (name) => null, - disposeProvider: dispose)) + using (var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { - } + options.AddProcessor(disposeTrackingProcessor); + })) + { + using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( + openTelemetryLoggerProvider, + (name) => null, + disposeProvider: dispose)) + { + } - Assert.Equal(dispose, openTelemetryLoggerProvider.Disposed); + Assert.Equal(dispose, disposeTrackingProcessor.Disposed); - if (!dispose) - { openTelemetryLoggerProvider.Dispose(); } - Assert.True(openTelemetryLoggerProvider.Disposed); + Assert.True(disposeTrackingProcessor.Disposed); } [Theory] @@ -67,7 +65,7 @@ public void OpenTelemetryEventSourceLogEmitterFilterTests(string sourceName, Eve List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new WrappedOpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -90,7 +88,7 @@ public void OpenTelemetryEventSourceLogEmitterCapturesExistingSourceTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new WrappedOpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -114,7 +112,7 @@ public void OpenTelemetryEventSourceLogEmitterSimpleEventTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new WrappedOpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -157,7 +155,7 @@ public void OpenTelemetryEventSourceLogEmitterSimpleEventWithActivityTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new WrappedOpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -190,7 +188,7 @@ public void OpenTelemetryEventSourceLogEmitterComplexEventTest(bool formatMessag List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new WrappedOpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.IncludeFormattedMessage = formatMessage; options.AddInMemoryExporter(exportedItems); @@ -258,7 +256,7 @@ public void OpenTelemetryEventSourceLogEmitterActivityIdTest(bool enableTplListe List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new WrappedOpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -293,13 +291,8 @@ public void OpenTelemetryEventSourceLogEmitterActivityIdTest(bool enableTplListe } } - private sealed class WrappedOpenTelemetryLoggerProvider : OpenTelemetryLoggerProvider + private sealed class DisposeTrackingProcessor : BaseProcessor { - public WrappedOpenTelemetryLoggerProvider(Action configure) - : base(configure) - { - } - public bool Disposed { get; private set; } protected override void Dispose(bool disposing) diff --git a/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs b/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs index 000a1e7c1d6..c20ca122543 100644 --- a/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs +++ b/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs @@ -33,29 +33,25 @@ public class OpenTelemetrySerilogSinkTests [InlineData(false)] public void SerilogDisposesProviderTests(bool dispose) { - List exportedItems = new(); - #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new WrappedOpenTelemetryLoggerProvider(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var disposeTrackingProcessor = new DisposeTrackingProcessor(); #pragma warning restore CA2000 // Dispose objects before losing scope - Log.Logger = new LoggerConfiguration() - .WriteTo.OpenTelemetry(openTelemetryLoggerProvider, disposeProvider: dispose) - .CreateLogger(); - - Log.CloseAndFlush(); + using (var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => + { + options.AddProcessor(disposeTrackingProcessor); + })) + { + Log.Logger = new LoggerConfiguration() + .WriteTo.OpenTelemetry(openTelemetryLoggerProvider, disposeProvider: dispose) + .CreateLogger(); - Assert.Equal(dispose, openTelemetryLoggerProvider.Disposed); + Log.CloseAndFlush(); - if (!dispose) - { - openTelemetryLoggerProvider.Dispose(); + Assert.Equal(dispose, disposeTrackingProcessor.Disposed); } - Assert.True(openTelemetryLoggerProvider.Disposed); + Assert.True(disposeTrackingProcessor.Disposed); } [Theory] @@ -66,7 +62,7 @@ public void SerilogBasicLogTests(bool includeFormattedMessage) List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new OpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.IncludeFormattedMessage = includeFormattedMessage; @@ -119,7 +115,7 @@ public void SerilogBasicLogWithActivityTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new OpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -151,7 +147,7 @@ public void SerilogCategoryNameTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new OpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -181,7 +177,7 @@ public void SerilogComplexMessageTemplateTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new OpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -214,7 +210,7 @@ public void SerilogArrayMessageTemplateTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new OpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -253,7 +249,7 @@ public void SerilogExceptionTest() InvalidOperationException ex = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = new OpenTelemetryLoggerProvider(options => + var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -276,13 +272,8 @@ public void SerilogExceptionTest() Assert.Equal(ex, logRecord.Exception); } - private sealed class WrappedOpenTelemetryLoggerProvider : OpenTelemetryLoggerProvider + private sealed class DisposeTrackingProcessor : BaseProcessor { - public WrappedOpenTelemetryLoggerProvider(Action configure) - : base(configure) - { - } - public bool Disposed { get; private set; } protected override void Dispose(bool disposing) diff --git a/test/OpenTelemetry.Tests/Logs/LogEmitterTests.cs b/test/OpenTelemetry.Tests/Logs/LogEmitterTests.cs index 7e086accf00..fcb11b8d8e4 100644 --- a/test/OpenTelemetry.Tests/Logs/LogEmitterTests.cs +++ b/test/OpenTelemetry.Tests/Logs/LogEmitterTests.cs @@ -29,7 +29,7 @@ public void LogEmitterBasicTest() { var exportedItems = new List(); - using var provider = new OpenTelemetryLoggerProvider(options => + using var provider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -82,7 +82,7 @@ public void LogEmitterFromActivityTest() { var exportedItems = new List(); - using var provider = new OpenTelemetryLoggerProvider(options => + using var provider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -117,7 +117,7 @@ public void LogEmitterLocalToUtcTimestampTest() { var exportedItems = new List(); - using var provider = new OpenTelemetryLoggerProvider(options => + using var provider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); @@ -148,7 +148,7 @@ public void LogEmitterUnspecifiedTimestampTest() { var exportedItems = new List(); - using var provider = new OpenTelemetryLoggerProvider(options => + using var provider = OpenTelemetryLoggerProvider.Create(options => { options.AddInMemoryExporter(exportedItems); }); diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs index 6ddd5d7caa4..41f8772180e 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs @@ -43,7 +43,7 @@ public void ConfigureCtorTests() { OpenTelemetryLoggerOptions defaults = new(); - using OpenTelemetryLoggerProvider provider = new(options => + using OpenTelemetryLoggerProvider provider = OpenTelemetryLoggerProvider.Create(options => { options.IncludeScopes = !defaults.IncludeScopes; options.IncludeFormattedMessage = !defaults.IncludeFormattedMessage; From 0836b09aa4857ca42845ba03222d194aac53e6c9 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 10:00:49 -0700 Subject: [PATCH 02/31] CHANGELOG update. --- src/OpenTelemetry/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 85eee3b91e2..32406f3a4d9 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -35,6 +35,10 @@ `OpenTelemetryLoggerProvider` directly ([#3489](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3489)) +* Added support for dependency injection scenarios when configuring + `OpenTelemetryLoggerProvider` + ([#3504](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3504)) + ## 1.3.0 Released 2022-Jun-03 From 013ab5935e3d332ac7ecf5a8d7ec198ef49a30b5 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 10:31:30 -0700 Subject: [PATCH 03/31] Bug fixes and a test. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 +- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 +- .../netstandard2.1/PublicAPI.Unshipped.txt | 2 +- .../Logs/OpenTelemetryLoggerProvider.cs | 9 +++-- .../Logs/OpenTelemetryLoggingExtensions.cs | 4 ++ .../OpenTelemetryLoggingExtensionsTests.cs | 40 +++++++++++++++++++ 7 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt index 7bfaa9b40a2..a80e6e807ff 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt @@ -15,7 +15,7 @@ OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BasePr OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.IServiceProvider! serviceProvider) -> void +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor! options, System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt index 7bfaa9b40a2..a80e6e807ff 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -15,7 +15,7 @@ OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BasePr OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.IServiceProvider! serviceProvider) -> void +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor! options, System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 9d750830015..751cc2ab753 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -15,7 +15,7 @@ OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMillisecond OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.IServiceProvider! serviceProvider) -> void +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor! options, System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 7bfaa9b40a2..a80e6e807ff 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -15,7 +15,7 @@ OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BasePr OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.IServiceProvider! serviceProvider) -> void +OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor! options, System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs index 79952603b91..2009fbf5eb4 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs @@ -53,11 +53,12 @@ static OpenTelemetryLoggerProvider() /// /// Initializes a new instance of the class. /// + /// . /// . - public OpenTelemetryLoggerProvider(IServiceProvider serviceProvider) + public OpenTelemetryLoggerProvider(IOptionsMonitor options, IServiceProvider serviceProvider) : this( - serviceProvider?.GetRequiredService>().Value ?? throw new ArgumentNullException(nameof(serviceProvider)), - serviceProvider, + options?.CurrentValue ?? throw new ArgumentNullException(nameof(options)), + serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)), ownsServiceProvider: false) { } @@ -66,7 +67,7 @@ public OpenTelemetryLoggerProvider(IServiceProvider serviceProvider) /// Initializes a new instance of the class. /// /// . - [Obsolete("Call the OpenTelemetryLoggerProvider constructor which accepts IServiceProvider")] + [Obsolete("Call the OpenTelemetryLoggerProvider constructor which accepts IOptions & IServiceProvider or the OpenTelemetryLoggerProvider.Create helper method")] public OpenTelemetryLoggerProvider(IOptionsMonitor options) : this(options?.CurrentValue ?? throw new ArgumentNullException(nameof(options)), serviceProvider: null, ownsServiceProvider: false) { diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs index 0f27df11c3d..d19b566808f 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs @@ -51,7 +51,11 @@ public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder, Act Guard.ThrowIfNull(builder); builder.AddConfiguration(); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + + LoggerProviderOptions.RegisterProviderOptions(builder.Services); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton>( new DefaultOpenTelemetryLoggerOptionsConfigureOptions(builder.Services))); diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index 5f07ee7b06f..dfa96f4aa33 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -197,6 +197,46 @@ public void LoggerFactoryCreateAddOpenTelemetryWithProviderAndDisposeSpecifiedTe Assert.True(provider.Disposed); } + [Fact] + public void ServiceCollectionAddOpenTelemetryServicesAvailableTest() + { + int invocationCount = 0; + + var services = new ServiceCollection(); + + services.Configure(options => + { + invocationCount++; + + // Note: Order is important the way things are implemented. Services + // aren't available until after the registration in AddOpenTelemetry + // fires. + + Assert.Null(options.Services); + }); + + services.AddLogging(configure => + { + configure.AddOpenTelemetry(options => + { + invocationCount++; + Assert.NotNull(options.Services); + }); + }); + + services.Configure(options => + { + invocationCount++; + Assert.NotNull(options.Services); + }); + + using var serviceProvider = services.BuildServiceProvider(); + + var loggerFactory = serviceProvider.GetRequiredService(); + + Assert.Equal(3, invocationCount); + } + private sealed class WrappedOpenTelemetryLoggerProvider : OpenTelemetryLoggerProvider { public bool Disposed { get; private set; } From 9ee35f23fc8cb1ff8ed19be0beabc3afe62aae55 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 11:29:12 -0700 Subject: [PATCH 04/31] More fixes and more tests. --- .../Logs/OpenTelemetryLoggerOptions.cs | 23 +++++ .../Logs/OpenTelemetryLoggingExtensions.cs | 48 ++++++----- .../OpenTelemetryLoggingExtensionsTests.cs | 86 +++++++++++++++---- 3 files changed, 122 insertions(+), 35 deletions(-) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs index 2ec92718eea..8bc67189cbf 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Internal; using OpenTelemetry.Resources; @@ -148,5 +149,27 @@ public OpenTelemetryLoggerOptions Configure(Action()); + // Note: This will bind logger options element (eg "Logging:OpenTelemetry") to OpenTelemetryLoggerOptions LoggerProviderOptions.RegisterProviderOptions(builder.Services); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton>( - new DefaultOpenTelemetryLoggerOptionsConfigureOptions(builder.Services))); - if (configure != null) { - builder.Services.Configure(configure); + /* + * We do a two-phase configuration here. + * + * Step 1: Configure callback is first invoked immediately. This + * is to make "Services" available for extension authors to + * register additional dependencies into the collection if + * needed. + * + * Step 2: When ServiceProvider is built from "Services" and the + * LoggerFactory is created then the options pipeline runs and + * builds a new OpenTelemetryLoggerOptions from configuration + * and callbacks are executed. "Services" can no longer be + * modified in this phase because the ServiceProvider is already + * complete. We apply the inline options to the final instance + * to bridge this gap. + */ + + var options = new OpenTelemetryLoggerOptions + { + Services = builder.Services, + }; + configure(options); + + builder.Services.Configure(finalOptions => + { + options.ApplyTo(finalOptions); + }); } return builder; @@ -113,20 +136,5 @@ public static ILoggingBuilder AddOpenTelemetry( return builder; } - - private sealed class DefaultOpenTelemetryLoggerOptionsConfigureOptions : IConfigureOptions - { - private readonly IServiceCollection services; - - public DefaultOpenTelemetryLoggerOptionsConfigureOptions(IServiceCollection services) - { - this.services = services; - } - - public void Configure(OpenTelemetryLoggerOptions options) - { - options.Services = this.services; - } - } } } diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index dfa96f4aa33..7179642bec8 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -16,6 +16,7 @@ #nullable enable +using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Xunit; @@ -75,14 +76,16 @@ public void ServiceCollectionAddOpenTelemetryConfigureActionTests(int numberOfBu serviceCollection.Configure(OptionsCallback); } + Assert.NotNull(optionsInstance); + using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider(); + optionsInstance = null; + ILoggerFactory? loggerFactory = serviceProvider.GetService(); Assert.NotNull(loggerFactory); - Assert.NotNull(optionsInstance); - Assert.Equal(numberOfBuilderRegistrations, configureCallbackInvocations); Assert.Equal(numberOfOptionsRegistrations, optionsCallbackInvocations); @@ -94,7 +97,7 @@ void ConfigureCallback(OpenTelemetryLoggerOptions options) } else { - Assert.Equal(optionsInstance, options); + Assert.NotEqual(optionsInstance, options); } configureCallbackInvocations++; @@ -204,37 +207,78 @@ public void ServiceCollectionAddOpenTelemetryServicesAvailableTest() var services = new ServiceCollection(); + services.AddLogging(configure => + { + configure.AddOpenTelemetry(options => + { + invocationCount++; + Assert.NotNull(options.Services); + }); + }); + services.Configure(options => { invocationCount++; - // Note: Order is important the way things are implemented. Services - // aren't available until after the registration in AddOpenTelemetry - // fires. + // Note: Services are no longer available once OpenTelemetryLoggerOptions has been created Assert.Null(options.Services); }); + using var serviceProvider = services.BuildServiceProvider(); + + var loggerFactory = serviceProvider.GetRequiredService(); + + Assert.Equal(2, invocationCount); + } + + [Fact] + public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithoutRegistrationThrowsTest() + { + var services = new ServiceCollection(); + + services.AddLogging(configure => + { + // Note: This will throw because CustomProcessor has not been + // registered with services + + configure.AddOpenTelemetry(options => options.AddProcessor()); + }); + + using var serviceProvider = services.BuildServiceProvider(); + + Assert.Throws(() => serviceProvider.GetRequiredService()); + } + + [Fact] + public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithRegistrationTest() + { + var services = new ServiceCollection(); + services.AddLogging(configure => { configure.AddOpenTelemetry(options => { - invocationCount++; - Assert.NotNull(options.Services); + options.Services!.AddSingleton(); + + options.AddProcessor(); }); }); - services.Configure(options => + CustomProcessor? customProcessor = null; + + using (var serviceProvider = services.BuildServiceProvider()) { - invocationCount++; - Assert.NotNull(options.Services); - }); + var loggerFactory = serviceProvider.GetRequiredService(); - using var serviceProvider = services.BuildServiceProvider(); + customProcessor = serviceProvider.GetRequiredService(); - var loggerFactory = serviceProvider.GetRequiredService(); + loggerFactory.Dispose(); + + Assert.False(customProcessor.Disposed); + } - Assert.Equal(3, invocationCount); + Assert.True(customProcessor.Disposed); } private sealed class WrappedOpenTelemetryLoggerProvider : OpenTelemetryLoggerProvider @@ -248,4 +292,16 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } } + + private sealed class CustomProcessor : BaseProcessor + { + public bool Disposed { get; private set; } + + protected override void Dispose(bool disposing) + { + this.Disposed = true; + + base.Dispose(disposing); + } + } } From c0fe82391ae733b9806e7ef961e3e2ce2455a77e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 11:30:23 -0700 Subject: [PATCH 05/31] Tweak comments for clarity. --- .../Logs/OpenTelemetryLoggingExtensions.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs index e0ab3335b42..1db09f758d6 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs @@ -65,7 +65,15 @@ public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder, Act * is to make "Services" available for extension authors to * register additional dependencies into the collection if * needed. - * + */ + + var options = new OpenTelemetryLoggerOptions + { + Services = builder.Services, + }; + configure(options); + + /* * Step 2: When ServiceProvider is built from "Services" and the * LoggerFactory is created then the options pipeline runs and * builds a new OpenTelemetryLoggerOptions from configuration @@ -75,12 +83,6 @@ public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder, Act * to bridge this gap. */ - var options = new OpenTelemetryLoggerOptions - { - Services = builder.Services, - }; - configure(options); - builder.Services.Configure(finalOptions => { options.ApplyTo(finalOptions); From 5b4ffc107f0428052d16431c20a61f1b27c4cb8a Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 11:47:51 -0700 Subject: [PATCH 06/31] Added OpenTelemetryLoggerOptions.Services xml detail remarks. --- src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs index 8bc67189cbf..75cb33dda9f 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs @@ -20,6 +20,7 @@ using System.Collections.Generic; using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Internal; using OpenTelemetry.Resources; @@ -38,6 +39,14 @@ public class OpenTelemetryLoggerOptions /// Gets the where Logging services are /// configured. /// + /// + /// Note: are only available during the + /// application configuration phase. When using "Options" pattern via + /// or interfaces such + /// as will be + /// unavailable because "Options" are built after application services + /// have been configured. + /// public IServiceCollection? Services { get; internal set; } /// From a1fe108321115efbf27dcb1b2d9faeb06196747d Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 11:56:42 -0700 Subject: [PATCH 07/31] More tests. --- .../OpenTelemetryLoggingExtensionsTests.cs | 58 ++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index 7179642bec8..a9e3de5b27a 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -97,6 +97,7 @@ void ConfigureCallback(OpenTelemetryLoggerOptions options) } else { + // Note: In the callback phase each options instance is unique Assert.NotEqual(optionsInstance, options); } @@ -111,6 +112,7 @@ void OptionsCallback(OpenTelemetryLoggerOptions options) } else { + // Note: In the options phase each instance is the same Assert.Equal(optionsInstance, options); } @@ -250,16 +252,26 @@ public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithoutRe Assert.Throws(() => serviceProvider.GetRequiredService()); } - [Fact] - public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithRegistrationTest() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithRegistrationTests(bool registerOutside) { var services = new ServiceCollection(); + if (registerOutside) + { + services.AddSingleton(); + } + services.AddLogging(configure => { configure.AddOpenTelemetry(options => { - options.Services!.AddSingleton(); + if (!registerOutside) + { + options.Services!.AddSingleton(); + } options.AddProcessor(); }); @@ -281,6 +293,40 @@ public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithRegis Assert.True(customProcessor.Disposed); } + [Fact] + public void ServiceCollectionAddOpenTelemetryConfigureCallbackTest() + { + var services = new ServiceCollection(); + + services.AddSingleton(); + + CustomProcessor? customProcessor = null; + + services.AddLogging(configure => + { + configure.AddOpenTelemetry(options => + { + options.Configure((sp, provider) => + { + var testClass = sp.GetRequiredService(); + + customProcessor = new CustomProcessor + { + TestClass = testClass, + }; + + provider.AddProcessor(customProcessor); + }); + }); + }); + + using var serviceProvider = services.BuildServiceProvider(); + + var loggerFactory = serviceProvider.GetRequiredService(); + + Assert.NotNull(customProcessor?.TestClass); + } + private sealed class WrappedOpenTelemetryLoggerProvider : OpenTelemetryLoggerProvider { public bool Disposed { get; private set; } @@ -297,6 +343,8 @@ private sealed class CustomProcessor : BaseProcessor { public bool Disposed { get; private set; } + public TestClass? TestClass { get; set; } + protected override void Dispose(bool disposing) { this.Disposed = true; @@ -304,4 +352,8 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } } + + private sealed class TestClass + { + } } From d2ba768f6d12476f1e8281627ff8029b7a7f79c4 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 12:13:23 -0700 Subject: [PATCH 08/31] More tests. --- .../OpenTelemetryLoggingExtensionsTests.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index a9e3de5b27a..1da0c6f5d23 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -291,6 +291,8 @@ public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithRegis } Assert.True(customProcessor.Disposed); + + Assert.Equal(1, CustomProcessor.InstanceCount); } [Fact] @@ -327,6 +329,26 @@ public void ServiceCollectionAddOpenTelemetryConfigureCallbackTest() Assert.NotNull(customProcessor?.TestClass); } + [Fact] + public void ServiceCollectionAddOpenTelemetryExternalRegistrationTest() + { + var services = new ServiceCollection(); + + services.AddSingleton>(sp => new CustomProcessor()); + services.AddSingleton>(sp => new CustomProcessor()); + + services.AddLogging(configure => + { + configure.AddOpenTelemetry(); + }); + + using var serviceProvider = services.BuildServiceProvider(); + + var loggerFactory = serviceProvider.GetRequiredService(); + + Assert.Equal(2, CustomProcessor.InstanceCount); + } + private sealed class WrappedOpenTelemetryLoggerProvider : OpenTelemetryLoggerProvider { public bool Disposed { get; private set; } @@ -341,6 +363,13 @@ protected override void Dispose(bool disposing) private sealed class CustomProcessor : BaseProcessor { + public CustomProcessor() + { + InstanceCount++; + } + + public static int InstanceCount { get; private set; } + public bool Disposed { get; private set; } public TestClass? TestClass { get; set; } From a8f8238aa3b410f8bb31ebd30663878917a1a569 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 12:27:22 -0700 Subject: [PATCH 09/31] Test fix. --- .../Logs/OpenTelemetryLoggingExtensionsTests.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index 1da0c6f5d23..f40b9013054 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -257,6 +257,8 @@ public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithoutRe [InlineData(false)] public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithRegistrationTests(bool registerOutside) { + CustomProcessor.InstanceCount = 0; + var services = new ServiceCollection(); if (registerOutside) @@ -332,6 +334,8 @@ public void ServiceCollectionAddOpenTelemetryConfigureCallbackTest() [Fact] public void ServiceCollectionAddOpenTelemetryExternalRegistrationTest() { + CustomProcessor.InstanceCount = 0; + var services = new ServiceCollection(); services.AddSingleton>(sp => new CustomProcessor()); @@ -368,7 +372,7 @@ public CustomProcessor() InstanceCount++; } - public static int InstanceCount { get; private set; } + public static int InstanceCount { get; set; } public bool Disposed { get; private set; } From 6daf110eec6a8f351fc12b2f9faae9f9aad037a6 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 13:04:20 -0700 Subject: [PATCH 10/31] More tests. --- .../AssemblyInfo.cs | 1 + ...OpenTelemetryEventSourceLogEmitterTests.cs | 67 +++-------------- ...tSourceServiceCollectionExtensionsTests.cs | 63 ++++++++++++++++ .../TestEventSource.cs | 71 +++++++++++++++++++ 4 files changed, 144 insertions(+), 58 deletions(-) create mode 100644 test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceServiceCollectionExtensionsTests.cs create mode 100644 test/OpenTelemetry.Extensions.EventSource.Tests/TestEventSource.cs diff --git a/src/OpenTelemetry.Extensions.EventSource/AssemblyInfo.cs b/src/OpenTelemetry.Extensions.EventSource/AssemblyInfo.cs index a51a83d9d1d..1aa11097133 100644 --- a/src/OpenTelemetry.Extensions.EventSource/AssemblyInfo.cs +++ b/src/OpenTelemetry.Extensions.EventSource/AssemblyInfo.cs @@ -18,6 +18,7 @@ using System.Runtime.CompilerServices; [assembly: CLSCompliant(false)] +[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.EventSource.Tests" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] #if SIGNED diff --git a/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs index 0f58e4c5459..46f2b1fe3d8 100644 --- a/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs +++ b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs @@ -57,8 +57,8 @@ public void OpenTelemetryEventSourceLogEmitterDisposesProviderTests(bool dispose } [Theory] - [InlineData("OpenTelemetry.Extensions.EventSource.Tests", EventLevel.LogAlways, 2)] - [InlineData("OpenTelemetry.Extensions.EventSource.Tests", EventLevel.Warning, 1)] + [InlineData(TestEventSource.EventSourceName, EventLevel.LogAlways, 2)] + [InlineData(TestEventSource.EventSourceName, EventLevel.Warning, 1)] [InlineData("_invalid_", EventLevel.LogAlways, 0)] public void OpenTelemetryEventSourceLogEmitterFilterTests(string sourceName, EventLevel? eventLevel, int expectedNumberOfLogRecords) { @@ -98,7 +98,7 @@ public void OpenTelemetryEventSourceLogEmitterCapturesExistingSourceTest() using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( openTelemetryLoggerProvider, - (name) => name == "OpenTelemetry.Extensions.EventSource.Tests" ? EventLevel.LogAlways : null)) + (name) => name == TestEventSource.EventSourceName ? EventLevel.LogAlways : null)) { TestEventSource.Log.SimpleEvent(); } @@ -120,7 +120,7 @@ public void OpenTelemetryEventSourceLogEmitterSimpleEventTest() using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( openTelemetryLoggerProvider, - (name) => name == "OpenTelemetry.Extensions.EventSource.Tests" ? EventLevel.LogAlways : null)) + (name) => name == TestEventSource.EventSourceName ? EventLevel.LogAlways : null)) { TestEventSource.Log.SimpleEvent(); } @@ -143,7 +143,7 @@ public void OpenTelemetryEventSourceLogEmitterSimpleEventTest() Assert.Equal(ActivityTraceFlags.None, logRecord.TraceFlags); Assert.NotNull(logRecord.StateValues); - Assert.Contains(logRecord.StateValues, kvp => kvp.Key == "event_source.name" && (string?)kvp.Value == "OpenTelemetry.Extensions.EventSource.Tests"); + Assert.Contains(logRecord.StateValues, kvp => kvp.Key == "event_source.name" && (string?)kvp.Value == TestEventSource.EventSourceName); } [Fact] @@ -163,7 +163,7 @@ public void OpenTelemetryEventSourceLogEmitterSimpleEventWithActivityTest() using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( openTelemetryLoggerProvider, - (name) => name == "OpenTelemetry.Extensions.EventSource.Tests" ? EventLevel.LogAlways : null)) + (name) => name == TestEventSource.EventSourceName ? EventLevel.LogAlways : null)) { TestEventSource.Log.SimpleEvent(); } @@ -197,7 +197,7 @@ public void OpenTelemetryEventSourceLogEmitterComplexEventTest(bool formatMessag using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( openTelemetryLoggerProvider, - (name) => name == "OpenTelemetry.Extensions.EventSource.Tests" ? EventLevel.LogAlways : null)) + (name) => name == TestEventSource.EventSourceName ? EventLevel.LogAlways : null)) { TestEventSource.Log.ComplexEvent("Test_Message", 18); } @@ -229,7 +229,7 @@ public void OpenTelemetryEventSourceLogEmitterComplexEventTest(bool formatMessag Assert.Equal(ActivityTraceFlags.None, logRecord.TraceFlags); Assert.NotNull(logRecord.StateValues); - Assert.Contains(logRecord.StateValues, kvp => kvp.Key == "event_source.name" && (string?)kvp.Value == "OpenTelemetry.Extensions.EventSource.Tests"); + Assert.Contains(logRecord.StateValues, kvp => kvp.Key == "event_source.name" && (string?)kvp.Value == TestEventSource.EventSourceName); Assert.Contains(logRecord.StateValues, kvp => kvp.Key == "arg1" && (string?)kvp.Value == "Test_Message"); Assert.Contains(logRecord.StateValues, kvp => kvp.Key == "arg2" && (int?)kvp.Value == 18); } @@ -264,7 +264,7 @@ public void OpenTelemetryEventSourceLogEmitterActivityIdTest(bool enableTplListe using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( openTelemetryLoggerProvider, - (name) => name == "OpenTelemetry.Extensions.EventSource.Tests" ? EventLevel.LogAlways : null)) + (name) => name == TestEventSource.EventSourceName ? EventLevel.LogAlways : null)) { TestEventSource.Log.WorkStart(); @@ -303,55 +303,6 @@ protected override void Dispose(bool disposing) } } - [EventSource(Name = "OpenTelemetry.Extensions.EventSource.Tests")] - private sealed class TestEventSource : System.Diagnostics.Tracing.EventSource - { - public const int SimpleEventId = 1; - public const string SimpleEventMessage = "Warning event with no arguments."; - - public const int ComplexEventId = 2; - public const string ComplexEventMessage = "Information event with two arguments: '{0}' & '{1}'."; - public const string ComplexEventMessageStructured = "Information event with two arguments: '{arg1}' & '{arg2}'."; - - public static TestEventSource Log { get; } = new(); - - [Event(SimpleEventId, Message = SimpleEventMessage, Level = EventLevel.Warning)] - public void SimpleEvent() - { - this.WriteEvent(SimpleEventId); - } - - [Event(ComplexEventId, Message = ComplexEventMessage, Level = EventLevel.Informational)] - public void ComplexEvent(string arg1, int arg2) - { - this.WriteEvent(ComplexEventId, arg1, arg2); - } - - [Event(3, Level = EventLevel.Verbose)] - public void WorkStart() - { - this.WriteEvent(3); - } - - [Event(4, Level = EventLevel.Verbose)] - public void WorkStop() - { - this.WriteEvent(4); - } - - [Event(5, Level = EventLevel.Verbose)] - public void SubworkStart() - { - this.WriteEvent(5); - } - - [Event(6, Level = EventLevel.Verbose)] - public void SubworkStop() - { - this.WriteEvent(6); - } - } - private sealed class TplEventSourceListener : EventListener { private readonly List eventSources = new(); diff --git a/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceServiceCollectionExtensionsTests.cs b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceServiceCollectionExtensionsTests.cs new file mode 100644 index 00000000000..80502b693aa --- /dev/null +++ b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceServiceCollectionExtensionsTests.cs @@ -0,0 +1,63 @@ +// +// 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.Collections.Generic; +using System.Diagnostics.Tracing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; +using Xunit; + +namespace OpenTelemetry.Extensions.EventSource.Tests +{ + public class OpenTelemetryEventSourceServiceCollectionExtensionsTests + { + [Fact] + public void AddOpenTelemetryEventSourceLogEmitterTest() + { + var exportedItems = new List(); + + var services = new ServiceCollection(); + + services.AddLogging(configure => + { + configure.AddOpenTelemetry(options => options.AddInMemoryExporter(exportedItems)); + }); + + services.AddOpenTelemetryEventSourceLogEmitter( + (name) => name == TestEventSource.EventSourceName ? EventLevel.LogAlways : null); + + OpenTelemetryEventSourceServiceCollectionExtensions.EventSourceManager? eventSourceManager = null; + + using (var serviceProvider = services.BuildServiceProvider()) + { + var loggerFactory = serviceProvider.GetRequiredService(); + + eventSourceManager = serviceProvider.GetRequiredService(); + + Assert.Single(eventSourceManager.Emitters); + + TestEventSource.Log.SimpleEvent(); + } + + Assert.Single(exportedItems); + + Assert.Empty(eventSourceManager.Emitters); + } + } +} diff --git a/test/OpenTelemetry.Extensions.EventSource.Tests/TestEventSource.cs b/test/OpenTelemetry.Extensions.EventSource.Tests/TestEventSource.cs new file mode 100644 index 00000000000..aee8f12b888 --- /dev/null +++ b/test/OpenTelemetry.Extensions.EventSource.Tests/TestEventSource.cs @@ -0,0 +1,71 @@ +// +// 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.Diagnostics.Tracing; + +namespace OpenTelemetry.Extensions.EventSource.Tests +{ + [EventSource(Name = TestEventSource.EventSourceName)] + public sealed class TestEventSource : System.Diagnostics.Tracing.EventSource + { + public const string EventSourceName = "OpenTelemetry.Extensions.EventSource.Tests"; + + public const int SimpleEventId = 1; + public const string SimpleEventMessage = "Warning event with no arguments."; + + public const int ComplexEventId = 2; + public const string ComplexEventMessage = "Information event with two arguments: '{0}' & '{1}'."; + public const string ComplexEventMessageStructured = "Information event with two arguments: '{arg1}' & '{arg2}'."; + + public static TestEventSource Log { get; } = new(); + + [Event(SimpleEventId, Message = SimpleEventMessage, Level = EventLevel.Warning)] + public void SimpleEvent() + { + this.WriteEvent(SimpleEventId); + } + + [Event(ComplexEventId, Message = ComplexEventMessage, Level = EventLevel.Informational)] + public void ComplexEvent(string arg1, int arg2) + { + this.WriteEvent(ComplexEventId, arg1, arg2); + } + + [Event(3, Level = EventLevel.Verbose)] + public void WorkStart() + { + this.WriteEvent(3); + } + + [Event(4, Level = EventLevel.Verbose)] + public void WorkStop() + { + this.WriteEvent(4); + } + + [Event(5, Level = EventLevel.Verbose)] + public void SubworkStart() + { + this.WriteEvent(5); + } + + [Event(6, Level = EventLevel.Verbose)] + public void SubworkStop() + { + this.WriteEvent(6); + } + } +} From 71cdfbf2d5beb18ee5d5b9ed454d3e6d087250bb Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 13:51:12 -0700 Subject: [PATCH 11/31] Tests and fixes. --- .../Logs/OpenTelemetryLoggerOptions.cs | 54 ++++++++-- .../OpenTelemetryLoggingExtensionsTests.cs | 99 ++++++++++++++++++- 2 files changed, 142 insertions(+), 11 deletions(-) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs index 75cb33dda9f..5d4e644bc86 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs @@ -35,6 +35,14 @@ public class OpenTelemetryLoggerOptions internal ResourceBuilder ResourceBuilder = ResourceBuilder.CreateDefault(); internal List>? ConfigurationActions = new(); + internal const bool DefaultIncludeScopes = false; + internal const bool DefaultIncludeFormattedMessage = false; + internal const bool DefaultParseStateValues = false; + + internal bool? includeScopes; + internal bool? includeFormattedMessage; + internal bool? parseStateValues; + /// /// Gets the where Logging services are /// configured. @@ -47,21 +55,29 @@ public class OpenTelemetryLoggerOptions /// unavailable because "Options" are built after application services /// have been configured. /// - public IServiceCollection? Services { get; internal set; } + public IServiceCollection? Services{ get; internal set; } /// /// Gets or sets a value indicating whether or not log scopes should be /// included on generated s. Default value: /// False. /// - public bool IncludeScopes { get; set; } + public bool IncludeScopes + { + get => this.includeScopes ?? DefaultIncludeScopes; + set => this.includeScopes = value; + } /// /// Gets or sets a value indicating whether or not formatted log message /// should be included on generated s. Default /// value: False. /// - public bool IncludeFormattedMessage { get; set; } + public bool IncludeFormattedMessage + { + get => this.includeFormattedMessage ?? DefaultIncludeFormattedMessage; + set => this.includeFormattedMessage = value; + } /// /// Gets or sets a value indicating whether or not log state should be @@ -73,7 +89,11 @@ public class OpenTelemetryLoggerOptions /// langword="true"/> will always be . /// - public bool ParseStateValues { get; set; } + public bool ParseStateValues + { + get => this.parseStateValues ?? DefaultParseStateValues; + set => this.parseStateValues = value; + } /// /// Adds processor to the options. @@ -163,14 +183,28 @@ internal void ApplyTo(OpenTelemetryLoggerOptions other) { Debug.Assert(other != null, "other instance was null"); - other!.IncludeFormattedMessage = this.IncludeFormattedMessage; - other.IncludeScopes = this.IncludeScopes; - other.ParseStateValues = this.ParseStateValues; - other.ResourceBuilder = this.ResourceBuilder; + other!.ResourceBuilder = this.ResourceBuilder; + + if (this.includeFormattedMessage.HasValue) + { + other.includeFormattedMessage = this.includeFormattedMessage; + } + + if (this.includeScopes.HasValue) + { + other.includeScopes = this.includeScopes; + } + + if (this.parseStateValues.HasValue) + { + other.parseStateValues = this.parseStateValues; + } + + Debug.Assert(this.Processors != null && other.Processors != null, "Processors was null"); - foreach (var processor in this.Processors) + foreach (var processor in this.Processors!) { - other.Processors.Add(processor); + other.Processors!.Add(processor); } Debug.Assert(this.ConfigurationActions != null && other.ConfigurationActions != null, "ConfigurationActions was null"); diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index f40b9013054..a1d11e158f5 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -19,6 +19,7 @@ using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Xunit; namespace OpenTelemetry.Logs.Tests; @@ -353,6 +354,99 @@ public void ServiceCollectionAddOpenTelemetryExternalRegistrationTest() Assert.Equal(2, CustomProcessor.InstanceCount); } + [Fact] + public void ServiceCollectionAddOpenTelemetryOptionsOrderingTest() + { + int configureInvocationCount = 0; + + var services = new ServiceCollection(); + + OpenTelemetryLoggerProvider? provider = null; + + services.Configure(options => + { + // Note: This will be applied first to the final options + options.IncludeFormattedMessage = true; + options.IncludeScopes = true; + options.ParseStateValues = true; + + options.AddProcessor(new CustomProcessor(0)); + + options.Configure((sp, p) => + { + Assert.Null(provider); + provider = p; + configureInvocationCount++; + }); + }); + + services.AddLogging(configure => + { + configure.AddOpenTelemetry(options => + { + // Note: This will run first, but be applied second to the final options + options.IncludeFormattedMessage = false; + options.ParseStateValues = false; + + options.AddProcessor(new CustomProcessor(1)); + + options.Configure((sp, p) => + { + configureInvocationCount++; + + Assert.NotNull(provider); + Assert.Equal(provider, p); + }); + }); + }); + + services.Configure(options => + { + // Note: This will be applied last to the final options + options.ParseStateValues = true; + + options.AddProcessor(new CustomProcessor(2)); + + options.Configure((sp, p) => + { + configureInvocationCount++; + + Assert.NotNull(provider); + Assert.Equal(provider, p); + }); + }); + + using var serviceProvider = services.BuildServiceProvider(); + + var loggerFactory = serviceProvider.GetRequiredService(); + + Assert.NotNull(provider); + Assert.Equal(3, configureInvocationCount); + + var finalOptions = serviceProvider.GetRequiredService>().CurrentValue; + + Assert.False(finalOptions.IncludeFormattedMessage); + Assert.True(finalOptions.IncludeScopes); + Assert.True(finalOptions.ParseStateValues); + + var processor = provider!.Processor as CompositeProcessor; + + Assert.NotNull(processor); + + int count = 0; + var current = processor!.Head; + while (current != null) + { + var instance = current.Value as CustomProcessor; + Assert.Equal(count, instance?.Id); + + count++; + current = current.Next; + } + + Assert.Equal(3, count); + } + private sealed class WrappedOpenTelemetryLoggerProvider : OpenTelemetryLoggerProvider { public bool Disposed { get; private set; } @@ -367,13 +461,16 @@ protected override void Dispose(bool disposing) private sealed class CustomProcessor : BaseProcessor { - public CustomProcessor() + public CustomProcessor(int? id = null) { + this.Id = id; InstanceCount++; } public static int InstanceCount { get; set; } + public int? Id { get; } + public bool Disposed { get; private set; } public TestClass? TestClass { get; set; } From 0c73626fcd876761e45178f9480f3ac22e3d4ceb Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 13:53:29 -0700 Subject: [PATCH 12/31] Warning cleanup. --- .../Logs/OpenTelemetryLoggerOptions.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs index 5d4e644bc86..10d685b4052 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs @@ -35,13 +35,13 @@ public class OpenTelemetryLoggerOptions internal ResourceBuilder ResourceBuilder = ResourceBuilder.CreateDefault(); internal List>? ConfigurationActions = new(); - internal const bool DefaultIncludeScopes = false; - internal const bool DefaultIncludeFormattedMessage = false; - internal const bool DefaultParseStateValues = false; + private const bool DefaultIncludeScopes = false; + private const bool DefaultIncludeFormattedMessage = false; + private const bool DefaultParseStateValues = false; - internal bool? includeScopes; - internal bool? includeFormattedMessage; - internal bool? parseStateValues; + private bool? includeScopes; + private bool? includeFormattedMessage; + private bool? parseStateValues; /// /// Gets the where Logging services are @@ -55,7 +55,7 @@ public class OpenTelemetryLoggerOptions /// unavailable because "Options" are built after application services /// have been configured. /// - public IServiceCollection? Services{ get; internal set; } + public IServiceCollection? Services { get; internal set; } /// /// Gets or sets a value indicating whether or not log scopes should be From c5c93e03f5820f906ccc1b65b2d5ad0b72a6d044 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 16:06:14 -0700 Subject: [PATCH 13/31] Added resource test. --- .../OpenTelemetryLoggingExtensionsTests.cs | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index a1d11e158f5..84b71a23368 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -17,9 +17,11 @@ #nullable enable using System; +using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using OpenTelemetry.Resources; using Xunit; namespace OpenTelemetry.Logs.Tests; @@ -447,6 +449,55 @@ public void ServiceCollectionAddOpenTelemetryOptionsOrderingTest() Assert.Equal(3, count); } + [Fact] + public void ServiceCollectionAddOpenTelemetryResourceTest() + { + var services = new ServiceCollection(); + + OpenTelemetryLoggerProvider? provider = null; + + services.AddLogging(configure => + { + configure.AddOpenTelemetry(options => + { + options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Examples.LoggingExtensions")); + + options.Configure((sp, p) => provider = p); + }); + + configure.AddOpenTelemetry(options => + { + options.ConfigureResource(builder => builder.AddAttributes(new Dictionary { ["key1"] = "value1" })); + }); + }); + + services.Configure(options => + { + options.ConfigureResource(builder => builder.AddAttributes(new Dictionary { ["key2"] = "value2" })); + }); + + services.Configure(options => + { + options.ConfigureResource(builder => builder.AddAttributes(new Dictionary { ["key3"] = "value3" })); + }); + + using var serviceProvider = services.BuildServiceProvider(); + + var loggerFactory = serviceProvider.GetRequiredService(); + + Assert.NotNull(provider); + + var resource = provider!.Resource; + + Assert.NotNull(resource); + + Assert.Contains(resource.Attributes, kvp => kvp.Key == "service.name"); + Assert.Contains(resource.Attributes, kvp => kvp.Key == "service.instance.id"); + Assert.Contains(resource.Attributes, kvp => kvp.Key == "key1"); + Assert.Contains(resource.Attributes, kvp => kvp.Key == "key2"); + Assert.Contains(resource.Attributes, kvp => kvp.Key == "key3"); + } + private sealed class WrappedOpenTelemetryLoggerProvider : OpenTelemetryLoggerProvider { public bool Disposed { get; private set; } From 363236681fb20192f5615f154b45da896c43e2e9 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 16:07:46 -0700 Subject: [PATCH 14/31] Smooth out multiple resource configurations. --- .../Logs/OpenTelemetryLoggerOptions.cs | 23 ++++++++++++++++--- .../Logs/OpenTelemetryLoggerProvider.cs | 9 ++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs index 10d685b4052..1fb19841986 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs @@ -32,7 +32,7 @@ namespace OpenTelemetry.Logs public class OpenTelemetryLoggerOptions { internal readonly List> Processors = new(); - internal ResourceBuilder ResourceBuilder = ResourceBuilder.CreateDefault(); + internal ResourceBuilder? ResourceBuilder; internal List>? ConfigurationActions = new(); private const bool DefaultIncludeScopes = false; @@ -140,7 +140,14 @@ public OpenTelemetryLoggerOptions AddProcessor() public OpenTelemetryLoggerOptions SetResourceBuilder(ResourceBuilder resourceBuilder) { Guard.ThrowIfNull(resourceBuilder); + + if (this.ResourceBuilder != null) + { + throw new InvalidOperationException("Multiple ResourceBuilders cannot be set on options. Call ConfigureResource to chain resource configuration instead."); + } + this.ResourceBuilder = resourceBuilder; + return this; } @@ -153,7 +160,14 @@ public OpenTelemetryLoggerOptions SetResourceBuilder(ResourceBuilder resourceBui public OpenTelemetryLoggerOptions ConfigureResource(Action configure) { Guard.ThrowIfNull(configure, nameof(configure)); - configure(this.ResourceBuilder); + + this.Configure((sp, provider) => + { + Debug.Assert(this.ResourceBuilder != null, "ResourceBuilder was null"); + + configure(this.ResourceBuilder!); + }); + return this; } @@ -183,7 +197,10 @@ internal void ApplyTo(OpenTelemetryLoggerOptions other) { Debug.Assert(other != null, "other instance was null"); - other!.ResourceBuilder = this.ResourceBuilder; + if (this.ResourceBuilder != null) + { + other!.ResourceBuilder = this.ResourceBuilder; + } if (this.includeFormattedMessage.HasValue) { diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs index 2009fbf5eb4..c8e03dae9a0 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs @@ -100,8 +100,6 @@ private OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IService this.ownedServiceProvider = serviceProvider as ServiceProvider; } - this.Resource = options.ResourceBuilder.Build(); - // Step 1: Add any processors added to options. foreach (var processor in options.Processors) @@ -109,6 +107,11 @@ private OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IService this.AddProcessor(processor); } + if (options.ResourceBuilder == null) + { + options.ResourceBuilder = ResourceBuilder.CreateDefault(); + } + var configurationActions = options.ConfigurationActions; if (configurationActions?.Count > 0) { @@ -139,6 +142,8 @@ private OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IService this.AddProcessor(processor); } } + + this.Resource = options.ResourceBuilder.Build(); } internal IExternalScopeProvider? ScopeProvider { get; private set; } From e78734c6489394f145750fc7e26acefada37dfee Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 16:23:22 -0700 Subject: [PATCH 15/31] Resource chaining fix. --- src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs | 8 ++++---- .../Logs/OpenTelemetryLoggerProvider.cs | 12 +++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs index 1fb19841986..dae8f28e10e 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs @@ -143,7 +143,7 @@ public OpenTelemetryLoggerOptions SetResourceBuilder(ResourceBuilder resourceBui if (this.ResourceBuilder != null) { - throw new InvalidOperationException("Multiple ResourceBuilders cannot be set on options. Call ConfigureResource to chain resource configuration instead."); + throw new InvalidOperationException("Multiple ResourceBuilders cannot be set on options. Call ConfigureResource to chain resource configuration calls instead."); } this.ResourceBuilder = resourceBuilder; @@ -159,13 +159,13 @@ public OpenTelemetryLoggerOptions SetResourceBuilder(ResourceBuilder resourceBui /// Returns for chaining. public OpenTelemetryLoggerOptions ConfigureResource(Action configure) { - Guard.ThrowIfNull(configure, nameof(configure)); + Guard.ThrowIfNull(configure); this.Configure((sp, provider) => { - Debug.Assert(this.ResourceBuilder != null, "ResourceBuilder was null"); + Debug.Assert(provider.ResourceBuilder != null, "provider.ResourceBuilder was null"); - configure(this.ResourceBuilder!); + configure(provider.ResourceBuilder); }); return this; diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs index c8e03dae9a0..d3a2b4b527e 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs @@ -18,6 +18,7 @@ using System; using System.Collections; +using System.Diagnostics; using System.Threading; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -37,6 +38,7 @@ public class OpenTelemetryLoggerProvider : BaseProvider, ILoggerProvider, ISuppo internal readonly bool IncludeFormattedMessage; internal readonly bool ParseStateValues; internal BaseProcessor? Processor; + internal ResourceBuilder? ResourceBuilder; internal Resource Resource; private readonly ServiceProvider? ownedServiceProvider; private readonly Hashtable loggers = new(); @@ -98,6 +100,8 @@ private OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IService if (ownsServiceProvider) { this.ownedServiceProvider = serviceProvider as ServiceProvider; + + Debug.Assert(this.ownedServiceProvider != null, "ownedServiceProvider was null"); } // Step 1: Add any processors added to options. @@ -107,10 +111,7 @@ private OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IService this.AddProcessor(processor); } - if (options.ResourceBuilder == null) - { - options.ResourceBuilder = ResourceBuilder.CreateDefault(); - } + this.ResourceBuilder = options.ResourceBuilder ?? ResourceBuilder.CreateDefault(); var configurationActions = options.ConfigurationActions; if (configurationActions?.Count > 0) @@ -143,7 +144,8 @@ private OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IService } } - this.Resource = options.ResourceBuilder.Build(); + this.Resource = this.ResourceBuilder.Build(); + this.ResourceBuilder = null; } internal IExternalScopeProvider? ScopeProvider { get; private set; } From 8aeb08ef2faa1513f4aaa9657428d84e5c4e1df1 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 16:31:38 -0700 Subject: [PATCH 16/31] Remove throw for additional SetResourceBuilder calls. --- src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs index dae8f28e10e..5053093e9d6 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs @@ -141,11 +141,6 @@ public OpenTelemetryLoggerOptions SetResourceBuilder(ResourceBuilder resourceBui { Guard.ThrowIfNull(resourceBuilder); - if (this.ResourceBuilder != null) - { - throw new InvalidOperationException("Multiple ResourceBuilders cannot be set on options. Call ConfigureResource to chain resource configuration calls instead."); - } - this.ResourceBuilder = resourceBuilder; return this; From 570ab370f2bccab3eff2bc05e7836202257f070f Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 29 Jul 2022 16:40:06 -0700 Subject: [PATCH 17/31] Warning fixes. --- .../Logs/OpenTelemetryLoggerOptions.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs index 5053093e9d6..9851c7dae5b 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs @@ -160,7 +160,7 @@ public OpenTelemetryLoggerOptions ConfigureResource(Action conf { Debug.Assert(provider.ResourceBuilder != null, "provider.ResourceBuilder was null"); - configure(provider.ResourceBuilder); + configure(provider.ResourceBuilder!); }); return this; @@ -199,31 +199,31 @@ internal void ApplyTo(OpenTelemetryLoggerOptions other) if (this.includeFormattedMessage.HasValue) { - other.includeFormattedMessage = this.includeFormattedMessage; + other!.includeFormattedMessage = this.includeFormattedMessage; } if (this.includeScopes.HasValue) { - other.includeScopes = this.includeScopes; + other!.includeScopes = this.includeScopes; } if (this.parseStateValues.HasValue) { - other.parseStateValues = this.parseStateValues; + other!.parseStateValues = this.parseStateValues; } - Debug.Assert(this.Processors != null && other.Processors != null, "Processors was null"); + Debug.Assert(this.Processors != null && other!.Processors != null, "Processors was null"); foreach (var processor in this.Processors!) { - other.Processors!.Add(processor); + other!.Processors!.Add(processor); } - Debug.Assert(this.ConfigurationActions != null && other.ConfigurationActions != null, "ConfigurationActions was null"); + Debug.Assert(this.ConfigurationActions != null && other!.ConfigurationActions != null, "ConfigurationActions was null"); foreach (var configurationAction in this.ConfigurationActions!) { - other.ConfigurationActions!.Add(configurationAction); + other!.ConfigurationActions!.Add(configurationAction); } } } From 813bacc43b7f53cd6ba3e4b9413c2fdbdeac2762 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Sat, 30 Jul 2022 13:24:18 -0700 Subject: [PATCH 18/31] Moved OpenTelemetryEventSourceLogEmitter extension to OpenTelemetryLoggerOptions. --- .../netstandard2.0/PublicAPI.Unshipped.txt | 4 +- .../netstandard2.1/PublicAPI.Unshipped.txt | 4 +- ...etryEventSourceLoggerOptionsExtensions.cs} | 38 +++++++++---------- .../README.md | 10 ++--- ...ventSourceLoggerOptionsExtensionsTests.cs} | 18 +++++---- 5 files changed, 35 insertions(+), 39 deletions(-) rename src/OpenTelemetry.Extensions.EventSource/{OpenTelemetryEventSourceServiceCollectionExtensions.cs => OpenTelemetryEventSourceLoggerOptionsExtensions.cs} (59%) rename test/OpenTelemetry.Extensions.EventSource.Tests/{OpenTelemetryEventSourceServiceCollectionExtensionsTests.cs => OpenTelemetryEventSourceLoggerOptionsExtensionsTests.cs} (70%) diff --git a/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index a888e2bf8c6..bd136d125a8 100644 --- a/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,6 +1,6 @@ #nullable enable OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter.OpenTelemetryEventSourceLogEmitter(OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, System.Func! shouldListenToFunc, bool disposeProvider = true) -> void -OpenTelemetry.Logs.OpenTelemetryEventSourceServiceCollectionExtensions +OpenTelemetry.Logs.OpenTelemetryEventSourceLoggerOptionsExtensions override OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter.Dispose() -> void -static OpenTelemetry.Logs.OpenTelemetryEventSourceServiceCollectionExtensions.AddOpenTelemetryEventSourceLogEmitter(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! shouldListenToFunc) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Logs.OpenTelemetryEventSourceLoggerOptionsExtensions.AddEventSourceLogEmitter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Func! shouldListenToFunc) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index a888e2bf8c6..bd136d125a8 100644 --- a/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.EventSource/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,6 +1,6 @@ #nullable enable OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter.OpenTelemetryEventSourceLogEmitter(OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, System.Func! shouldListenToFunc, bool disposeProvider = true) -> void -OpenTelemetry.Logs.OpenTelemetryEventSourceServiceCollectionExtensions +OpenTelemetry.Logs.OpenTelemetryEventSourceLoggerOptionsExtensions override OpenTelemetry.Logs.OpenTelemetryEventSourceLogEmitter.Dispose() -> void -static OpenTelemetry.Logs.OpenTelemetryEventSourceServiceCollectionExtensions.AddOpenTelemetryEventSourceLogEmitter(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! shouldListenToFunc) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Logs.OpenTelemetryEventSourceLoggerOptionsExtensions.AddEventSourceLogEmitter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Func! shouldListenToFunc) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceServiceCollectionExtensions.cs b/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceLoggerOptionsExtensions.cs similarity index 59% rename from src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceServiceCollectionExtensions.cs rename to src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceLoggerOptionsExtensions.cs index 5224f0daf2e..8675b1a1bd9 100644 --- a/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceServiceCollectionExtensions.cs +++ b/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceLoggerOptionsExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,42 +24,40 @@ namespace OpenTelemetry.Logs { /// - /// Contains extension methods for registering OpenTelemetry EventSource utilities into application services. + /// Contains extension methods for registering OpenTelemetry EventSource utilities into logging services. /// - public static class OpenTelemetryEventSourceServiceCollectionExtensions + public static class OpenTelemetryEventSourceLoggerOptionsExtensions { /// - /// Registers into application services an - /// which will convert events into - /// OpenTelemetry logs. + /// Registers an which will convert events into OpenTelemetry logs. /// - /// . + /// . /// Callback function used to decide if /// events should be captured for a given . Return if no /// events should be captured. - /// Supplied for chaining calls. - public static IServiceCollection AddOpenTelemetryEventSourceLogEmitter( - this IServiceCollection services, + /// Supplied for + /// chaining calls. + public static OpenTelemetryLoggerOptions AddEventSourceLogEmitter( + this OpenTelemetryLoggerOptions options, Func shouldListenToFunc) { - Guard.ThrowIfNull(services); + Guard.ThrowIfNull(options); Guard.ThrowIfNull(shouldListenToFunc); - services.TryAddSingleton(); + options.Services.TryAddSingleton(); - services.Configure(options => + options.Configure((sp, provider) => { - options.Configure((sp, provider) => - { - var manager = sp.GetRequiredService(); + var manager = sp.GetRequiredService(); - manager.Emitters.Add( - new OpenTelemetryEventSourceLogEmitter(provider, shouldListenToFunc, disposeProvider: false)); - }); + manager.Emitters.Add( + new OpenTelemetryEventSourceLogEmitter(provider, shouldListenToFunc, disposeProvider: false)); }); - return services; + return options; } internal sealed class EventSourceManager : IDisposable diff --git a/src/OpenTelemetry.Extensions.EventSource/README.md b/src/OpenTelemetry.Extensions.EventSource/README.md index 994523416d4..c66044c8878 100644 --- a/src/OpenTelemetry.Extensions.EventSource/README.md +++ b/src/OpenTelemetry.Extensions.EventSource/README.md @@ -30,15 +30,11 @@ IHost host = Host.CreateDefaultBuilder(args) { options .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyService")) - .AddConsoleExporter(); + .AddConsoleExporter() + // Step 2: Register OpenTelemetryEventSourceLogEmitter to listen to events... + .AddEventSourceLogEmitter((name) => name == MyEventSource.Name ? EventLevel.Informational : null); }); }) - .ConfigureServices((hostContext, services) => - { - // Step 2: Register OpenTelemetryEventSourceLogEmitter to listen to events... - services.AddOpenTelemetryEventSourceLogEmitter( - (name) => name == MyEventSource.Name ? EventLevel.Informational : null); - }) .Build(); host.Run(); diff --git a/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceServiceCollectionExtensionsTests.cs b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLoggerOptionsExtensionsTests.cs similarity index 70% rename from test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceServiceCollectionExtensionsTests.cs rename to test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLoggerOptionsExtensionsTests.cs index 80502b693aa..0dea48dd69f 100644 --- a/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceServiceCollectionExtensionsTests.cs +++ b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLoggerOptionsExtensionsTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,7 +25,7 @@ namespace OpenTelemetry.Extensions.EventSource.Tests { - public class OpenTelemetryEventSourceServiceCollectionExtensionsTests + public class OpenTelemetryEventSourceLoggerOptionsExtensionsTests { [Fact] public void AddOpenTelemetryEventSourceLogEmitterTest() @@ -36,19 +36,21 @@ public void AddOpenTelemetryEventSourceLogEmitterTest() services.AddLogging(configure => { - configure.AddOpenTelemetry(options => options.AddInMemoryExporter(exportedItems)); + configure.AddOpenTelemetry(options => + { + options + .AddInMemoryExporter(exportedItems) + .AddEventSourceLogEmitter((name) => name == TestEventSource.EventSourceName ? EventLevel.LogAlways : null); + }); }); - services.AddOpenTelemetryEventSourceLogEmitter( - (name) => name == TestEventSource.EventSourceName ? EventLevel.LogAlways : null); - - OpenTelemetryEventSourceServiceCollectionExtensions.EventSourceManager? eventSourceManager = null; + OpenTelemetryEventSourceLoggerOptionsExtensions.EventSourceManager? eventSourceManager = null; using (var serviceProvider = services.BuildServiceProvider()) { var loggerFactory = serviceProvider.GetRequiredService(); - eventSourceManager = serviceProvider.GetRequiredService(); + eventSourceManager = serviceProvider.GetRequiredService(); Assert.Single(eventSourceManager.Emitters); From 6ffd623d9035ba2c3caaa55037b58dcb25022607 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Sat, 30 Jul 2022 15:25:16 -0700 Subject: [PATCH 19/31] Tweaks. --- src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs | 2 +- src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs index 9851c7dae5b..a491ae2f4ad 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs @@ -44,7 +44,7 @@ public class OpenTelemetryLoggerOptions private bool? parseStateValues; /// - /// Gets the where Logging services are + /// Gets the where logging services are /// configured. /// /// diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs index d3a2b4b527e..5411823a6de 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs @@ -171,7 +171,11 @@ public static OpenTelemetryLoggerProvider Create(Action>().CurrentValue; + + options.ApplyTo(finalOptions); + + return new OpenTelemetryLoggerProvider(finalOptions, serviceProvider, ownsServiceProvider: true); } return new OpenTelemetryLoggerProvider(options, serviceProvider: null, ownsServiceProvider: false); From fad5a6c0655e47aa000caf4d0ccb4ac5bf18190e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 1 Aug 2022 12:11:16 -0700 Subject: [PATCH 20/31] Switched from static to builder pattern. --- examples/LoggingExtensions/Program.cs | 15 ++--- ...metryEventSourceLoggerOptionsExtensions.cs | 2 +- .../README.md | 12 ++-- .../README.md | 10 ++-- .../.publicApi/net462/PublicAPI.Shipped.txt | 6 +- .../.publicApi/net462/PublicAPI.Unshipped.txt | 10 ++-- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 6 +- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 10 ++-- .../netstandard2.0/PublicAPI.Shipped.txt | 6 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 10 ++-- .../netstandard2.1/PublicAPI.Shipped.txt | 6 +- .../netstandard2.1/PublicAPI.Unshipped.txt | 10 ++-- src/OpenTelemetry/CHANGELOG.md | 4 +- .../Logs/OpenTelemetryLoggerProvider.cs | 46 +------------- .../Logs/OpenTelemetryLoggingExtensions.cs | 8 ++- .../OpenTelemetryLoggerOptions.cs | 58 ++++++++++++------ .../OpenTelemetryLoggerOptionsExtensions.cs | 45 ++++++++++++++ .../Options/OpenTelemetryLoggerOptionsSdk.cs | 60 +++++++++++++++++++ src/OpenTelemetry/Sdk.cs | 36 +++++++++++ ...OpenTelemetryEventSourceLogEmitterTests.cs | 51 +++++++--------- .../OpenTelemetrySerilogSinkTests.cs | 56 ++++++++--------- .../Logs/LogEmitterTests.cs | 28 ++++----- .../Logs/OpenTelemetryLoggerProviderTests.cs | 4 +- .../OpenTelemetryLoggingExtensionsTests.cs | 10 ++-- 24 files changed, 310 insertions(+), 199 deletions(-) rename src/OpenTelemetry/Logs/{ => Options}/OpenTelemetryLoggerOptions.cs (83%) create mode 100644 src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsExtensions.cs create mode 100644 src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs diff --git a/examples/LoggingExtensions/Program.cs b/examples/LoggingExtensions/Program.cs index 7ab7259a49b..7abc315e582 100644 --- a/examples/LoggingExtensions/Program.cs +++ b/examples/LoggingExtensions/Program.cs @@ -16,19 +16,16 @@ using System.Diagnostics.Tracing; using Examples.LoggingExtensions; +using OpenTelemetry; using OpenTelemetry.Logs; using OpenTelemetry.Resources; using Serilog; -var resourceBuilder = ResourceBuilder.CreateDefault().AddService("Examples.LoggingExtensions"); - -var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => -{ - options.IncludeFormattedMessage = true; - options - .SetResourceBuilder(resourceBuilder) - .AddConsoleExporter(); -}); +var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder( + options => options.IncludeFormattedMessage = true) + .ConfigureResource(builder => builder.AddService("Examples.LoggingExtensions")) + .AddConsoleExporter() + .Build(); // Creates an OpenTelemetryEventSourceLogEmitter for routing ExampleEventSource // events into logs diff --git a/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceLoggerOptionsExtensions.cs b/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceLoggerOptionsExtensions.cs index 8675b1a1bd9..ccd4b439016 100644 --- a/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceLoggerOptionsExtensions.cs +++ b/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceLoggerOptionsExtensions.cs @@ -49,7 +49,7 @@ public static OpenTelemetryLoggerOptions AddEventSourceLogEmitter( options.Services.TryAddSingleton(); - options.Configure((sp, provider) => + options.ConfigureProvider((sp, provider) => { var manager = sp.GetRequiredService(); diff --git a/src/OpenTelemetry.Extensions.EventSource/README.md b/src/OpenTelemetry.Extensions.EventSource/README.md index c66044c8878..b88f146a0eb 100644 --- a/src/OpenTelemetry.Extensions.EventSource/README.md +++ b/src/OpenTelemetry.Extensions.EventSource/README.md @@ -29,7 +29,7 @@ IHost host = Host.CreateDefaultBuilder(args) builder.AddOpenTelemetry(options => { options - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyService")) + .ConfigureResource(builder => builder.AddService("MyService")) .AddConsoleExporter() // Step 2: Register OpenTelemetryEventSourceLogEmitter to listen to events... .AddEventSourceLogEmitter((name) => name == MyEventSource.Name ? EventLevel.Informational : null); @@ -44,12 +44,10 @@ IHost host = Host.CreateDefaultBuilder(args) ```csharp // Step 1: Configure OpenTelemetryLoggerProvider... -var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => -{ - options - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyService")) - .AddConsoleExporter(); -}); +var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .ConfigureResource(builder => builder.AddService("MyService")) + .AddConsoleExporter() + .Build(); // Step 2: Create OpenTelemetryEventSourceLogEmitter to listen to events... using var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( diff --git a/src/OpenTelemetry.Extensions.Serilog/README.md b/src/OpenTelemetry.Extensions.Serilog/README.md index c7ec8a020b6..2d0c837bfbb 100644 --- a/src/OpenTelemetry.Extensions.Serilog/README.md +++ b/src/OpenTelemetry.Extensions.Serilog/README.md @@ -17,12 +17,10 @@ dotnet add package OpenTelemetry.Extensions.Serilog --prerelease ```csharp // Step 1: Configure OpenTelemetryLoggerProvider... -var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => -{ - options - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyService")) - .AddConsoleExporter(); -}); +var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .ConfigureResource(builder => builder.AddService("MyService")) + .AddConsoleExporter() + .Build(); // Step 2: Register OpenTelemetry sink with Serilog... Log.Logger = new LoggerConfiguration() diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt index afa4f5a68a7..352877fe2fe 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt @@ -94,9 +94,9 @@ readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExpo ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddEnvironmentVariableDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddService(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, string serviceName, string serviceNamespace = null, string serviceVersion = null, bool autoGenerateServiceInstanceId = true, string serviceInstanceId = null) -> OpenTelemetry.Resources.ResourceBuilder ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddTelemetrySdk(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder -~static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Sdk.CreateTracerProviderBuilder() -> OpenTelemetry.Trace.TracerProviderBuilder -~static OpenTelemetry.Sdk.SetDefaultTextMapPropagator(OpenTelemetry.Context.Propagation.TextMapPropagator textMapPropagator) -> void +static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Sdk.CreateTracerProviderBuilder() -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Sdk.SetDefaultTextMapPropagator(OpenTelemetry.Context.Propagation.TextMapPropagator! textMapPropagator) -> void ~static OpenTelemetry.SuppressInstrumentationScope.Begin(bool value = true) -> System.IDisposable ~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, OpenTelemetry.BaseProcessor processor) -> OpenTelemetry.Trace.TracerProviderBuilder ~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.Build(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProvider diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt index a80e6e807ff..caf43aedf78 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt @@ -8,18 +8,20 @@ OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Configure(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection? +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureServices(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +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 *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor! options, System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! -static OpenTelemetry.Logs.OpenTelemetryLoggerProvider.Create(System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! +static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! +static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Sdk.CreateLoggerProviderBuilder(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! ~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 diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt index afa4f5a68a7..352877fe2fe 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -94,9 +94,9 @@ readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExpo ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddEnvironmentVariableDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddService(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, string serviceName, string serviceNamespace = null, string serviceVersion = null, bool autoGenerateServiceInstanceId = true, string serviceInstanceId = null) -> OpenTelemetry.Resources.ResourceBuilder ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddTelemetrySdk(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder -~static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Sdk.CreateTracerProviderBuilder() -> OpenTelemetry.Trace.TracerProviderBuilder -~static OpenTelemetry.Sdk.SetDefaultTextMapPropagator(OpenTelemetry.Context.Propagation.TextMapPropagator textMapPropagator) -> void +static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Sdk.CreateTracerProviderBuilder() -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Sdk.SetDefaultTextMapPropagator(OpenTelemetry.Context.Propagation.TextMapPropagator! textMapPropagator) -> void ~static OpenTelemetry.SuppressInstrumentationScope.Begin(bool value = true) -> System.IDisposable ~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, OpenTelemetry.BaseProcessor processor) -> OpenTelemetry.Trace.TracerProviderBuilder ~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.Build(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProvider diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt index a80e6e807ff..caf43aedf78 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -8,18 +8,20 @@ OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Configure(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection? +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureServices(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +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 *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor! options, System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! -static OpenTelemetry.Logs.OpenTelemetryLoggerProvider.Create(System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! +static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! +static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Sdk.CreateLoggerProviderBuilder(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! ~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 diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index afa4f5a68a7..352877fe2fe 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -94,9 +94,9 @@ readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExpo ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddEnvironmentVariableDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddService(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, string serviceName, string serviceNamespace = null, string serviceVersion = null, bool autoGenerateServiceInstanceId = true, string serviceInstanceId = null) -> OpenTelemetry.Resources.ResourceBuilder ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddTelemetrySdk(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder -~static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Sdk.CreateTracerProviderBuilder() -> OpenTelemetry.Trace.TracerProviderBuilder -~static OpenTelemetry.Sdk.SetDefaultTextMapPropagator(OpenTelemetry.Context.Propagation.TextMapPropagator textMapPropagator) -> void +static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Sdk.CreateTracerProviderBuilder() -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Sdk.SetDefaultTextMapPropagator(OpenTelemetry.Context.Propagation.TextMapPropagator! textMapPropagator) -> void ~static OpenTelemetry.SuppressInstrumentationScope.Begin(bool value = true) -> System.IDisposable ~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, OpenTelemetry.BaseProcessor processor) -> OpenTelemetry.Trace.TracerProviderBuilder ~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.Build(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProvider diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 751cc2ab753..95cd98ecf76 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -8,18 +8,20 @@ OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Configure(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection? +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureServices(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +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 OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor! options, System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! -static OpenTelemetry.Logs.OpenTelemetryLoggerProvider.Create(System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! +static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! +static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Sdk.CreateLoggerProviderBuilder(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! ~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 diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt index afa4f5a68a7..352877fe2fe 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt @@ -94,9 +94,9 @@ readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExpo ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddEnvironmentVariableDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddService(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, string serviceName, string serviceNamespace = null, string serviceVersion = null, bool autoGenerateServiceInstanceId = true, string serviceInstanceId = null) -> OpenTelemetry.Resources.ResourceBuilder ~static OpenTelemetry.Resources.ResourceBuilderExtensions.AddTelemetrySdk(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Resources.ResourceBuilder -~static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Sdk.CreateTracerProviderBuilder() -> OpenTelemetry.Trace.TracerProviderBuilder -~static OpenTelemetry.Sdk.SetDefaultTextMapPropagator(OpenTelemetry.Context.Propagation.TextMapPropagator textMapPropagator) -> void +static OpenTelemetry.Sdk.CreateMeterProviderBuilder() -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Sdk.CreateTracerProviderBuilder() -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Sdk.SetDefaultTextMapPropagator(OpenTelemetry.Context.Propagation.TextMapPropagator! textMapPropagator) -> void ~static OpenTelemetry.SuppressInstrumentationScope.Begin(bool value = true) -> System.IDisposable ~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, OpenTelemetry.BaseProcessor processor) -> OpenTelemetry.Trace.TracerProviderBuilder ~static OpenTelemetry.Trace.TracerProviderBuilderExtensions.Build(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProvider diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index a80e6e807ff..caf43aedf78 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -8,18 +8,20 @@ OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Configure(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -OpenTelemetry.Logs.OpenTelemetryLoggerOptions.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection? +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureServices(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +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 *REMOVED*static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure = null) -> Microsoft.Extensions.Logging.ILoggingBuilder! -OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor! options, System.IServiceProvider! serviceProvider) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, OpenTelemetry.Logs.OpenTelemetryLoggerProvider! openTelemetryLoggerProvider, bool disposeProvider) -> Microsoft.Extensions.Logging.ILoggingBuilder! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! -static OpenTelemetry.Logs.OpenTelemetryLoggerProvider.Create(System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! +static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! +static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Sdk.CreateLoggerProviderBuilder(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! ~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 diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 32406f3a4d9..ede63b8d190 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -35,8 +35,8 @@ `OpenTelemetryLoggerProvider` directly ([#3489](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3489)) -* Added support for dependency injection scenarios when configuring - `OpenTelemetryLoggerProvider` +* Added `Sdk.CreateLoggerProviderBuilder` method and support for dependency + injection scenarios when configuring `OpenTelemetryLoggerProvider` ([#3504](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3504)) ## 1.3.0 diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs index 5411823a6de..c41fdd4e5b6 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs @@ -56,20 +56,7 @@ static OpenTelemetryLoggerProvider() /// Initializes a new instance of the class. /// /// . - /// . - public OpenTelemetryLoggerProvider(IOptionsMonitor options, IServiceProvider serviceProvider) - : this( - options?.CurrentValue ?? throw new ArgumentNullException(nameof(options)), - serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)), - ownsServiceProvider: false) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// . - [Obsolete("Call the OpenTelemetryLoggerProvider constructor which accepts IOptions & IServiceProvider or the OpenTelemetryLoggerProvider.Create helper method")] + [Obsolete("Use the Sdk.CreateLoggerProviderBuilder method instead")] public OpenTelemetryLoggerProvider(IOptionsMonitor options) : this(options?.CurrentValue ?? throw new ArgumentNullException(nameof(options)), serviceProvider: null, ownsServiceProvider: false) { @@ -89,7 +76,7 @@ internal OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options) { } - private OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IServiceProvider? serviceProvider, bool ownsServiceProvider) + internal OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IServiceProvider? serviceProvider, bool ownsServiceProvider) { Guard.ThrowIfNull(options); @@ -152,35 +139,6 @@ private OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IService internal ILogRecordPool LogRecordPool => this.threadStaticPool ?? LogRecordSharedPool.Current; - /// - /// Create a instance. - /// - /// Configuration callback. - /// . - public static OpenTelemetryLoggerProvider Create(Action? configure = null) - { - OpenTelemetryLoggerOptions options = new(); - - if (configure != null) - { - ServiceCollection services = new ServiceCollection(); - - options.Services = services; - - configure.Invoke(options); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - var finalOptions = serviceProvider.GetRequiredService>().CurrentValue; - - options.ApplyTo(finalOptions); - - return new OpenTelemetryLoggerProvider(finalOptions, serviceProvider, ownsServiceProvider: true); - } - - return new OpenTelemetryLoggerProvider(options, serviceProvider: null, ownsServiceProvider: false); - } - /// void ISupportExternalScope.SetScopeProvider(IExternalScopeProvider scopeProvider) { diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs index 1db09f758d6..4faa98d9ad4 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs @@ -21,6 +21,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Configuration; +using Microsoft.Extensions.Options; using OpenTelemetry.Internal; using OpenTelemetry.Logs; @@ -51,7 +52,12 @@ public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder, Act builder.AddConfiguration(); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton(sp => + { + var options = sp.GetRequiredService>().CurrentValue; + + return new OpenTelemetryLoggerProvider(options, sp, ownsServiceProvider: false); + })); // Note: This will bind logger options element (eg "Logging:OpenTelemetry") to OpenTelemetryLoggerOptions LoggerProviderOptions.RegisterProviderOptions(builder.Services); diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs similarity index 83% rename from src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs rename to src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs index a491ae2f4ad..b02c1b8dc8d 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs @@ -34,6 +34,7 @@ public class OpenTelemetryLoggerOptions internal readonly List> Processors = new(); internal ResourceBuilder? ResourceBuilder; internal List>? ConfigurationActions = new(); + internal IServiceCollection? Services; private const bool DefaultIncludeScopes = false; private const bool DefaultIncludeFormattedMessage = false; @@ -43,20 +44,6 @@ public class OpenTelemetryLoggerOptions private bool? includeFormattedMessage; private bool? parseStateValues; - /// - /// Gets the where logging services are - /// configured. - /// - /// - /// Note: are only available during the - /// application configuration phase. When using "Options" pattern via - /// or interfaces such - /// as will be - /// unavailable because "Options" are built after application services - /// have been configured. - /// - public IServiceCollection? Services { get; internal set; } - /// /// Gets or sets a value indicating whether or not log scopes should be /// included on generated s. Default value: @@ -123,7 +110,7 @@ public OpenTelemetryLoggerOptions AddProcessor(BaseProcessor processo public OpenTelemetryLoggerOptions AddProcessor() where T : BaseProcessor { - return this.Configure((sp, provider) => + return this.ConfigureProvider((sp, provider) => { provider.AddProcessor(sp.GetRequiredService()); }); @@ -152,11 +139,12 @@ public OpenTelemetryLoggerOptions SetResourceBuilder(ResourceBuilder resourceBui /// /// An action which modifies the provided in-place. /// Returns for chaining. - public OpenTelemetryLoggerOptions ConfigureResource(Action configure) + public OpenTelemetryLoggerOptions ConfigureResource( + Action configure) { Guard.ThrowIfNull(configure); - this.Configure((sp, provider) => + this.ConfigureProvider((sp, provider) => { Debug.Assert(provider.ResourceBuilder != null, "provider.ResourceBuilder was null"); @@ -166,6 +154,37 @@ public OpenTelemetryLoggerOptions ConfigureResource(Action conf return this; } + /// + /// Register a callback action to configure the where logging services are configured. + /// + /// + /// Note: Logging services are only available during the application + /// configuration phase. When using "Options" pattern via or interfaces such as + /// logging services will be + /// unavailable because "Options" are built after application services + /// have been configured. + /// + /// Configuration callback. + /// The supplied for chaining. + public OpenTelemetryLoggerOptions ConfigureServices( + Action configure) + { + Guard.ThrowIfNull(configure); + + var services = this.Services; + + if (services == null) + { + throw new NotSupportedException("Services cannot be configured outside of application configuration phase."); + } + + configure(services); + + return this; + } + /// /// Register a callback action to configure the once the application conf /// /// Configuration callback. /// The supplied for chaining. - public OpenTelemetryLoggerOptions Configure(Action configure) + public OpenTelemetryLoggerOptions ConfigureProvider( + Action configure) { Guard.ThrowIfNull(configure); var configurationActions = this.ConfigurationActions; if (configurationActions == null) { - throw new InvalidOperationException("Configuration actions cannot be registered on options after OpenTelemetryLoggerProvider has been created."); + throw new NotSupportedException("Configuration actions cannot be registered on options after OpenTelemetryLoggerProvider has been created."); } configurationActions.Add(configure); diff --git a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsExtensions.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsExtensions.cs new file mode 100644 index 00000000000..eb613e2dee3 --- /dev/null +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsExtensions.cs @@ -0,0 +1,45 @@ +// +// 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.Internal; + +namespace OpenTelemetry.Logs; + +/// +/// Contains extension methods for the class. +/// +public static class OpenTelemetryLoggerOptionsExtensions +{ + /// + /// Run the given actions to initialize the . + /// + /// . + /// . + public static OpenTelemetryLoggerProvider Build(this OpenTelemetryLoggerOptions options) + { + Guard.ThrowIfNull(options); + + if (options is not OpenTelemetryLoggerOptionsSdk openTelemetryLoggerOptionsSdk) + { + throw new NotSupportedException("Build is only supported on options instances created using the Sdk.CreateLoggerProviderBuilder method."); + } + + return openTelemetryLoggerOptionsSdk.Build(); + } +} diff --git a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs new file mode 100644 index 00000000000..c12592ab3f3 --- /dev/null +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs @@ -0,0 +1,60 @@ +// +// 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 Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace OpenTelemetry.Logs; + +internal sealed class OpenTelemetryLoggerOptionsSdk : OpenTelemetryLoggerOptions +{ + public OpenTelemetryLoggerOptionsSdk(Action? configure) + { + var services = new ServiceCollection(); + + services.AddOptions(); + + this.Services = services; + + configure?.Invoke(this); + } + + public OpenTelemetryLoggerProvider Build() + { + var services = this.Services; + + if (services == null) + { + throw new NotSupportedException("LoggerProviderBuilder build method cannot be called multiple times."); + } + + this.Services = null; + + var serviceProvider = services.BuildServiceProvider(); + + var finalOptions = serviceProvider.GetRequiredService>().CurrentValue; + + this.ApplyTo(finalOptions); + + return new OpenTelemetryLoggerProvider( + finalOptions, + serviceProvider, + ownsServiceProvider: true); + } +} diff --git a/src/OpenTelemetry/Sdk.cs b/src/OpenTelemetry/Sdk.cs index 72b5e8e5913..313e7e1e02c 100644 --- a/src/OpenTelemetry/Sdk.cs +++ b/src/OpenTelemetry/Sdk.cs @@ -14,9 +14,13 @@ // limitations under the License. // +#nullable enable + +using System; using System.Diagnostics; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Internal; +using OpenTelemetry.Logs; using OpenTelemetry.Metrics; using OpenTelemetry.Trace; @@ -51,9 +55,41 @@ static Sdk() /// TextMapPropagator to be set as default. public static void SetDefaultTextMapPropagator(TextMapPropagator textMapPropagator) { + Guard.ThrowIfNull(textMapPropagator); + Propagators.DefaultTextMapPropagator = textMapPropagator; } + /// + /// Creates a which is used to build + /// an . In a typical application, a single + /// is created at application startup and disposed + /// at application shutdown. It is important to ensure that the provider is not + /// disposed too early. + /// + /// instance, which is used to build a . + public static OpenTelemetryLoggerOptions CreateLoggerProviderBuilder() + { + return new OpenTelemetryLoggerOptionsSdk(configure: null); + } + + /// + /// Creates a which is used to build + /// an . In a typical application, a single + /// is created at application startup and disposed + /// at application shutdown. It is important to ensure that the provider is not + /// disposed too early. + /// + /// Configuration action. + /// instance, which is used to build a . + public static OpenTelemetryLoggerOptions CreateLoggerProviderBuilder( + Action configure) + { + Guard.ThrowIfNull(configure); + + return new OpenTelemetryLoggerOptionsSdk(configure); + } + /// /// Creates a which is used to build /// a . In a typical application, a single diff --git a/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs index 46f2b1fe3d8..07f8ca5b920 100644 --- a/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs +++ b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs @@ -36,10 +36,9 @@ public void OpenTelemetryEventSourceLogEmitterDisposesProviderTests(bool dispose var disposeTrackingProcessor = new DisposeTrackingProcessor(); #pragma warning restore CA2000 // Dispose objects before losing scope - using (var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddProcessor(disposeTrackingProcessor); - })) + using (var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddProcessor(disposeTrackingProcessor) + .Build()) { using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( openTelemetryLoggerProvider, @@ -65,10 +64,9 @@ public void OpenTelemetryEventSourceLogEmitterFilterTests(string sourceName, Eve List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( @@ -88,10 +86,9 @@ public void OpenTelemetryEventSourceLogEmitterCapturesExistingSourceTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope TestEventSource.Log.SimpleEvent(); @@ -112,10 +109,9 @@ public void OpenTelemetryEventSourceLogEmitterSimpleEventTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( @@ -155,10 +151,9 @@ public void OpenTelemetryEventSourceLogEmitterSimpleEventWithActivityTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( @@ -188,11 +183,10 @@ public void OpenTelemetryEventSourceLogEmitterComplexEventTest(bool formatMessag List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.IncludeFormattedMessage = formatMessage; - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder( + options => options.IncludeFormattedMessage = formatMessage) + .AddInMemoryExporter(exportedItems) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( @@ -256,10 +250,9 @@ public void OpenTelemetryEventSourceLogEmitterActivityIdTest(bool enableTplListe List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope using (var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter( diff --git a/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs b/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs index c20ca122543..8173867340c 100644 --- a/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs +++ b/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs @@ -37,10 +37,9 @@ public void SerilogDisposesProviderTests(bool dispose) var disposeTrackingProcessor = new DisposeTrackingProcessor(); #pragma warning restore CA2000 // Dispose objects before losing scope - using (var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddProcessor(disposeTrackingProcessor); - })) + using (var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddProcessor(disposeTrackingProcessor) + .Build()) { Log.Logger = new LoggerConfiguration() .WriteTo.OpenTelemetry(openTelemetryLoggerProvider, disposeProvider: dispose) @@ -62,12 +61,14 @@ public void SerilogBasicLogTests(bool includeFormattedMessage) List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.IncludeFormattedMessage = includeFormattedMessage; - - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder( + options => + { + options.IncludeFormattedMessage = includeFormattedMessage; + + options.AddInMemoryExporter(exportedItems); + }) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope Log.Logger = new LoggerConfiguration() @@ -115,10 +116,9 @@ public void SerilogBasicLogWithActivityTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope Log.Logger = new LoggerConfiguration() @@ -147,10 +147,9 @@ public void SerilogCategoryNameTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope Log.Logger = new LoggerConfiguration() @@ -177,10 +176,9 @@ public void SerilogComplexMessageTemplateTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope Log.Logger = new LoggerConfiguration() @@ -210,10 +208,9 @@ public void SerilogArrayMessageTemplateTest() List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope Log.Logger = new LoggerConfiguration() @@ -249,10 +246,9 @@ public void SerilogExceptionTest() InvalidOperationException ex = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope Log.Logger = new LoggerConfiguration() diff --git a/test/OpenTelemetry.Tests/Logs/LogEmitterTests.cs b/test/OpenTelemetry.Tests/Logs/LogEmitterTests.cs index fcb11b8d8e4..e8da01b66f0 100644 --- a/test/OpenTelemetry.Tests/Logs/LogEmitterTests.cs +++ b/test/OpenTelemetry.Tests/Logs/LogEmitterTests.cs @@ -29,10 +29,9 @@ public void LogEmitterBasicTest() { var exportedItems = new List(); - using var provider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + using var provider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); var logEmitter = provider.CreateEmitter(); @@ -82,10 +81,9 @@ public void LogEmitterFromActivityTest() { var exportedItems = new List(); - using var provider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + using var provider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); var logEmitter = provider.CreateEmitter(); @@ -117,10 +115,9 @@ public void LogEmitterLocalToUtcTimestampTest() { var exportedItems = new List(); - using var provider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + using var provider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); var logEmitter = provider.CreateEmitter(); @@ -148,10 +145,9 @@ public void LogEmitterUnspecifiedTimestampTest() { var exportedItems = new List(); - using var provider = OpenTelemetryLoggerProvider.Create(options => - { - options.AddInMemoryExporter(exportedItems); - }); + using var provider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); var logEmitter = provider.CreateEmitter(); diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs index 41f8772180e..5fe51af8aa6 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs @@ -43,7 +43,7 @@ public void ConfigureCtorTests() { OpenTelemetryLoggerOptions defaults = new(); - using OpenTelemetryLoggerProvider provider = OpenTelemetryLoggerProvider.Create(options => + using OpenTelemetryLoggerProvider provider = Sdk.CreateLoggerProviderBuilder(options => { options.IncludeScopes = !defaults.IncludeScopes; options.IncludeFormattedMessage = !defaults.IncludeFormattedMessage; @@ -54,7 +54,7 @@ public void ConfigureCtorTests() .AddAttributes(new[] { new KeyValuePair("key1", "value1") })); options.AddInMemoryExporter(new List()); - }); + }).Build(); Assert.Equal(!defaults.IncludeScopes, provider.IncludeScopes); Assert.Equal(!defaults.IncludeFormattedMessage, provider.IncludeFormattedMessage); diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index 84b71a23368..e5488483568 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -313,7 +313,7 @@ public void ServiceCollectionAddOpenTelemetryConfigureCallbackTest() { configure.AddOpenTelemetry(options => { - options.Configure((sp, provider) => + options.ConfigureProvider((sp, provider) => { var testClass = sp.GetRequiredService(); @@ -374,7 +374,7 @@ public void ServiceCollectionAddOpenTelemetryOptionsOrderingTest() options.AddProcessor(new CustomProcessor(0)); - options.Configure((sp, p) => + options.ConfigureProvider((sp, p) => { Assert.Null(provider); provider = p; @@ -392,7 +392,7 @@ public void ServiceCollectionAddOpenTelemetryOptionsOrderingTest() options.AddProcessor(new CustomProcessor(1)); - options.Configure((sp, p) => + options.ConfigureProvider((sp, p) => { configureInvocationCount++; @@ -409,7 +409,7 @@ public void ServiceCollectionAddOpenTelemetryOptionsOrderingTest() options.AddProcessor(new CustomProcessor(2)); - options.Configure((sp, p) => + options.ConfigureProvider((sp, p) => { configureInvocationCount++; @@ -462,7 +462,7 @@ public void ServiceCollectionAddOpenTelemetryResourceTest() { options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Examples.LoggingExtensions")); - options.Configure((sp, p) => provider = p); + options.ConfigureProvider((sp, p) => provider = p); }); configure.AddOpenTelemetry(options => From d477d8d016fe03e98321c65959808e131d2c2a76 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 1 Aug 2022 13:56:25 -0700 Subject: [PATCH 21/31] Tweaks. --- ...metryEventSourceLoggerOptionsExtensions.cs | 2 +- .../Logs/OpenTelemetryLoggingExtensions.cs | 6 +-- .../Options/OpenTelemetryLoggerOptions.cs | 42 ++++++++++++++++++- .../Options/OpenTelemetryLoggerOptionsSdk.cs | 31 +------------- .../OpenTelemetryLoggingExtensionsTests.cs | 2 +- 5 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceLoggerOptionsExtensions.cs b/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceLoggerOptionsExtensions.cs index ccd4b439016..582e65a5c1e 100644 --- a/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceLoggerOptionsExtensions.cs +++ b/src/OpenTelemetry.Extensions.EventSource/OpenTelemetryEventSourceLoggerOptionsExtensions.cs @@ -47,7 +47,7 @@ public static OpenTelemetryLoggerOptions AddEventSourceLogEmitter( Guard.ThrowIfNull(options); Guard.ThrowIfNull(shouldListenToFunc); - options.Services.TryAddSingleton(); + options.ConfigureServices(services => services.TryAddSingleton()); options.ConfigureProvider((sp, provider) => { diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs index 4faa98d9ad4..080f48cd961 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs @@ -73,10 +73,8 @@ public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder, Act * needed. */ - var options = new OpenTelemetryLoggerOptions - { - Services = builder.Services, - }; + var options = new OpenTelemetryLoggerOptions(builder.Services); + configure(options); /* diff --git a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs index b02c1b8dc8d..c44fe838171 100644 --- a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs @@ -34,16 +34,29 @@ public class OpenTelemetryLoggerOptions internal readonly List> Processors = new(); internal ResourceBuilder? ResourceBuilder; internal List>? ConfigurationActions = new(); - internal IServiceCollection? Services; private const bool DefaultIncludeScopes = false; private const bool DefaultIncludeFormattedMessage = false; private const bool DefaultParseStateValues = false; + private IServiceCollection? services; private bool? includeScopes; private bool? includeFormattedMessage; private bool? parseStateValues; + /// + /// Initializes a new instance of the class. + /// + public OpenTelemetryLoggerOptions() + : this(services: null) + { + } + + internal OpenTelemetryLoggerOptions(IServiceCollection? services) + { + this.services = services; + } + /// /// Gets or sets a value indicating whether or not log scopes should be /// included on generated s. Default value: @@ -82,6 +95,8 @@ public bool ParseStateValues set => this.parseStateValues = value; } + internal IServiceCollection? Services => this.services; + /// /// Adds processor to the options. /// @@ -173,7 +188,7 @@ public OpenTelemetryLoggerOptions ConfigureServices( { Guard.ThrowIfNull(configure); - var services = this.Services; + var services = this.services; if (services == null) { @@ -208,6 +223,29 @@ public OpenTelemetryLoggerOptions ConfigureProvider( return this; } + internal OpenTelemetryLoggerProvider Build() + { + var services = this.services; + + if (services == null) + { + throw new NotSupportedException("LoggerProviderBuilder build method cannot be called multiple times."); + } + + this.services = null; + + var serviceProvider = services.BuildServiceProvider(); + + var finalOptions = serviceProvider.GetRequiredService>().CurrentValue; + + this.ApplyTo(finalOptions); + + return new OpenTelemetryLoggerProvider( + finalOptions, + serviceProvider, + ownsServiceProvider: true); + } + internal void ApplyTo(OpenTelemetryLoggerOptions other) { Debug.Assert(other != null, "other instance was null"); diff --git a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs index c12592ab3f3..01503cf8c5e 100644 --- a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs @@ -18,43 +18,16 @@ using System; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; namespace OpenTelemetry.Logs; internal sealed class OpenTelemetryLoggerOptionsSdk : OpenTelemetryLoggerOptions { public OpenTelemetryLoggerOptionsSdk(Action? configure) + : base(new ServiceCollection()) { - var services = new ServiceCollection(); - - services.AddOptions(); - - this.Services = services; + this.ConfigureServices(services => services.AddOptions()); configure?.Invoke(this); } - - public OpenTelemetryLoggerProvider Build() - { - var services = this.Services; - - if (services == null) - { - throw new NotSupportedException("LoggerProviderBuilder build method cannot be called multiple times."); - } - - this.Services = null; - - var serviceProvider = services.BuildServiceProvider(); - - var finalOptions = serviceProvider.GetRequiredService>().CurrentValue; - - this.ApplyTo(finalOptions); - - return new OpenTelemetryLoggerProvider( - finalOptions, - serviceProvider, - ownsServiceProvider: true); - } } diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index e5488483568..8e1b92196ef 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -275,7 +275,7 @@ public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithRegis { if (!registerOutside) { - options.Services!.AddSingleton(); + options.ConfigureServices(services => services.AddSingleton()); } options.AddProcessor(); From 2c4195d496aeca4438ad85bedd45d3ab5941a57a Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 1 Aug 2022 14:35:49 -0700 Subject: [PATCH 22/31] More tests. --- .../Options/OpenTelemetryLoggerOptions.cs | 6 +- .../OpenTelemetryLoggerOptionsSdkTests.cs | 135 ++++++++++++++++++ 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs diff --git a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs index c44fe838171..e1d0f6d83bc 100644 --- a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs @@ -240,10 +240,14 @@ internal OpenTelemetryLoggerProvider Build() this.ApplyTo(finalOptions); - return new OpenTelemetryLoggerProvider( + var provider = new OpenTelemetryLoggerProvider( finalOptions, serviceProvider, ownsServiceProvider: true); + + this.ConfigurationActions = null; + + return provider; } internal void ApplyTo(OpenTelemetryLoggerOptions other) diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs new file mode 100644 index 00000000000..2e9e524c0a2 --- /dev/null +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs @@ -0,0 +1,135 @@ +// +// 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 Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.Logs.Tests; + +public class OpenTelemetryLoggerOptionsSdkTests +{ + [Fact] + public void CreateLoggerProviderBuilderBuildValidProviderTest() + { + List exportedItems = new(); + + using var provider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .Build(); + + Assert.NotNull(provider); + + provider.CreateEmitter().Emit(new() + { + Message = "Hello world", + }); + + Assert.Single(exportedItems); + } + + [Fact] + public void CreateLoggerProviderBuilderExtensionPointsTest() + { + int ctorConfigureInvocations = 0; + int optionsConfigureInvocations = 0; + OpenTelemetryLoggerProvider? providerFromConfigureCallback = null; + + var returnedOptions = Sdk.CreateLoggerProviderBuilder(options => + { + ctorConfigureInvocations++; + + Assert.NotNull(options.Services); + + options.ConfigureServices(services => services.AddSingleton()); + }) + .AddProcessor(new CustomProcessor()) + .AddProcessor() + .ConfigureServices(services => + { + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton, CustomProcessor>(); + services.Configure(o => + { + optionsConfigureInvocations++; + + Assert.Null(o.Services); + + Assert.Throws(() => o.ConfigureServices(s => { })); + + o.ConfigureResource(r => r.AddAttributes(new Dictionary { ["key1"] = "value1" })); + + o.ConfigureProvider((sp, p) => optionsConfigureInvocations++); + }); + }) + .ConfigureProvider((sp, p) => + { + Assert.NotNull(sp); + + providerFromConfigureCallback = p; + + Assert.NotNull(sp.GetService()); + Assert.NotNull(sp.GetService()); + }); + + using var provider = returnedOptions.Build(); + + Assert.NotNull(provider); + + Assert.Throws(() => returnedOptions.ConfigureServices(s => { })); + Assert.Throws(() => returnedOptions.ConfigureResource(r => { })); + Assert.Throws(() => returnedOptions.ConfigureProvider((sp, p) => { })); + Assert.Throws(() => returnedOptions.Build()); + + Assert.Equal(1, ctorConfigureInvocations); + Assert.Equal(2, optionsConfigureInvocations); + Assert.NotNull(providerFromConfigureCallback); + Assert.Equal(provider, providerFromConfigureCallback); + + Assert.NotNull(provider.Resource?.Attributes); + Assert.Contains(provider.Resource!.Attributes, kvp => kvp.Key == "key1" && (string)kvp.Value == "value1"); + + var processor = provider.Processor as CompositeProcessor; + Assert.NotNull(processor); + + int count = 0; + var current = processor?.Head; + while (current != null) + { + count++; + current = current.Next; + } + + Assert.Equal(3, count); + } + + private sealed class TestClass1 + { + } + + private sealed class TestClass2 + { + } + + private sealed class CustomProcessor : BaseProcessor + { + } +} From 6284ff1ce1854f0ca150f880b63abe3049886e18 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 4 Aug 2022 14:43:43 -0700 Subject: [PATCH 23/31] Fix CHANGELOG for release. --- src/OpenTelemetry/CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index a34f18fc781..af068bfd454 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Added `Sdk.CreateLoggerProviderBuilder` method and support for dependency + injection scenarios when configuring `OpenTelemetryLoggerProvider` + ([#3504](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3504)) + ## 1.4.0-alpha.1 Released 2022-Aug-02 @@ -31,10 +35,6 @@ Released 2022-Aug-02 `OpenTelemetryLoggerProvider` directly ([#3489](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3489)) -* Added `Sdk.CreateLoggerProviderBuilder` method and support for dependency - injection scenarios when configuring `OpenTelemetryLoggerProvider` - ([#3504](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3504)) - ## 1.3.0 Released 2022-Jun-03 From 2b26cb0fb5de024ed229328a0251f70744aa5f6d Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 5 Aug 2022 11:24:40 -0700 Subject: [PATCH 24/31] Tweaks. --- .../Logs/Options/OpenTelemetryLoggerOptions.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs index e1d0f6d83bc..e3380ba5d3a 100644 --- a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs @@ -20,6 +20,7 @@ using System.Collections.Generic; using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; using OpenTelemetry.Internal; using OpenTelemetry.Resources; @@ -120,15 +121,17 @@ public OpenTelemetryLoggerOptions AddProcessor(BaseProcessor processo /// /// Adds a processor to the options which will be retrieved using dependency injection. /// + /// + /// Note: The type specified by will be + /// registered as a singleton service into application services. + /// /// Processor type. /// The supplied for chaining. public OpenTelemetryLoggerOptions AddProcessor() where T : BaseProcessor { - return this.ConfigureProvider((sp, provider) => - { - provider.AddProcessor(sp.GetRequiredService()); - }); + return this + .ConfigureServices(services => services.TryAddSingleton, T>()); } /// From 280ad5de52338b52c8f20113471604d3aca01c0b Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 5 Aug 2022 11:33:06 -0700 Subject: [PATCH 25/31] Test updates. --- .../OpenTelemetryLoggingExtensionsTests.cs | 38 +++---------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index 8e1b92196ef..beda6375aba 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -238,46 +238,16 @@ public void ServiceCollectionAddOpenTelemetryServicesAvailableTest() } [Fact] - public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithoutRegistrationThrowsTest() - { - var services = new ServiceCollection(); - - services.AddLogging(configure => - { - // Note: This will throw because CustomProcessor has not been - // registered with services - - configure.AddOpenTelemetry(options => options.AddProcessor()); - }); - - using var serviceProvider = services.BuildServiceProvider(); - - Assert.Throws(() => serviceProvider.GetRequiredService()); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithRegistrationTests(bool registerOutside) + public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyTest() { CustomProcessor.InstanceCount = 0; var services = new ServiceCollection(); - if (registerOutside) - { - services.AddSingleton(); - } - services.AddLogging(configure => { configure.AddOpenTelemetry(options => { - if (!registerOutside) - { - options.ConfigureServices(services => services.AddSingleton()); - } - options.AddProcessor(); }); }); @@ -288,11 +258,13 @@ public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyWithRegis { var loggerFactory = serviceProvider.GetRequiredService(); - customProcessor = serviceProvider.GetRequiredService(); + customProcessor = serviceProvider.GetRequiredService>() as CustomProcessor; + + Assert.NotNull(customProcessor); loggerFactory.Dispose(); - Assert.False(customProcessor.Disposed); + Assert.False(customProcessor!.Disposed); } Assert.True(customProcessor.Disposed); From 251ff8113b93ed312d1bc8ae2cfb37355d2a191e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 5 Aug 2022 11:49:50 -0700 Subject: [PATCH 26/31] Added a detached configuration option. --- .../Logs/OpenTelemetryLoggerProvider.cs | 17 +++++++++++++++-- .../OpenTelemetryLoggingExtensionsTests.cs | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs index c41fdd4e5b6..7b438b264ae 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs @@ -100,10 +100,23 @@ internal OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IServic this.ResourceBuilder = options.ResourceBuilder ?? ResourceBuilder.CreateDefault(); + if (serviceProvider != null) + { + // Step 2: Look for any Action configuration actions registered and + // execute them. + + var registeredConfigurations = serviceProvider.GetServices>(); + foreach (var registeredConfiguration in registeredConfigurations) + { + registeredConfiguration?.Invoke(serviceProvider, this); + } + } + var configurationActions = options.ConfigurationActions; if (configurationActions?.Count > 0) { - // Step 2: Execute any configuration actions. + // Step 3: Execute any configuration actions. if (serviceProvider == null) { @@ -122,7 +135,7 @@ internal OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IServic if (serviceProvider != null) { - // Step 3: Look for any processors registered directly with the service provider. + // Step 4: Look for any processors registered directly with the service provider. var registeredProcessors = serviceProvider.GetServices>(); foreach (BaseProcessor processor in registeredProcessors) diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index beda6375aba..46a314ec8fe 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -470,6 +470,24 @@ public void ServiceCollectionAddOpenTelemetryResourceTest() Assert.Contains(resource.Attributes, kvp => kvp.Key == "key3"); } + [Fact] + public void ServiceCollectionAddOpenTelemetryDetachedConfigurationTest() + { + int configurationInvocations = 0; + + var services = new ServiceCollection(); + + services.AddLogging(configure => configure.AddOpenTelemetry()); + + services.AddSingleton>((sp, provider) => configurationInvocations++); + + using var serviceProvider = services.BuildServiceProvider(); + + var loggerFactory = serviceProvider.GetRequiredService(); + + Assert.Equal(1, configurationInvocations); + } + private sealed class WrappedOpenTelemetryLoggerProvider : OpenTelemetryLoggerProvider { public bool Disposed { get; private set; } From 5f2b5b52689af965186cfc7a702dd5bdb3412b45 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 5 Aug 2022 14:32:48 -0700 Subject: [PATCH 27/31] Prevent double registration to be consistent with tracer builder pattern. --- .../Logs/OpenTelemetryLoggingExtensions.cs | 33 +++++++++- .../OpenTelemetryLoggingExtensionsTests.cs | 61 +++++++++++-------- 2 files changed, 65 insertions(+), 29 deletions(-) diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs index 080f48cd961..5a1d80f81e9 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs @@ -17,6 +17,7 @@ #nullable enable using System; +using System.Linq; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; @@ -35,6 +36,11 @@ public static class OpenTelemetryLoggingExtensions /// /// Adds an OpenTelemetry logger named 'OpenTelemetry' to the . /// + /// + /// Note: This is safe to be called more than once and should be used by + /// library authors to ensure at least one is registered. + /// /// The to use. /// The supplied for call chaining. public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder) @@ -43,6 +49,11 @@ public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder) /// /// Adds an OpenTelemetry logger named 'OpenTelemetry' to the . /// + /// + /// Note: This is should only be called once during application + /// bootstrap for a given . This should + /// not be used by library authors. + /// /// The to use. /// Optional configuration action. /// The supplied for call chaining. @@ -54,9 +65,15 @@ public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder, Act builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton(sp => { - var options = sp.GetRequiredService>().CurrentValue; + var registeredBuilders = sp.GetServices(); + if (registeredBuilders.Count() > 1) + { + throw new NotSupportedException("Multiple logger provider builders cannot be registered in the same service collection."); + } + + var finalOptions = sp.GetRequiredService>().CurrentValue; - return new OpenTelemetryLoggerProvider(options, sp, ownsServiceProvider: false); + return new OpenTelemetryLoggerProvider(finalOptions, sp, ownsServiceProvider: false); })); // Note: This will bind logger options element (eg "Logging:OpenTelemetry") to OpenTelemetryLoggerOptions @@ -77,6 +94,8 @@ public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder, Act configure(options); + builder.Services.AddSingleton(new TrackedOpenTelemetryLoggerOptions(options)); + /* * Step 2: When ServiceProvider is built from "Services" and the * LoggerFactory is created then the options pipeline runs and @@ -142,5 +161,15 @@ public static ILoggingBuilder AddOpenTelemetry( return builder; } + + private sealed class TrackedOpenTelemetryLoggerOptions + { + public TrackedOpenTelemetryLoggerOptions(OpenTelemetryLoggerOptions options) + { + this.Options = options; + } + + public OpenTelemetryLoggerOptions Options { get; } + } } } diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index 46a314ec8fe..f4553728681 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -29,7 +29,7 @@ namespace OpenTelemetry.Logs.Tests; public sealed class OpenTelemetryLoggingExtensionsTests { [Fact] - public void ServiceCollectionAddOpenTelemetryNoParametersTest() + public void LoggingBuilderAddOpenTelemetryNoParametersTest() { bool optionsCallbackInvoked = false; @@ -55,10 +55,9 @@ public void ServiceCollectionAddOpenTelemetryNoParametersTest() } [Theory] - [InlineData(1, 0)] - [InlineData(1, 1)] - [InlineData(5, 5)] - public void ServiceCollectionAddOpenTelemetryConfigureActionTests(int numberOfBuilderRegistrations, int numberOfOptionsRegistrations) + [InlineData(1)] + [InlineData(5)] + public void LoggingBuilderAddOpenTelemetryConfigureActionTests(int numberOfOptionsRegistrations) { int configureCallbackInvocations = 0; int optionsCallbackInvocations = 0; @@ -68,10 +67,8 @@ public void ServiceCollectionAddOpenTelemetryConfigureActionTests(int numberOfBu serviceCollection.AddLogging(configure => { - for (int i = 0; i < numberOfBuilderRegistrations; i++) - { - configure.AddOpenTelemetry(ConfigureCallback); - } + configure.AddOpenTelemetry(); // <- Just to verify this doesn't cause a throw. + configure.AddOpenTelemetry(ConfigureCallback); }); for (int i = 0; i < numberOfOptionsRegistrations; i++) @@ -89,7 +86,7 @@ public void ServiceCollectionAddOpenTelemetryConfigureActionTests(int numberOfBu Assert.NotNull(loggerFactory); - Assert.Equal(numberOfBuilderRegistrations, configureCallbackInvocations); + Assert.Equal(1, configureCallbackInvocations); Assert.Equal(numberOfOptionsRegistrations, optionsCallbackInvocations); void ConfigureCallback(OpenTelemetryLoggerOptions options) @@ -124,7 +121,23 @@ void OptionsCallback(OpenTelemetryLoggerOptions options) } [Fact] - public void ServiceCollectionAddOpenTelemetryWithProviderTest() + public void LoggingBuilderAddOpenTelemetryMultipleBuildersThrows() + { + var serviceCollection = new ServiceCollection(); + + serviceCollection.AddLogging(configure => + { + configure.AddOpenTelemetry(optiosn => { }); + configure.AddOpenTelemetry(optiosn => { }); + }); + + using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider(); + + Assert.Throws(() => serviceProvider.GetService()); + } + + [Fact] + public void LoggingBuilderAddOpenTelemetryWithProviderTest() { var provider = new WrappedOpenTelemetryLoggerProvider(); @@ -153,7 +166,7 @@ public void ServiceCollectionAddOpenTelemetryWithProviderTest() [Theory] [InlineData(true)] [InlineData(false)] - public void ServiceCollectionAddOpenTelemetryWithProviderAndDisposeSpecifiedTests(bool dispose) + public void LoggingBuilderAddOpenTelemetryWithProviderAndDisposeSpecifiedTests(bool dispose) { var provider = new WrappedOpenTelemetryLoggerProvider(); @@ -206,7 +219,7 @@ public void LoggerFactoryCreateAddOpenTelemetryWithProviderAndDisposeSpecifiedTe } [Fact] - public void ServiceCollectionAddOpenTelemetryServicesAvailableTest() + public void LoggingBuilderAddOpenTelemetryServicesAvailableTest() { int invocationCount = 0; @@ -238,7 +251,7 @@ public void ServiceCollectionAddOpenTelemetryServicesAvailableTest() } [Fact] - public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyTest() + public void LoggingBuilderAddOpenTelemetryProcessorThroughDependencyTest() { CustomProcessor.InstanceCount = 0; @@ -273,7 +286,7 @@ public void ServiceCollectionAddOpenTelemetryProcessorThroughDependencyTest() } [Fact] - public void ServiceCollectionAddOpenTelemetryConfigureCallbackTest() + public void LoggingBuilderAddOpenTelemetryConfigureCallbackTest() { var services = new ServiceCollection(); @@ -307,7 +320,7 @@ public void ServiceCollectionAddOpenTelemetryConfigureCallbackTest() } [Fact] - public void ServiceCollectionAddOpenTelemetryExternalRegistrationTest() + public void LoggingBuilderAddOpenTelemetryExternalRegistrationTest() { CustomProcessor.InstanceCount = 0; @@ -329,7 +342,7 @@ public void ServiceCollectionAddOpenTelemetryExternalRegistrationTest() } [Fact] - public void ServiceCollectionAddOpenTelemetryOptionsOrderingTest() + public void LoggingBuilderAddOpenTelemetryOptionsOrderingTest() { int configureInvocationCount = 0; @@ -422,7 +435,7 @@ public void ServiceCollectionAddOpenTelemetryOptionsOrderingTest() } [Fact] - public void ServiceCollectionAddOpenTelemetryResourceTest() + public void LoggingBuilderAddOpenTelemetryResourceTest() { var services = new ServiceCollection(); @@ -436,21 +449,16 @@ public void ServiceCollectionAddOpenTelemetryResourceTest() options.ConfigureProvider((sp, p) => provider = p); }); - - configure.AddOpenTelemetry(options => - { - options.ConfigureResource(builder => builder.AddAttributes(new Dictionary { ["key1"] = "value1" })); - }); }); services.Configure(options => { - options.ConfigureResource(builder => builder.AddAttributes(new Dictionary { ["key2"] = "value2" })); + options.ConfigureResource(builder => builder.AddAttributes(new Dictionary { ["key1"] = "value1" })); }); services.Configure(options => { - options.ConfigureResource(builder => builder.AddAttributes(new Dictionary { ["key3"] = "value3" })); + options.ConfigureResource(builder => builder.AddAttributes(new Dictionary { ["key2"] = "value2" })); }); using var serviceProvider = services.BuildServiceProvider(); @@ -467,11 +475,10 @@ public void ServiceCollectionAddOpenTelemetryResourceTest() Assert.Contains(resource.Attributes, kvp => kvp.Key == "service.instance.id"); Assert.Contains(resource.Attributes, kvp => kvp.Key == "key1"); Assert.Contains(resource.Attributes, kvp => kvp.Key == "key2"); - Assert.Contains(resource.Attributes, kvp => kvp.Key == "key3"); } [Fact] - public void ServiceCollectionAddOpenTelemetryDetachedConfigurationTest() + public void LoggingBuilderAddOpenTelemetryDetachedConfigurationTest() { int configurationInvocations = 0; From 28301d86c6af0dbf2cc4384c435c94ff4abd8463 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 5 Aug 2022 15:05:01 -0700 Subject: [PATCH 28/31] API review. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 +- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 4 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 4 +- .../netstandard2.1/PublicAPI.Unshipped.txt | 4 +- .../Options/OpenTelemetryLoggerOptions.cs | 39 +++++++++++++++++++ .../Options/OpenTelemetryLoggerOptionsSdk.cs | 4 +- src/OpenTelemetry/Sdk.cs | 19 +-------- ...OpenTelemetryEventSourceLogEmitterTests.cs | 4 +- .../OpenTelemetrySerilogSinkTests.cs | 10 ++--- .../OpenTelemetryLoggerOptionsSdkTests.cs | 16 +------- .../Logs/OpenTelemetryLoggerProviderTests.cs | 19 ++++----- 11 files changed, 68 insertions(+), 59 deletions(-) diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt index caf43aedf78..5f9d0a1ac8c 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt @@ -11,6 +11,9 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureServices(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetIncludeFormattedMessage(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetIncludeScopes(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetParseStateValues(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool @@ -22,6 +25,5 @@ static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTeleme static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Sdk.CreateLoggerProviderBuilder(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! ~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 diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt index caf43aedf78..5f9d0a1ac8c 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -11,6 +11,9 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureServices(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetIncludeFormattedMessage(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetIncludeScopes(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetParseStateValues(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool @@ -22,6 +25,5 @@ static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTeleme static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Sdk.CreateLoggerProviderBuilder(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! ~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 diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 95cd98ecf76..a840723ef46 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -10,6 +10,9 @@ OpenTelemetry.Logs.LogRecord.TraceState.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureServices(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetIncludeFormattedMessage(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetIncludeScopes(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetParseStateValues(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool @@ -22,6 +25,5 @@ static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTeleme static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Sdk.CreateLoggerProviderBuilder(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! ~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 diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index caf43aedf78..5f9d0a1ac8c 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -11,6 +11,9 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureServices(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetIncludeFormattedMessage(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetIncludeScopes(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.SetParseStateValues(bool enabled) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool @@ -22,6 +25,5 @@ static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTeleme static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddOpenTelemetry(this Microsoft.Extensions.Logging.ILoggingBuilder! builder, System.Action? configure) -> Microsoft.Extensions.Logging.ILoggingBuilder! static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Sdk.CreateLoggerProviderBuilder(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! ~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 diff --git a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs index e3380ba5d3a..6be36c3a2e9 100644 --- a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs @@ -226,6 +226,45 @@ public OpenTelemetryLoggerOptions ConfigureProvider( return this; } + /// + /// Sets the value of the options. + /// + /// to enable the option or + /// to disable it. + /// The supplied for + /// chaining. + public OpenTelemetryLoggerOptions SetIncludeFormattedMessage(bool enabled) + { + this.includeFormattedMessage = enabled; + return this; + } + + /// + /// Sets the value of the options. + /// + /// to enable the option or + /// to disable it. + /// The supplied for + /// chaining. + public OpenTelemetryLoggerOptions SetIncludeScopes(bool enabled) + { + this.includeScopes = enabled; + return this; + } + + /// + /// Sets the value of the options. + /// + /// to enable the option or + /// to disable it. + /// The supplied for + /// chaining. + public OpenTelemetryLoggerOptions SetParseStateValues(bool enabled) + { + this.parseStateValues = enabled; + return this; + } + internal OpenTelemetryLoggerProvider Build() { var services = this.services; diff --git a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs index 01503cf8c5e..b566372e19c 100644 --- a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs @@ -23,11 +23,9 @@ namespace OpenTelemetry.Logs; internal sealed class OpenTelemetryLoggerOptionsSdk : OpenTelemetryLoggerOptions { - public OpenTelemetryLoggerOptionsSdk(Action? configure) + public OpenTelemetryLoggerOptionsSdk() : base(new ServiceCollection()) { this.ConfigureServices(services => services.AddOptions()); - - configure?.Invoke(this); } } diff --git a/src/OpenTelemetry/Sdk.cs b/src/OpenTelemetry/Sdk.cs index 313e7e1e02c..1b6bc2a31c2 100644 --- a/src/OpenTelemetry/Sdk.cs +++ b/src/OpenTelemetry/Sdk.cs @@ -70,24 +70,7 @@ public static void SetDefaultTextMapPropagator(TextMapPropagator textMapPropagat /// instance, which is used to build a . public static OpenTelemetryLoggerOptions CreateLoggerProviderBuilder() { - return new OpenTelemetryLoggerOptionsSdk(configure: null); - } - - /// - /// Creates a which is used to build - /// an . In a typical application, a single - /// is created at application startup and disposed - /// at application shutdown. It is important to ensure that the provider is not - /// disposed too early. - /// - /// Configuration action. - /// instance, which is used to build a . - public static OpenTelemetryLoggerOptions CreateLoggerProviderBuilder( - Action configure) - { - Guard.ThrowIfNull(configure); - - return new OpenTelemetryLoggerOptionsSdk(configure); + return new OpenTelemetryLoggerOptionsSdk(); } /// diff --git a/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs index 07f8ca5b920..1da0f6ef04e 100644 --- a/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs +++ b/test/OpenTelemetry.Extensions.EventSource.Tests/OpenTelemetryEventSourceLogEmitterTests.cs @@ -183,8 +183,8 @@ public void OpenTelemetryEventSourceLogEmitterComplexEventTest(bool formatMessag List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder( - options => options.IncludeFormattedMessage = formatMessage) + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .SetIncludeFormattedMessage(formatMessage) .AddInMemoryExporter(exportedItems) .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope diff --git a/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs b/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs index 8173867340c..b1978aa5c86 100644 --- a/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs +++ b/test/OpenTelemetry.Extensions.Serilog.Tests/OpenTelemetrySerilogSinkTests.cs @@ -61,13 +61,9 @@ public void SerilogBasicLogTests(bool includeFormattedMessage) List exportedItems = new(); #pragma warning disable CA2000 // Dispose objects before losing scope - var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder( - options => - { - options.IncludeFormattedMessage = includeFormattedMessage; - - options.AddInMemoryExporter(exportedItems); - }) + var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .SetIncludeFormattedMessage(includeFormattedMessage) + .AddInMemoryExporter(exportedItems) .Build(); #pragma warning restore CA2000 // Dispose objects before losing scope diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs index 2e9e524c0a2..e4a0b9a3917 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs @@ -52,19 +52,12 @@ public void CreateLoggerProviderBuilderExtensionPointsTest() int optionsConfigureInvocations = 0; OpenTelemetryLoggerProvider? providerFromConfigureCallback = null; - var returnedOptions = Sdk.CreateLoggerProviderBuilder(options => - { - ctorConfigureInvocations++; - - Assert.NotNull(options.Services); - - options.ConfigureServices(services => services.AddSingleton()); - }) + var returnedOptions = Sdk.CreateLoggerProviderBuilder() .AddProcessor(new CustomProcessor()) .AddProcessor() .ConfigureServices(services => { - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton, CustomProcessor>(); services.Configure(o => @@ -87,7 +80,6 @@ public void CreateLoggerProviderBuilderExtensionPointsTest() providerFromConfigureCallback = p; Assert.NotNull(sp.GetService()); - Assert.NotNull(sp.GetService()); }); using var provider = returnedOptions.Build(); @@ -125,10 +117,6 @@ private sealed class TestClass1 { } - private sealed class TestClass2 - { - } - private sealed class CustomProcessor : BaseProcessor { } diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs index 5fe51af8aa6..674e63eaef5 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs @@ -43,18 +43,15 @@ public void ConfigureCtorTests() { OpenTelemetryLoggerOptions defaults = new(); - using OpenTelemetryLoggerProvider provider = Sdk.CreateLoggerProviderBuilder(options => - { - options.IncludeScopes = !defaults.IncludeScopes; - options.IncludeFormattedMessage = !defaults.IncludeFormattedMessage; - options.ParseStateValues = !defaults.ParseStateValues; - - options.SetResourceBuilder(ResourceBuilder + using OpenTelemetryLoggerProvider provider = Sdk.CreateLoggerProviderBuilder() + .SetIncludeScopes(!defaults.IncludeScopes) + .SetIncludeFormattedMessage(!defaults.IncludeFormattedMessage) + .SetParseStateValues(!defaults.ParseStateValues) + .SetResourceBuilder(ResourceBuilder .CreateEmpty() - .AddAttributes(new[] { new KeyValuePair("key1", "value1") })); - - options.AddInMemoryExporter(new List()); - }).Build(); + .AddAttributes(new[] { new KeyValuePair("key1", "value1") })) + .AddInMemoryExporter(new List()) + .Build(); Assert.Equal(!defaults.IncludeScopes, provider.IncludeScopes); Assert.Equal(!defaults.IncludeFormattedMessage, provider.IncludeFormattedMessage); From 7cc28653f52f15c03e9332747566dbd4b08f4042 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 5 Aug 2022 15:28:45 -0700 Subject: [PATCH 29/31] Warning cleanup. --- src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs | 1 - src/OpenTelemetry/Sdk.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs index b566372e19c..48f2a53b492 100644 --- a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptionsSdk.cs @@ -16,7 +16,6 @@ #nullable enable -using System; using Microsoft.Extensions.DependencyInjection; namespace OpenTelemetry.Logs; diff --git a/src/OpenTelemetry/Sdk.cs b/src/OpenTelemetry/Sdk.cs index 1b6bc2a31c2..eb17c6d3631 100644 --- a/src/OpenTelemetry/Sdk.cs +++ b/src/OpenTelemetry/Sdk.cs @@ -16,7 +16,6 @@ #nullable enable -using System; using System.Diagnostics; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Internal; From 8ecfdafed58a625b62d024bb2d17921ad1012d23 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 5 Aug 2022 15:33:43 -0700 Subject: [PATCH 30/31] Build fixes. --- examples/LoggingExtensions/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/LoggingExtensions/Program.cs b/examples/LoggingExtensions/Program.cs index 7abc315e582..795398f2966 100644 --- a/examples/LoggingExtensions/Program.cs +++ b/examples/LoggingExtensions/Program.cs @@ -21,8 +21,8 @@ using OpenTelemetry.Resources; using Serilog; -var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder( - options => options.IncludeFormattedMessage = true) +var openTelemetryLoggerProvider = Sdk.CreateLoggerProviderBuilder() + .SetIncludeFormattedMessage(true) .ConfigureResource(builder => builder.AddService("Examples.LoggingExtensions")) .AddConsoleExporter() .Build(); From 7057343559b9c3c44ec597856a27f3d0e4bbb54d Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 5 Aug 2022 16:30:29 -0700 Subject: [PATCH 31/31] Test fix. --- .../Logs/OpenTelemetryLoggerOptionsSdkTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs index e4a0b9a3917..b62080951c3 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerOptionsSdkTests.cs @@ -48,7 +48,6 @@ public void CreateLoggerProviderBuilderBuildValidProviderTest() [Fact] public void CreateLoggerProviderBuilderExtensionPointsTest() { - int ctorConfigureInvocations = 0; int optionsConfigureInvocations = 0; OpenTelemetryLoggerProvider? providerFromConfigureCallback = null; @@ -91,7 +90,6 @@ public void CreateLoggerProviderBuilderExtensionPointsTest() Assert.Throws(() => returnedOptions.ConfigureProvider((sp, p) => { })); Assert.Throws(() => returnedOptions.Build()); - Assert.Equal(1, ctorConfigureInvocations); Assert.Equal(2, optionsConfigureInvocations); Assert.NotNull(providerFromConfigureCallback); Assert.Equal(provider, providerFromConfigureCallback);