-
Notifications
You must be signed in to change notification settings - Fork 752
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[sdk] Add OpenTelemetrySdk builder pattern (#5325)
- Loading branch information
1 parent
36c586d
commit 05bb05a
Showing
5 changed files
with
244 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
OpenTelemetry.OpenTelemetrySdk | ||
OpenTelemetry.OpenTelemetrySdk.Dispose() -> void | ||
OpenTelemetry.OpenTelemetrySdk.LoggerProvider.get -> OpenTelemetry.Logs.LoggerProvider! | ||
OpenTelemetry.OpenTelemetrySdk.MeterProvider.get -> OpenTelemetry.Metrics.MeterProvider! | ||
OpenTelemetry.OpenTelemetrySdk.TracerProvider.get -> OpenTelemetry.Trace.TracerProvider! | ||
OpenTelemetry.OpenTelemetrySdkExtensions | ||
static OpenTelemetry.OpenTelemetrySdk.Create(System.Action<OpenTelemetry.IOpenTelemetryBuilder!>! configure) -> OpenTelemetry.OpenTelemetrySdk! | ||
static OpenTelemetry.OpenTelemetrySdkExtensions.GetLoggerFactory(this OpenTelemetry.OpenTelemetrySdk! sdk) -> Microsoft.Extensions.Logging.ILoggerFactory! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
using System.Diagnostics; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using OpenTelemetry.Internal; | ||
using OpenTelemetry.Logs; | ||
using OpenTelemetry.Metrics; | ||
using OpenTelemetry.Trace; | ||
|
||
namespace OpenTelemetry; | ||
|
||
/// <summary> | ||
/// Contains methods for configuring the OpenTelemetry SDK and accessing | ||
/// logging, metrics, and tracing providers. | ||
/// </summary> | ||
public sealed class OpenTelemetrySdk : IDisposable | ||
{ | ||
private readonly ServiceProvider serviceProvider; | ||
|
||
private OpenTelemetrySdk( | ||
Action<IOpenTelemetryBuilder> configure) | ||
{ | ||
Debug.Assert(configure != null, "configure was null"); | ||
|
||
var services = new ServiceCollection(); | ||
|
||
var builder = new OpenTelemetrySdkBuilder(services); | ||
|
||
configure!(builder); | ||
|
||
this.serviceProvider = services.BuildServiceProvider(); | ||
|
||
this.LoggerProvider = (LoggerProvider?)this.serviceProvider.GetService(typeof(LoggerProvider)) | ||
?? new NoopLoggerProvider(); | ||
this.MeterProvider = (MeterProvider?)this.serviceProvider.GetService(typeof(MeterProvider)) | ||
?? new NoopMeterProvider(); | ||
this.TracerProvider = (TracerProvider?)this.serviceProvider.GetService(typeof(TracerProvider)) | ||
?? new NoopTracerProvider(); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the <see cref="Logs.LoggerProvider"/>. | ||
/// </summary> | ||
/// <remarks> | ||
/// Note: The default <see cref="LoggerProvider"/> will be a no-op instance. | ||
/// Call <see | ||
/// cref="OpenTelemetryBuilderSdkExtensions.WithLogging(IOpenTelemetryBuilder)"/> to | ||
/// enable logging. | ||
/// </remarks> | ||
public LoggerProvider LoggerProvider { get; } | ||
|
||
/// <summary> | ||
/// Gets the <see cref="Metrics.MeterProvider"/>. | ||
/// </summary> | ||
/// <remarks> | ||
/// Note: The default <see cref="MeterProvider"/> will be a no-op instance. | ||
/// Call <see | ||
/// cref="OpenTelemetryBuilderSdkExtensions.WithMetrics(IOpenTelemetryBuilder)"/> | ||
/// to enable metrics. | ||
/// </remarks> | ||
public MeterProvider MeterProvider { get; } | ||
|
||
/// <summary> | ||
/// Gets the <see cref="Trace.TracerProvider"/>. | ||
/// </summary> | ||
/// <remarks> | ||
/// Note: The default <see cref="TracerProvider"/> will be a no-op instance. | ||
/// Call <see | ||
/// cref="OpenTelemetryBuilderSdkExtensions.WithTracing(IOpenTelemetryBuilder)"/> | ||
/// to enable tracing. | ||
/// </remarks> | ||
public TracerProvider TracerProvider { get; } | ||
|
||
/// <summary> | ||
/// Gets the <see cref="IServiceProvider"/> containing SDK services. | ||
/// </summary> | ||
internal IServiceProvider Services => this.serviceProvider; | ||
|
||
/// <summary> | ||
/// Create an <see cref="OpenTelemetrySdk"/> instance. | ||
/// </summary> | ||
/// <param name="configure"><see cref="IOpenTelemetryBuilder"/> configuration delegate.</param> | ||
/// <returns>Created <see cref="OpenTelemetrySdk"/>.</returns> | ||
public static OpenTelemetrySdk Create( | ||
Action<IOpenTelemetryBuilder> configure) | ||
{ | ||
Guard.ThrowIfNull(configure); | ||
|
||
return new(configure); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public void Dispose() | ||
{ | ||
this.serviceProvider.Dispose(); | ||
} | ||
|
||
internal sealed class NoopLoggerProvider : LoggerProvider | ||
{ | ||
} | ||
|
||
internal sealed class NoopMeterProvider : MeterProvider | ||
{ | ||
} | ||
|
||
internal sealed class NoopTracerProvider : TracerProvider | ||
{ | ||
} | ||
|
||
private sealed class OpenTelemetrySdkBuilder : IOpenTelemetryBuilder | ||
{ | ||
public OpenTelemetrySdkBuilder(IServiceCollection services) | ||
{ | ||
Debug.Assert(services != null, "services was null"); | ||
|
||
services!.AddOpenTelemetrySharedProviderBuilderServices(); | ||
|
||
this.Services = services!; | ||
} | ||
|
||
public IServiceCollection Services { get; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Logging.Abstractions; | ||
using OpenTelemetry.Internal; | ||
|
||
namespace OpenTelemetry; | ||
|
||
/// <summary> | ||
/// Contains methods for extending the <see cref="OpenTelemetrySdk"/> class. | ||
/// </summary> | ||
public static class OpenTelemetrySdkExtensions | ||
{ | ||
private static readonly NullLoggerFactory NoopLoggerFactory = new(); | ||
|
||
/// <summary> | ||
/// Gets the <see cref="ILoggerFactory"/> contained in an <see | ||
/// cref="OpenTelemetrySdk"/> instance. | ||
/// </summary> | ||
/// <remarks> | ||
/// Note: The default <see cref="ILoggerFactory"/> will be a no-op instance. | ||
/// Call <see | ||
/// cref="OpenTelemetryBuilderSdkExtensions.WithLogging(IOpenTelemetryBuilder)"/> | ||
/// to enable logging. | ||
/// </remarks> | ||
/// <param name="sdk"><see cref="OpenTelemetrySdk"/>.</param> | ||
/// <returns><see cref="ILoggerFactory"/>.</returns> | ||
public static ILoggerFactory GetLoggerFactory(this OpenTelemetrySdk sdk) | ||
{ | ||
Guard.ThrowIfNull(sdk); | ||
|
||
return (ILoggerFactory?)sdk.Services.GetService(typeof(ILoggerFactory)) | ||
?? NoopLoggerFactory; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#nullable enable | ||
|
||
using Microsoft.Extensions.Logging.Abstractions; | ||
using OpenTelemetry.Logs; | ||
using OpenTelemetry.Metrics; | ||
using OpenTelemetry.Trace; | ||
using Xunit; | ||
|
||
namespace OpenTelemetry.Tests; | ||
|
||
public class OpenTelemetrySdkTests | ||
{ | ||
[Fact] | ||
public void BuilderDelegateRequiredTest() | ||
{ | ||
Assert.Throws<ArgumentNullException>(() => OpenTelemetrySdk.Create(null!)); | ||
} | ||
|
||
[Fact] | ||
public void NoopProvidersReturnedTest() | ||
{ | ||
bool builderDelegateInvoked = false; | ||
|
||
using var sdk = OpenTelemetrySdk.Create(builder => | ||
{ | ||
builderDelegateInvoked = true; | ||
Assert.NotNull(builder.Services); | ||
}); | ||
|
||
Assert.True(builderDelegateInvoked); | ||
|
||
Assert.NotNull(sdk); | ||
Assert.NotNull(sdk.Services); | ||
Assert.True(sdk.LoggerProvider is OpenTelemetrySdk.NoopLoggerProvider); | ||
Assert.True(sdk.MeterProvider is OpenTelemetrySdk.NoopMeterProvider); | ||
Assert.True(sdk.TracerProvider is OpenTelemetrySdk.NoopTracerProvider); | ||
Assert.True(sdk.GetLoggerFactory() is NullLoggerFactory); | ||
} | ||
|
||
[Fact] | ||
public void ProvidersCreatedAndDisposedTest() | ||
{ | ||
var sdk = OpenTelemetrySdk.Create(builder => | ||
{ | ||
builder | ||
.WithLogging() | ||
.WithMetrics() | ||
.WithTracing(); | ||
}); | ||
|
||
var loggerProvider = sdk.LoggerProvider as LoggerProviderSdk; | ||
var meterProvider = sdk.MeterProvider as MeterProviderSdk; | ||
var tracerProvider = sdk.TracerProvider as TracerProviderSdk; | ||
|
||
Assert.NotNull(loggerProvider); | ||
Assert.NotNull(meterProvider); | ||
Assert.NotNull(tracerProvider); | ||
|
||
Assert.True(sdk.GetLoggerFactory() is not NullLoggerFactory); | ||
|
||
sdk.Dispose(); | ||
|
||
Assert.True(loggerProvider.Disposed); | ||
Assert.True(meterProvider.Disposed); | ||
Assert.True(tracerProvider.Disposed); | ||
} | ||
} |