From f5c116001f8c57a42a707392d949dfc89109cd99 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 8 Dec 2023 09:31:54 -0800 Subject: [PATCH 1/2] [api-logs] Define OTEL1000 & OTEL1001 diagnostics and decorate APIs (#4963) Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> --- OpenTelemetry.sln | 18 +++++++- build/Common.props | 2 + docs/diagnostics/README.md | 23 ++++++++++ .../diagnostics/experimental-apis/OTEL1000.md | 42 +++++++++++++++++++ .../diagnostics/experimental-apis/OTEL1001.md | 35 ++++++++++++++++ docs/diagnostics/experimental-apis/README.md | 42 +++++++++++++++++++ docs/metrics/exemplars/docker-compose.yaml | 1 - .../Logs/IDeferredLoggerProviderBuilder.cs | 10 ++++- .../Logs/LogRecordAttributeList.cs | 6 +++ src/OpenTelemetry.Api/Logs/LogRecordData.cs | 7 ++++ .../Logs/LogRecordSeverity.cs | 8 ++++ .../Logs/LogRecordSeverityExtensions.cs | 8 ++++ src/OpenTelemetry.Api/Logs/Logger.cs | 10 ++++- src/OpenTelemetry.Api/Logs/LoggerProvider.cs | 18 ++++++++ .../Logs/LoggerProviderBuilder.cs | 8 ++++ .../OpenTelemetry.Api.csproj | 1 + src/Shared/DiagnosticDefinitions.cs | 14 +++++++ 17 files changed, 248 insertions(+), 5 deletions(-) create mode 100644 docs/diagnostics/README.md create mode 100644 docs/diagnostics/experimental-apis/OTEL1000.md create mode 100644 docs/diagnostics/experimental-apis/OTEL1001.md create mode 100644 docs/diagnostics/experimental-apis/README.md create mode 100644 src/Shared/DiagnosticDefinitions.cs diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 337b5953028..f4d72580bb3 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -32,7 +32,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7CB2F02E build\docfx.cmd = build\docfx.cmd build\docker-compose.net6.0.yml = build\docker-compose.net6.0.yml build\docker-compose.net7.0.yml = build\docker-compose.net7.0.yml - build\docker-compose.net8.0.yml = build\docker-compose.net8.0.yml build\finalize-publicapi.ps1 = build\finalize-publicapi.ps1 build\GlobalAttrExclusions.txt = build\GlobalAttrExclusions.txt build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png @@ -92,8 +91,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ ProjectSection(SolutionItems) = preProject .github\workflows\ci-aot-md.yml = .github\workflows\ci-aot-md.yml .github\workflows\ci-aot.yml = .github\workflows\ci-aot.yml - .github\workflows\ci-concurrency.yml = .github\workflows\ci-concurrency.yml .github\workflows\ci-concurrency-md.yml = .github\workflows\ci-concurrency-md.yml + .github\workflows\ci-concurrency.yml = .github\workflows\ci-concurrency.yml .github\workflows\ci-instrumentation-libraries-md.yml = .github\workflows\ci-instrumentation-libraries-md.yml .github\workflows\ci-instrumentation-libraries.yml = .github\workflows\ci-instrumentation-libraries.yml .github\workflows\ci-md.yml = .github\workflows\ci-md.yml @@ -266,6 +265,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A49299 ProjectSection(SolutionItems) = preProject src\Shared\ActivityHelperExtensions.cs = src\Shared\ActivityHelperExtensions.cs src\Shared\ActivityInstrumentationHelper.cs = src\Shared\ActivityInstrumentationHelper.cs + src\Shared\DiagnosticDefinitions.cs = src\Shared\DiagnosticDefinitions.cs src\Shared\ExceptionExtensions.cs = src\Shared\ExceptionExtensions.cs src\Shared\Guard.cs = src\Shared\Guard.cs src\Shared\HttpSemanticConventionHelper.cs = src\Shared\HttpSemanticConventionHelper.cs @@ -323,6 +323,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "getting-started-aspnetcore" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "links-creation", "docs\trace\links-creation-with-new-activities\links-creation.csproj", "{B4856711-6D4C-4246-A686-49458D4C1301}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "diagnostics", "diagnostics", "{52AF6D7D-9E66-4234-9A2C-5D16C6F22B40}" + ProjectSection(SolutionItems) = preProject + docs\diagnostics\README.md = docs\diagnostics\README.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "experimental-apis", "experimental-apis", "{17A22B0E-6EC3-4A39-B955-0A486AD06699}" + ProjectSection(SolutionItems) = preProject + docs\diagnostics\experimental-apis\OTEL1000.md = docs\diagnostics\experimental-apis\OTEL1000.md + docs\diagnostics\experimental-apis\OTEL1001.md = docs\diagnostics\experimental-apis\OTEL1001.md + docs\diagnostics\experimental-apis\README.md = docs\diagnostics\experimental-apis\README.md + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -650,6 +662,8 @@ Global {1C459B5B-C702-46FF-BF1A-EE795E420FFA} = {A49299FB-C5CD-4E0E-B7E1-B7867BBD67CC} {99B4D965-8782-4694-8DFA-B7A3630CEF60} = {3862190B-E2C5-418E-AFDC-DB281FB5C705} {B4856711-6D4C-4246-A686-49458D4C1301} = {5B7FB835-3FFF-4BC2-99C5-A5B5FAE3C818} + {52AF6D7D-9E66-4234-9A2C-5D16C6F22B40} = {7C87CAF9-79D7-4C26-9FFB-F3F1FB6911F1} + {17A22B0E-6EC3-4A39-B955-0A486AD06699} = {52AF6D7D-9E66-4234-9A2C-5D16C6F22B40} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {55639B5C-0770-4A22-AB56-859604650521} diff --git a/build/Common.props b/build/Common.props index 8a0a062ca07..758306e5571 100644 --- a/build/Common.props +++ b/build/Common.props @@ -9,6 +9,8 @@ true enable enable + + $(NoWarn);OTEL1000;OTEL1001 diff --git a/docs/diagnostics/README.md b/docs/diagnostics/README.md new file mode 100644 index 00000000000..2c959a6278e --- /dev/null +++ b/docs/diagnostics/README.md @@ -0,0 +1,23 @@ +# OpenTelemetry Diagnostics + +This document describes the diagnostic categories used in OpenTelemetry .NET +components. Diagnostics are used by the compiler to report information to users +about experimental and/or obsolete code being invoked or to suggest improvements +to specific code patterns identified through static analysis. + +## Experimental APIs + +Range: OTEL1XXX + +Experimental APIs exposed in OpenTelemetry .NET pre-relase builds. APIs are +exposed experimentally when either the OpenTelemetry Specification has +explicitly marked some feature as +[experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md) +or when the SIG members are still working through the design for a feature and +want to solicit feedback from the community. + +> **Note** Experimental APIs are exposed as `public` in pre-release builds and +> `internal` in stable builds. + +For defined diagnostics see: [OpenTelemetry .NET Experimental +APIs](./experimental-apis/README.md) diff --git a/docs/diagnostics/experimental-apis/OTEL1000.md b/docs/diagnostics/experimental-apis/OTEL1000.md new file mode 100644 index 00000000000..5febb4f7ab4 --- /dev/null +++ b/docs/diagnostics/experimental-apis/OTEL1000.md @@ -0,0 +1,42 @@ +# OpenTelemetry .NET Diagnostic: OTEL1000 + +## Overview + +This is an Experimental API diagnostic covering the following APIs: + +* `LoggerProviderBuilder` +* `LoggerProvider` +* `IDeferredLoggerProviderBuilder` + +Experimental APIs may be changed or removed in the future. + +## Details + +The OpenTelemetry Specification defines a `LoggerProvider` as part of its +[API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/bridge-api.md) +& +[SDK](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/sdk.md) +components. + +The SDK allows calling `Shutdown` and `ForceFlush` on the `LoggerProvider` and +also allows processors to be added dynamically to a pipeline after its creation. + +Today the OpenTelemetry .NET log pipeline is built on top of the +Microsoft.Extensions.Logging `ILogger` \ `ILoggerProvider` \ `ILoggerFactory` +APIs which do not expose such features. + +We also have an issue with the `ILoggingBuilder.AddOpenTelemetry` API in that it +interacts with the `OpenTelemetryLoggerOptions` class. Options classes are NOT +available until the `IServiceProvider` is available and services can no longer +be registered at that point. This prevents the current logging pipeline from +exposing the same dependency injection surface we have for traces and metrics. + +We are exposing these APIs to solve these issues and gather feedback about their +usefulness. + +## Log Bridge API + +The OpenTelemetry Specification defines a Log Bridge API which is rooted off of +the `LoggerProvider` (`GetLogger`) and exposes a `Logger` API to submit log +records. See [OTEL1001](./OTEL1001.md) for details about the Log Bridge API +implementation status. diff --git a/docs/diagnostics/experimental-apis/OTEL1001.md b/docs/diagnostics/experimental-apis/OTEL1001.md new file mode 100644 index 00000000000..66c1f7627ec --- /dev/null +++ b/docs/diagnostics/experimental-apis/OTEL1001.md @@ -0,0 +1,35 @@ +# OpenTelemetry .NET Diagnostic: OTEL1001 + +## Overview + +This is an Experimental API diagnostic covering the following APIs: + +* `LoggerProvider.GetLogger` +* `Logger` +* `LogRecordAttributeList` +* `LogRecordData` +* `LogRecordSeverity` + +Experimental APIs may be changed or removed in the future. + +## Details + +The OpenTelemetry Specification defines a [Logs Bridge +API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/bridge-api.md). + +The log bridge API is used by library authors to build log appenders which route +messages from different log frameworks into OpenTelemetry. + +Today the OpenTelemetry .NET log pipeline is built on top of the +Microsoft.Extensions.Logging `ILogger` \ `ILoggerProvider` \ `ILoggerFactory` +APIs. + +We are exposing these APIs gather feedback about their usefulness. An +alternative approach may be taken which would be to append into `ILogger` +instead of OpenTelemetry directly. + +## LoggerProvider API + +The OpenTelemetry Specification defines a `LoggerProvider` API. See +[OTEL1000](./OTEL1000.md) for details about the `LoggerProvider` implementation +status. diff --git a/docs/diagnostics/experimental-apis/README.md b/docs/diagnostics/experimental-apis/README.md new file mode 100644 index 00000000000..6333099f527 --- /dev/null +++ b/docs/diagnostics/experimental-apis/README.md @@ -0,0 +1,42 @@ +# OpenTelemetry .NET Experimental APIs + +This document describes experimental APIs exposed in OpenTelemetry .NET +pre-relase builds. APIs are exposed experimentally when either the OpenTelemetry +Specification has explicitly marked some feature as +[experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md) +or when the SIG members are still working through the design for a feature and +want to solicit feedback from the community. + +> **Note** +> Experimental APIs are exposed as `public` in pre-release builds and `internal` +> in stable builds. + +## Active + +Experimental APIs available in the pre-release builds: + +### OTEL1000 + +Description: `LoggerProvider` and `LoggerProviderBuilder` + +Details: [OTEL1000](./OTEL1000.md) + +### OTEL1001 + +Description: Log Bridge API + +Details: [OTEL1001](./OTEL1001.md) + +## Inactive + +Experimental APIs which have been released stable or removed: + + + +None diff --git a/docs/metrics/exemplars/docker-compose.yaml b/docs/metrics/exemplars/docker-compose.yaml index 87cd7a6c6d6..c8cc94fa4b1 100644 --- a/docs/metrics/exemplars/docker-compose.yaml +++ b/docs/metrics/exemplars/docker-compose.yaml @@ -48,4 +48,3 @@ services: - GF_FEATURE_TOGGLES_ENABLE=traceqlEditor ports: - "3000:3000" - diff --git a/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs b/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs index b7f5f3b0811..70528fe6cb7 100644 --- a/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Logs/IDeferredLoggerProviderBuilder.cs @@ -3,6 +3,11 @@ #nullable enable +#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES +using System.Diagnostics.CodeAnalysis; +using OpenTelemetry.Internal; +#endif + namespace OpenTelemetry.Logs; #if EXPOSE_EXPERIMENTAL_FEATURES @@ -12,6 +17,9 @@ namespace OpenTelemetry.Logs; /// dependency injection. /// /// +#if NET8_0_OR_GREATER +[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public #else /// @@ -21,7 +29,7 @@ namespace OpenTelemetry.Logs; /// internal #endif - interface IDeferredLoggerProviderBuilder +interface IDeferredLoggerProviderBuilder { /// /// Register a callback action to configure the /// +#if NET8_0_OR_GREATER +[Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public #else /// diff --git a/src/OpenTelemetry.Api/Logs/LogRecordData.cs b/src/OpenTelemetry.Api/Logs/LogRecordData.cs index ab5af385266..cf7cc550dec 100644 --- a/src/OpenTelemetry.Api/Logs/LogRecordData.cs +++ b/src/OpenTelemetry.Api/Logs/LogRecordData.cs @@ -4,6 +4,10 @@ #nullable enable using System.Diagnostics; +#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES +using System.Diagnostics.CodeAnalysis; +using OpenTelemetry.Internal; +#endif namespace OpenTelemetry.Logs; @@ -12,6 +16,9 @@ namespace OpenTelemetry.Logs; /// Stores details about a log message. /// /// +#if NET8_0_OR_GREATER +[Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public #else /// diff --git a/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs b/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs index 760f6882997..d3a0442cabb 100644 --- a/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs +++ b/src/OpenTelemetry.Api/Logs/LogRecordSeverity.cs @@ -3,6 +3,11 @@ #nullable enable +#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES +using System.Diagnostics.CodeAnalysis; +using OpenTelemetry.Internal; +#endif + namespace OpenTelemetry.Logs; #if EXPOSE_EXPERIMENTAL_FEATURES @@ -10,6 +15,9 @@ namespace OpenTelemetry.Logs; /// Describes the severity level of a log record. /// /// +#if NET8_0_OR_GREATER +[Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public #else /// diff --git a/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs b/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs index c7f180294b7..cf22c26a23f 100644 --- a/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs +++ b/src/OpenTelemetry.Api/Logs/LogRecordSeverityExtensions.cs @@ -3,6 +3,11 @@ #nullable enable +#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES +using System.Diagnostics.CodeAnalysis; +using OpenTelemetry.Internal; +#endif + namespace OpenTelemetry.Logs; #if EXPOSE_EXPERIMENTAL_FEATURES @@ -10,6 +15,9 @@ namespace OpenTelemetry.Logs; /// Contains extension methods for the enum. /// /// +#if NET8_0_OR_GREATER +[Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public #else /// diff --git a/src/OpenTelemetry.Api/Logs/Logger.cs b/src/OpenTelemetry.Api/Logs/Logger.cs index 6db679016fb..b112a81cdbb 100644 --- a/src/OpenTelemetry.Api/Logs/Logger.cs +++ b/src/OpenTelemetry.Api/Logs/Logger.cs @@ -3,6 +3,11 @@ #nullable enable +#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES +using System.Diagnostics.CodeAnalysis; +using OpenTelemetry.Internal; +#endif + namespace OpenTelemetry.Logs; #if EXPOSE_EXPERIMENTAL_FEATURES @@ -10,6 +15,9 @@ namespace OpenTelemetry.Logs; /// Logger is the class responsible for creating log records. /// /// WARNING: This is an experimental API which might change or be removed in the future. Use at your own risk. +#if NET8_0_OR_GREATER +[Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public #else /// @@ -17,7 +25,7 @@ namespace OpenTelemetry.Logs; /// internal #endif - abstract class Logger +abstract class Logger { /// /// Initializes a new instance of the class. diff --git a/src/OpenTelemetry.Api/Logs/LoggerProvider.cs b/src/OpenTelemetry.Api/Logs/LoggerProvider.cs index fd8099715cf..f29ec12d38c 100644 --- a/src/OpenTelemetry.Api/Logs/LoggerProvider.cs +++ b/src/OpenTelemetry.Api/Logs/LoggerProvider.cs @@ -6,6 +6,9 @@ #if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER using System.Diagnostics.CodeAnalysis; #endif +#if NET8_0_OR_GREATER +using OpenTelemetry.Internal; +#endif namespace OpenTelemetry.Logs; @@ -14,6 +17,9 @@ namespace OpenTelemetry.Logs; /// LoggerProvider is the entry point of the OpenTelemetry API. It provides access to . /// /// +#if NET8_0_OR_GREATER +[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public #else /// @@ -36,6 +42,9 @@ protected LoggerProvider() /// Gets a logger. /// /// instance. +#if NET8_0_OR_GREATER + [Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public Logger GetLogger() => this.GetLogger(name: null, version: null); @@ -44,6 +53,9 @@ public Logger GetLogger() /// /// Optional name identifying the instrumentation library. /// instance. +#if NET8_0_OR_GREATER + [Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public Logger GetLogger(string? name) => this.GetLogger(name, version: null); @@ -53,6 +65,9 @@ public Logger GetLogger(string? name) /// Optional name identifying the instrumentation library. /// Optional version of the instrumentation library. /// instance. +#if NET8_0_OR_GREATER + [Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public Logger GetLogger(string? name, string? version) { if (!this.TryCreateLogger(name, out var logger)) @@ -71,6 +86,9 @@ public Logger GetLogger(string? name, string? version) /// Optional name identifying the instrumentation library. /// . /// if the logger was created. +#if NET8_0_OR_GREATER + [Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif protected virtual bool TryCreateLogger( string? name, #if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER diff --git a/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs b/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs index 617a51ead09..3fa9c6fc743 100644 --- a/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Logs/LoggerProviderBuilder.cs @@ -3,6 +3,11 @@ #nullable enable +#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES +using System.Diagnostics.CodeAnalysis; +using OpenTelemetry.Internal; +#endif + namespace OpenTelemetry.Logs; #if EXPOSE_EXPERIMENTAL_FEATURES @@ -10,6 +15,9 @@ namespace OpenTelemetry.Logs; /// LoggerProviderBuilder base class. /// /// +#if NET8_0_OR_GREATER +[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)] +#endif public #else /// diff --git a/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj b/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj index 27aa7389a8d..0a781a94173 100644 --- a/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj +++ b/src/OpenTelemetry.Api/OpenTelemetry.Api.csproj @@ -15,6 +15,7 @@ + diff --git a/src/Shared/DiagnosticDefinitions.cs b/src/Shared/DiagnosticDefinitions.cs new file mode 100644 index 00000000000..7e6fb6af6cf --- /dev/null +++ b/src/Shared/DiagnosticDefinitions.cs @@ -0,0 +1,14 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +namespace OpenTelemetry.Internal; + +internal static class DiagnosticDefinitions +{ + public const string ExperimentalApiUrlFormat = "https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/diagnostics/experimental-apis/README.md#{0}"; + + public const string LoggerProviderExperimentalApi = "OTEL1000"; + public const string LogBridgeApiExperimentalApi = "OTEL1001"; +} From f075128b1253be77962277ae946bb7b2f9d878da Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Fri, 8 Dec 2023 20:43:00 +0100 Subject: [PATCH 2/2] Solve 404 error in unit test (#5145) --- .../BasicTests.cs | 18 +++++++------- test/TestApp.AspNetCore/Program.cs | 2 ++ test/TestApp.AspNetCore/TestMiddleware.cs | 24 +++++++++++++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 test/TestApp.AspNetCore/TestMiddleware.cs diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index 9888ab9a172..2d3f6d2c21a 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -947,6 +947,7 @@ public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHan int numberOfUnSubscribedEvents = 0; int numberOfSubscribedEvents = 0; int numberOfExceptionCallbacks = 0; + bool exceptionHandled = false; // configure SDK this.tracerProvider = Sdk.CreateTracerProviderBuilder() @@ -991,18 +992,18 @@ public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHan }) .Build(); + TestMiddleware.Create(builder => builder + .UseExceptionHandler(handler => + handler.Run(async (ctx) => + { + exceptionHandled = true; + await ctx.Response.WriteAsync("handled"); + }))); + using (var client = this.factory .WithWebHostBuilder(builder => { builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); - builder.Configure(app => app - .UseExceptionHandler(handler => - { - handler.Run(async (ctx) => - { - await ctx.Response.WriteAsync("handled"); - }); - })); }) .CreateClient()) { @@ -1020,6 +1021,7 @@ public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHan Assert.Equal(0, numberOfExceptionCallbacks); Assert.Equal(0, numberOfUnSubscribedEvents); Assert.Equal(2, numberOfSubscribedEvents); + Assert.True(exceptionHandled); } public void Dispose() diff --git a/test/TestApp.AspNetCore/Program.cs b/test/TestApp.AspNetCore/Program.cs index 49b801fb6c3..06071eab4bd 100644 --- a/test/TestApp.AspNetCore/Program.cs +++ b/test/TestApp.AspNetCore/Program.cs @@ -47,6 +47,8 @@ public static void Main(string[] args) app.UseMiddleware(); + app.AddTestMiddleware(); + app.Run(); } } diff --git a/test/TestApp.AspNetCore/TestMiddleware.cs b/test/TestApp.AspNetCore/TestMiddleware.cs new file mode 100644 index 00000000000..39acf58db3d --- /dev/null +++ b/test/TestApp.AspNetCore/TestMiddleware.cs @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace TestApp.AspNetCore; + +public static class TestMiddleware +{ + private static readonly AsyncLocal?> Current = new(); + + public static IApplicationBuilder AddTestMiddleware(this IApplicationBuilder builder) + { + if (Current.Value is { } configure) + { + configure(builder); + } + + return builder; + } + + public static void Create(Action action) + { + Current.Value = action; + } +}