[api-logs] Define OTEL1000 & OTEL1001 diagnostics and decorate APIs (#4963)

Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com>
This commit is contained in:
Mikel Blanchard 2023-12-08 09:31:54 -08:00 committed by GitHub
parent 93fd7d34a7
commit f5c116001f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 248 additions and 5 deletions

View File

@ -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}

View File

@ -9,6 +9,8 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<!-- Suppress warnings for repo code using experimental features -->
<NoWarn>$(NoWarn);OTEL1000;OTEL1001</NoWarn>
<!--temporarily disable. See 3958-->
<!--<AnalysisLevel>latest-All</AnalysisLevel>-->
</PropertyGroup>

View File

@ -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)

View File

@ -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.

View File

@ -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.

View File

@ -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:
<!-- When an experimental API is released or removed:
1) Move the section from above down here.
2) Delete the individual file from the repo and switch the link here to a
permalink to the last version.
3) Add the version info for when the API was released stable or removed. If
removed add details for alternative solution or reasoning.
-->
None

View File

@ -48,4 +48,3 @@ services:
- GF_FEATURE_TOGGLES_ENABLE=traceqlEditor
ports:
- "3000:3000"

View File

@ -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.
/// </summary>
/// <remarks><inheritdoc cref="Logger" path="/remarks"/></remarks>
#if NET8_0_OR_GREATER
[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)]
#endif
public
#else
/// <summary>
@ -21,7 +29,7 @@ public
/// </summary>
internal
#endif
interface IDeferredLoggerProviderBuilder
interface IDeferredLoggerProviderBuilder
{
/// <summary>
/// Register a callback action to configure the <see

View File

@ -6,6 +6,9 @@
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
#if NET8_0_OR_GREATER && EXPOSE_EXPERIMENTAL_FEATURES
using System.Diagnostics.CodeAnalysis;
#endif
using OpenTelemetry.Internal;
using OpenTelemetry.Trace;
@ -16,6 +19,9 @@ namespace OpenTelemetry.Logs;
/// Stores attributes to be added to a log message.
/// </summary>
/// <remarks><inheritdoc cref="Logger" path="/remarks"/></remarks>
#if NET8_0_OR_GREATER
[Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)]
#endif
public
#else
/// <summary>

View File

@ -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.
/// </summary>
/// <remarks><inheritdoc cref="Logger" path="/remarks"/></remarks>
#if NET8_0_OR_GREATER
[Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)]
#endif
public
#else
/// <summary>

View File

@ -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.
/// </summary>
/// <remarks><inheritdoc cref="Logger" path="/remarks"/></remarks>
#if NET8_0_OR_GREATER
[Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)]
#endif
public
#else
/// <summary>

View File

@ -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 <see cref="LogRecordSeverity"/> enum.
/// </summary>
/// <remarks><inheritdoc cref="Logger" path="/remarks"/></remarks>
#if NET8_0_OR_GREATER
[Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)]
#endif
public
#else
/// <summary>

View File

@ -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.
/// </summary>
/// <remarks><b>WARNING</b>: This is an experimental API which might change or be removed in the future. Use at your own risk.</remarks>
#if NET8_0_OR_GREATER
[Experimental(DiagnosticDefinitions.LogBridgeApiExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)]
#endif
public
#else
/// <summary>
@ -17,7 +25,7 @@ public
/// </summary>
internal
#endif
abstract class Logger
abstract class Logger
{
/// <summary>
/// Initializes a new instance of the <see cref="Logger"/> class.

View File

@ -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 <see cref="Logger"/>.
/// </summary>
/// <remarks><inheritdoc cref="Logger" path="/remarks"/></remarks>
#if NET8_0_OR_GREATER
[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)]
#endif
public
#else
/// <summary>
@ -36,6 +42,9 @@ internal
/// Gets a logger.
/// </summary>
/// <returns><see cref="Logger"/> instance.</returns>
#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 @@ internal
/// </summary>
/// <param name="name">Optional name identifying the instrumentation library.</param>
/// <returns><see cref="Logger"/> instance.</returns>
#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 @@ internal
/// <param name="name">Optional name identifying the instrumentation library.</param>
/// <param name="version">Optional version of the instrumentation library.</param>
/// <returns><see cref="Logger"/> instance.</returns>
#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 @@ internal
/// <param name="name">Optional name identifying the instrumentation library.</param>
/// <param name="logger"><see cref="Logger"/>.</param>
/// <returns><see langword="true"/> if the logger was created.</returns>
#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

View File

@ -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.
/// </summary>
/// <remarks><inheritdoc cref="Logger" path="/remarks"/></remarks>
#if NET8_0_OR_GREATER
[Experimental(DiagnosticDefinitions.LoggerProviderExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)]
#endif
public
#else
/// <summary>

View File

@ -15,6 +15,7 @@
<ItemGroup>
<Compile Include="$(RepoRoot)\src\Shared\ActivityHelperExtensions.cs" Link="Includes\ActivityHelperExtensions.cs" />
<Compile Include="$(RepoRoot)\src\Shared\DiagnosticDefinitions.cs" Link="Includes\DiagnosticDefinitions.cs" />
<Compile Include="$(RepoRoot)\src\Shared\ExceptionExtensions.cs" Link="Includes\ExceptionExtensions.cs" />
<Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\Shared\SemanticConventions.cs" Link="Includes\SemanticConventions.cs" />

View File

@ -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";
}