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