diff --git a/.github/workflows/linux-ci-md.yml b/.github/workflows/ci-md.yml
similarity index 74%
rename from .github/workflows/linux-ci-md.yml
rename to .github/workflows/ci-md.yml
index 5b7008872e4..1dde2355a3e 100644
--- a/.github/workflows/linux-ci-md.yml
+++ b/.github/workflows/ci-md.yml
@@ -5,7 +5,7 @@
# IMPORTANT: This workflow MUST use the same 'name' as the non -md workflow.
-name: Linux
+name: Build
on:
pull_request:
@@ -15,11 +15,14 @@ on:
jobs:
build-test:
- runs-on: ubuntu-latest
-
strategy:
matrix:
- version: [net6.0]
+ os: [ windows-latest, ubuntu-latest ]
+ version: [ net462, net6.0, net7.0 ]
+ exclude:
+ - os: ubuntu-latest
+ version: net462
+ runs-on: ubuntu-latest
steps:
- - run: 'echo "No build required"'
+ - run: 'echo "No build required"'
diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/ci.yml
similarity index 63%
rename from .github/workflows/windows-ci.yml
rename to .github/workflows/ci.yml
index b88ef208dd2..216e71c5248 100644
--- a/.github/workflows/windows-ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,4 +1,4 @@
-name: Windows
+name: Build
on:
push:
@@ -12,12 +12,16 @@ on:
jobs:
build-test:
- runs-on: windows-latest
-
strategy:
+ fail-fast: false # ensures the entire test matrix is run, even if one permutation fails
matrix:
- version: [net462,net6.0,net7.0]
+ os: [ windows-latest, ubuntu-latest ]
+ version: [ net462, net6.0, net7.0 ]
+ exclude:
+ - os: ubuntu-latest
+ version: net462
+ runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
with:
@@ -34,4 +38,4 @@ jobs:
run: dotnet build --configuration Release --no-restore
- name: Test ${{ matrix.version }}
- run: dotnet test **\bin\**\${{ matrix.version }}\*Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed"
+ run: dotnet test **/bin/**/${{ matrix.version }}/*Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed"
diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml
deleted file mode 100644
index 6834fdc7f8b..00000000000
--- a/.github/workflows/linux-ci.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: Linux
-
-on:
- push:
- branches: [ 'main*' ]
- paths-ignore:
- - '**.md'
- pull_request:
- branches: [ 'main*' ]
- paths-ignore:
- - '**.md'
-
-jobs:
- build-test:
- runs-on: ubuntu-latest
-
- strategy:
- matrix:
- version: [net6.0, net7.0]
-
- steps:
- - uses: actions/checkout@v3
- with:
- fetch-depth: 0 # fetching all
-
- - uses: actions/setup-dotnet@v3.0.3
- with:
- dotnet-version: '6.0.x'
-
- - uses: actions/setup-dotnet@v3.0.3
- with:
- dotnet-version: '7.0.x'
-
- - name: Install dependencies
- run: dotnet restore
-
- - name: Build
- run: dotnet build --configuration Release --no-restore
-
- - name: Test ${{ matrix.version }}
- run: dotnet test **/bin/**/${{ matrix.version }}/*.Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed"
diff --git a/.github/workflows/windows-ci-md.yml b/.github/workflows/windows-ci-md.yml
deleted file mode 100644
index 894773ddb37..00000000000
--- a/.github/workflows/windows-ci-md.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-# Syntax: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
-# See also: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
-
-# Description: This workflow exists to unblock documentation-only PRs.
-
-# IMPORTANT: This workflow MUST use the same 'name' as the non -md workflow.
-
-name: Windows
-
-on:
- pull_request:
- branches: [ 'main*' ]
- paths:
- - '**.md'
-
-jobs:
- build-test:
- runs-on: ubuntu-latest
-
- strategy:
- matrix:
- version: [net462,net6.0,net7.0]
-
- steps:
- - run: 'echo "No build required"'
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 80311886304..b94b3d3678d 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -2,6 +2,7 @@
"cSpell.words": [
"appsettings",
"asax",
+ "bankwar",
"cijo",
"cncf",
"codebases",
@@ -50,6 +51,7 @@
"unencrypted",
"unvalidated",
"utkarsh",
+ "vishwesh",
"xunit",
"zipkin",
"zpages"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9aa487e4afa..6f713ae1146 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -59,7 +59,7 @@ of Windows.
* Visual Studio 2022+ or Visual Studio Code
* .NET Framework 4.6.2+
-**NOTE** : Visual Studio 2022 preview is **recommended** due to projects
+**Note:** : Visual Studio 2022 preview is **recommended** due to projects
targeting `.net7.0` which is in preview currently.
### Public API
diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln
index 1b961fc5f7b..471a28502a8 100644
--- a/OpenTelemetry.sln
+++ b/OpenTelemetry.sln
@@ -93,19 +93,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
ProjectSection(SolutionItems) = preProject
.github\workflows\apicompatibility.yml = .github\workflows\apicompatibility.yml
.github\workflows\code-coverage.yml = .github\workflows\code-coverage.yml
+ .github\workflows\ci.yml = .github\workflows\ci.yml
+ .github\workflows\ci-md.yml = .github\workflows\ci-md.yml
.github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml
.github\workflows\docfx.yml = .github\workflows\docfx.yml
.github\workflows\dotnet-format-md.yml = .github\workflows\dotnet-format-md.yml
.github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml
.github\workflows\integration-md.yml = .github\workflows\integration-md.yml
.github\workflows\integration.yml = .github\workflows\integration.yml
- .github\workflows\linux-ci-md.yml = .github\workflows\linux-ci-md.yml
- .github\workflows\linux-ci.yml = .github\workflows\linux-ci.yml
.github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml
.github\workflows\publish-packages-1.0.yml = .github\workflows\publish-packages-1.0.yml
.github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml
- .github\workflows\windows-ci-md.yml = .github\workflows\windows-ci-md.yml
- .github\workflows\windows-ci.yml = .github\workflows\windows-ci.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C1542297-8763-4DF4-957C-489ED771C21D}"
diff --git a/README.md b/README.md
index 5ef0b03e1a7..f681bc1709c 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,11 @@ files.
Logs](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol#otlp-logs)
is still non-stable.
+See [Spec Compliance
+Matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/main/spec-compliance-matrix.md)
+to understand which portions of the specification has been implemented in this
+repo.
+
## Getting Started
If you are new here, please read the getting started docs:
@@ -70,8 +75,10 @@ libraries](https://github.com/open-telemetry/opentelemetry-specification/blob/ma
* [Prometheus AspNetCore](./src/OpenTelemetry.Exporter.Prometheus.AspNetCore/README.md)
* [Zipkin](./src/OpenTelemetry.Exporter.Zipkin/README.md)
-See the [OpenTelemetry registry](https://opentelemetry.io/registry/?s=net) for
-more exporters.
+See the [OpenTelemetry registry](https://opentelemetry.io/registry/?s=net) and
+[OpenTelemetry .NET Contrib
+repo](https://github.com/open-telemetry/opentelemetry-dotnet-contrib) for more
+components.
## Extensibility
diff --git a/build/Common.props b/build/Common.props
index ea961e63739..0906bb0a67b 100644
--- a/build/Common.props
+++ b/build/Common.props
@@ -43,7 +43,7 @@
[2.8.0,3.0)[1.2.0-beta.435,2.0)1.4.0
- 7.0.0-rc.2.22472.3
+ 7.0.04.7.04.7.24.5.4
diff --git a/docs/metrics/customizing-the-sdk/README.md b/docs/metrics/customizing-the-sdk/README.md
index bf5ecdae364..d700d6da54f 100644
--- a/docs/metrics/customizing-the-sdk/README.md
+++ b/docs/metrics/customizing-the-sdk/README.md
@@ -251,7 +251,7 @@ default boundaries. This requires the use of
new ExplicitBucketHistogramConfiguration { Boundaries = new double[] { 10, 20 } })
// If you provide an empty `double` array as `Boundaries` to the `ExplicitBucketHistogramConfiguration`,
- // the SDK will only export the sum and count for the measurements.
+ // the SDK will only export the sum, count, min and max for the measurements.
// There are no buckets exported in this case.
.AddView(
instrumentName: "MyHistogram",
@@ -276,7 +276,7 @@ default boundaries. This requires the use of
})
```
-**NOTE:** The SDK currently does not support any changes to `Aggregation` type
+**Note:** The SDK currently does not support any changes to `Aggregation` type
by using Views.
See [Program.cs](./Program.cs) for a complete example.
@@ -329,9 +329,9 @@ ignored. The SDK chooses the key/value combinations in the order in which they
are emitted. `SetMaxMetricPointsPerMetricStream` can be used to override the
default.
-**NOTE**: One `MetricPoint` is reserved for every `MetricStream` for the special
-case where there is no key/value pair associated with the metric. The maximum
-number of `MetricPoint`s has to accommodate for this special case.
+**Note:**: One `MetricPoint` is reserved for every `MetricStream` for the
+special case where there is no key/value pair associated with the metric. The
+maximum number of `MetricPoint`s has to accommodate for this special case.
Consider the below example. Here we set the maximum number of `MetricPoint`s
allowed to be `3`. This means that for every `MetricStream`, the SDK will export
@@ -395,7 +395,7 @@ AnotherFruitCounter.Add(5, new("name", "banana"), new("color", "yellow")); // Ex
AnotherFruitCounter.Add(4, new("name", "mango"), new("color", "yellow")); // Not exported
```
-**NOTE:** The above limit is *per* metric stream, and applies to all the metric
+**Note:** The above limit is *per* metric stream, and applies to all the metric
streams. There is no ability to apply different limits for each instrument at
this moment.
diff --git a/docs/metrics/getting-started-prometheus-grafana/README.md b/docs/metrics/getting-started-prometheus-grafana/README.md
index 1e2f2e35e99..8c57ed65853 100644
--- a/docs/metrics/getting-started-prometheus-grafana/README.md
+++ b/docs/metrics/getting-started-prometheus-grafana/README.md
@@ -172,18 +172,19 @@ Follow the instructions in the Grafana getting started
[doc](https://grafana.com/docs/grafana/latest/getting-started/getting-started/#step-2-log-in)
to log in.
-After successfully logging in, click on the Configuration icon
-on the panel at the left hand side, and click on Prometheus.
-Type in the default endpoint of Prometheus as suggested by the UI
-as the value for the URI.
+After successfully logging in, hover on the Configuration icon
+on the panel at the left hand side, and click on Plugins.
+Find and click on the Prometheus plugin. Next click on
+`Create a Prometheus data source` button. Type in the default endpoint of
+Prometheus as suggested by the UI as the value for the URI.
```console
http://localhost:9090
```
-Then, click on the Explore icon on the left panel of
-the website - we should be able to write some queries to explore our metrics
-now!
+At the bottom of the page click `Save & test` to ensure the data source is
+working. Then, click on the `Explore` button - we should be able to write
+some queries to explore our metrics now!
Feel free to find some handy PromQL
[here](https://promlabs.com/promql-cheat-sheet/).
diff --git a/docs/trace/customizing-the-sdk/README.md b/docs/trace/customizing-the-sdk/README.md
index d162574a954..ead1fd85986 100644
--- a/docs/trace/customizing-the-sdk/README.md
+++ b/docs/trace/customizing-the-sdk/README.md
@@ -38,9 +38,10 @@ tracerProvider.Dispose()
```
**Note:** The `Sdk.CreateTracerProviderBuilder()` API is available for all
-runtimes. Additionally, for `ASP.NET Core` and [.NET Generic
-Host](https://learn.microsoft.com/dotnet/core/extensions/generic-host) users,
-helper extensions are provided in the
+runtimes. Additionally, for [ASP.NET
+Core](https://learn.microsoft.com/aspnet/core/fundamentals/host/web-host) and
+[.NET Generic](https://learn.microsoft.com/dotnet/core/extensions/generic-host)
+host users, helper extensions are provided in the
[OpenTelemetry.Extensions.Hosting](../../../src/OpenTelemetry.Extensions.Hosting/README.md)
package to simplify configuration and management of the `TracerProvider`.
@@ -109,7 +110,7 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder()
See [Program.cs](./Program.cs) for complete example.
-**Note** A common mistake while configuring `TracerProvider` is forgetting to
+**Note:** A common mistake while configuring `TracerProvider` is forgetting to
add all `ActivitySources` to the provider. It is recommended to leverage the
wild card subscription model where it makes sense. For example, if your
application is expecting to enable tracing from a number of libraries from a
@@ -153,8 +154,8 @@ processor classes `SimpleExportProcessor` & `BatchExportProcessor` are provided
to support invoking exporters through the processor pipeline and implement the
standard behaviors prescribed by the OpenTelemetry specification.
-**Note** The SDK only ever invokes processors and has no direct knowledge of any
-registered exporters.
+**Note:** The SDK only ever invokes processors and has no direct knowledge of
+any registered exporters.
#### Processor Configuration
@@ -175,11 +176,11 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder()
tracerProvider.AddProcessor(new MyProcessor3());
```
-**Note** A `TracerProvider` assumes ownership of **all** processors added to it.
-This means that the provider will call the `Shutdown` method on all registered
-processors when it is shutting down and call the `Dispose` method on all
-registered processors when it is disposed. If multiple providers are being set
-up in an application then separate instances of processors **MUST** be
+**Note:** A `TracerProvider` assumes ownership of **all** processors added to
+it. This means that the provider will call the `Shutdown` method on all
+registered processors when it is shutting down and call the `Dispose` method on
+all registered processors when it is disposed. If multiple providers are being
+set up in an application then separate instances of processors **MUST** be
registered on each provider. Otherwise shutting down one provider will cause the
shared processor(s) in other providers to be shut down as well which may lead to
undesired results.
@@ -213,12 +214,12 @@ For exporting purposes, the SDK provides the following built-in processors:
: This is an exporting processor which passes telemetry to the configured
exporter immediately without any batching.
-**Note** A special processor
+**Note:** A special processor
[CompositeProcessor<T>](../../../src/OpenTelemetry/CompositeProcessor.cs)
is used by the SDK to chain multiple processors together and may be used as
needed by users to define sub-pipelines.
-**Note** The processors shipped from this SDK are generic implementations and
+**Note:** The processors shipped from this SDK are generic implementations and
support tracing and logging by implementing `Activity` and `LogRecord`
respectively.
@@ -240,19 +241,6 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder()
.Build();
```
-To make exporter registration easier an `AddExporter` extension is also
-provided. The snippet below shows how to add an export processor using
- `AddExporter` to the provider before it is built.
-
- ```csharp
-using OpenTelemetry;
-using OpenTelemetry.Trace;
-
-var tracerProvider = Sdk.CreateTracerProviderBuilder()
- .AddExporter(ExportProcessorType.Batch)
- .Build();
-```
-
It is also common for exporters to provide their own extensions to simplify
registration. The snippet below shows how to add the
[JaegerExporter](../../../src/OpenTelemetry.Exporter.Jaeger/README.md) to the
@@ -359,10 +347,314 @@ using OpenTelemetry;
Sdk.SetDefaultTextMapPropagator(new MyCustomPropagator());
```
-## Dependency Injection Support
+## Dependency injection support
+
+**Note:** This information applies to the OpenTelemetry SDK version 1.4.0 and
+newer only.
+
+The SDK implementation of `TracerProviderBuilder` is backed by an
+`IServiceCollection` and supports a wide range of APIs to enable what is
+generally known as [dependency
+injection](https://learn.microsoft.com/dotnet/core/extensions/dependency-injection).
+
+### Dependency injection examples
-// TODO: Add details here
+For the below examples imagine a processor with this constructor:
+
+```csharp
+public class MyCustomProcessor : BaseProcessor
+{
+ public MyCustomProcessor(MyCustomService myCustomService)
+ {
+ // Implementation not important
+ }
+}
+```
+
+We want to inject `MyCustomService` dependency into our `MyCustomProcessor`
+instance.
+
+#### Using Sdk.CreateTracerProviderBuilder()
+
+To register `MyCustomProcessor` and `MyCustomService` we can use the
+`ConfigureServices` and `AddProcessor` methods:
+
+```csharp
+using var tracerProvider = Sdk.CreateTracerProviderBuilder()
+ .ConfigureServices(services =>
+ {
+ services.AddSingleton();
+ })
+ .AddProcessor()
+ .Build();
+```
+
+When using the `Sdk.CreateTracerProviderBuilder` method the `TracerProvider`
+owns its own `IServiceCollection`. It will only be able to see services
+registered into that collection.
+
+**Note:** It is important to correctly manage the lifecycle of the
+`TracerProvider`. See [Building a TracerProvider](#building-a-tracerprovider)
+for details.
+
+#### Using the OpenTelemetry.Extensions.Hosting package
+
+**Note:** If you are authoring an [ASP.NET Core
+application](https://learn.microsoft.com/aspnet/core/fundamentals/host/web-host)
+or using the [.NET Generic
+Host](https://learn.microsoft.com/dotnet/core/extensions/generic-host) the
+[OpenTelemetry.Extensions.Hosting](../../../src/OpenTelemetry.Extensions.Hosting/README.md)
+package is the recommended mechanism.
+
+```csharp
+var appBuilder = WebApplication.CreateBuilder(args);
-## Configuration files and Environment Variables
+appBuilder.Services.AddSingleton();
-// TODO: Add details here
+appBuilder.Services.AddOpenTelemetryTracing(builder => builder
+ .AddProcessor();
+```
+
+When using the `AddOpenTelemetryTracing` method the `TracerProvider` does not
+own its `IServiceCollection` and instead registers into an existing collection
+(typically the collection used is the one managed by the application host). The
+`TracerProviderBuilder` will be able to access all services registered into that
+collection. For lifecycle management, an [IHostedService
+](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.ihostedservice)
+is used to automatically start the `TracerProvider` when the host starts and the
+host will automatically shutdown and dispose the `TracerProvider` when it is
+shutdown.
+
+**Note:** Multiple calls to `AddOpenTelemetryTracing` will configure the same
+`TracerProvider`. Only a single `TraceProvider` may exist in an
+`IServiceCollection` \ `IServiceProvider`.
+
+### Dependency injection `TracerProviderBuilder` extension method reference
+
+* `AddInstrumentation`: Adds instrumentation of type `T` into the
+ `TracerProvider`.
+
+* `AddProcessor`: Adds a processor of type `T` (must derive from
+ `BaseProcessor`) into the `TracerProvider`.
+
+* `SetSampler`: Register type `T` (must derive from `Sampler`) as the sampler
+ for the `TracerProvider`.
+
+* `ConfigureServices`: Registers a callback function for configuring the
+ `IServiceCollection` used by the `TracerProviderBuilder`. **Note:**
+ `ConfigureServices` may only be called before the `IServiceProvider` has been
+ created after which point service can no longer be added.
+
+* `ConfigureBuilder`: Registers a callback function for configuring the
+ `TracerProviderBuilder` once the `IServiceProvider` is available.
+
+ ```csharp
+ var appBuilder = WebApplication.CreateBuilder(args);
+
+ appBuilder.Services.AddOpenTelemetryTracing(builder => builder
+ .ConfigureBuilder((sp, builder) =>
+ {
+ builder.AddProcessor(
+ new MyCustomProcessor(
+ // Note: This example uses the final IServiceProvider once it is available.
+ sp.GetRequiredService(),
+ sp.GetRequiredService>().Value));
+ }));
+ ```
+
+ **Note:** `ConfigureBuilder` is an advanced API and is expected to be used
+ primarily by library authors. Services may NOT be added to the
+ `IServiceCollection` during `ConfigureBuilder` because the `IServiceProvider`
+ has already been created.
+
+## Configuration files and environment variables
+
+**Note:** This information applies to the OpenTelemetry SDK version 1.4.0 and
+newer only.
+
+The OpenTelemetry .NET SDK integrates with the standard
+[configuration](https://learn.microsoft.com/dotnet/core/extensions/configuration)
+and [options](https://learn.microsoft.com/dotnet/core/extensions/options)
+patterns provided by .NET. The configuration pattern supports building a
+composited view of settings from external sources and the options pattern helps
+use those settings to configure features by binding to simple classes.
+
+### How to set up configuration
+
+The following sections describe how to set up configuration based on the host
+and OpenTelemetry API being used.
+
+#### Using .NET hosts with the OpenTelemetry.Extensions.Hosting package
+
+[ASP.NET
+Core](https://learn.microsoft.com/aspnet/core/fundamentals/host/web-host) and
+[.NET Generic](https://learn.microsoft.com/dotnet/core/extensions/generic-host)
+host users using the
+[OpenTelemetry.Extensions.Hosting](../../../src/OpenTelemetry.Extensions.Hosting/README.md)
+package do not need to do anything extra to enable `IConfiguration` support. The
+OpenTelemetry SDK will automatically use whatever `IConfiguration` has been
+supplied by the host. The host by default will load environment variables,
+command-line arguments, and config files. See [Configuration in
+.NET](https://learn.microsoft.com/dotnet/core/extensions/configuration) for
+details.
+
+#### Using Sdk.CreateTracerProviderBuilder directly
+
+By default the `Sdk.CreateTracerProviderBuilder` API will create an
+`IConfiguration` from environment variables. The following example shows how to
+customize the `IConfiguration` used by `Sdk.CreateTracerProviderBuilder` for
+cases where additional sources beyond environment variables are required.
+
+```csharp
+// Build configuration from sources. Order is important.
+var configuration = new ConfigurationBuilder()
+ .AddJsonFile("./myOTelSettings.json")
+ .AddEnvironmentVariables()
+ .AddCommandLine(args)
+ .Build();
+
+// Set up a TracerProvider using the configuration.
+var provider = Sdk.CreateTracerProviderBuilder()
+ .ConfigureServices(services => services.AddSingleton(configuration))
+ .Build();
+```
+
+### OpenTelemetry Specification environment variables
+
+The [OpenTelemetry
+Specification](https://github.com/open-telemetry/opentelemetry-specification)
+defines [specific environment
+variables](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md)
+which may be used to configure SDK implementations.
+
+The OpenTelemetry .NET SDK will look for the environment variables defined in
+the specification using `IConfiguration` which means in addition to environment
+variables users may also manage these settings via the command-line,
+configuration files, or any other source registered with the .NET configuration
+engine. This provides greater flexibility than what the specification defines.
+
+**Note:** Not all of the environment variables defined in the specification are
+supported. Consult the individual project README files for details on specific
+environment variable support.
+
+As an example the OpenTelemetry Specification defines the `OTEL_SERVICE_NAME`
+environment variable which may be used to configure the service name emitted on
+telemetry by the SDK.
+
+A traditional environment variable is set using a command like `set
+OTEL_SERVICE_NAME=MyService` on Windows or `export OTEL_SERVICE_NAME=MyService`
+on Linux.
+
+That works as expected but the OpenTelemetry .NET SDK is actually looking for
+the `OTEL_SERVICE_NAME` key in `IConfiguration` which means it may also be
+configured in any configuration source registered with the
+`IConfigurationBuilder` used to create the final configuration for the host.
+
+Below are two examples of configuring the `OTEL_SERVICE_NAME` setting beyond
+environment variables.
+
+* Using appsettings.json:
+
+ ```json
+ {
+ "OTEL_SERVICE_NAME": "MyService"
+ }
+ ```
+
+* Using command-line:
+
+ ```sh
+ dotnet run --OTEL_SERVICE_NAME "MyService"
+ ```
+
+**Note:** The [.NET
+ Configuration](https://learn.microsoft.com/dotnet/core/extensions/configuration)
+ pattern is hierarchical meaning the order of registered configuration sources
+ controls which value will seen by the SDK when it is defined in multiple
+ sources.
+
+### Using the .NET Options pattern to configure the SDK
+
+Options are typically simple classes containing only properties with public
+"getters" and "setters" (aka POCOs) and have "Options" at the end of the class
+name. These options classes are primarily used when interacting with the
+`TracerProviderBuilder` to control settings and features of the different SDK
+components.
+
+Options classes can always be configured through code but users typically want to
+control key settings through configuration.
+
+The following example shows how to configure `JaegerExporterOptions` by binding
+to an `IConfiguration` section.
+
+Json config file (usually appsettings.json):
+
+```json
+{
+ "OpenTelemetry": {
+ "Jaeger": {
+ "Protocol": "UdpCompactThrift"
+ "AgentHost": "localhost",
+ "AgentPort": 6831,
+ "BatchExportProcessorOptions": {
+ "ScheduledDelayMilliseconds": 5000
+ }
+ }
+ }
+}
+```
+
+Code:
+
+```csharp
+var appBuilder = WebApplication.CreateBuilder(args);
+
+appBuilder.Services.Configure(
+ appBuilder.Configuration.GetSection("OpenTelemetry:Jaeger"));
+
+appBuilder.Services.AddOpenTelemetryTracing(
+ builder => builder.AddJaegerExporter());
+```
+
+The OpenTelemetry .NET SDK supports running multiple `TracerProvider`s inside
+the same application and it also supports registering multiple similar
+components such as exporters into a single `TracerProvider`. In order to allow
+users to target configuration at specific components a "name" parameter is
+typically supported on configuration extensions to control the options instance
+used for the component being registered.
+
+The below example shows how to configure two `JaegerExporter` instances inside a
+single `TracerProvider` sending to different ports.
+
+Json config file (usually appsettings.json):
+
+```json
+{
+ "OpenTelemetry": {
+ "JaegerPrimary": {
+ "AgentPort": 1818
+ },
+ "JaegerSecondary": {
+ "AgentPort": 8818
+ }
+ }
+}
+```
+
+Code:
+
+```csharp
+var appBuilder = WebApplication.CreateBuilder(args);
+
+appBuilder.Services.Configure(
+ "JaegerPrimary",
+ appBuilder.Configuration.GetSection("OpenTelemetry:JaegerPrimary"));
+
+appBuilder.Services.Configure(
+ "JaegerSecondary",
+ appBuilder.Configuration.GetSection("OpenTelemetry:JaegerSecondary"));
+
+appBuilder.Services.AddOpenTelemetryTracing(builder => builder
+ .AddJaegerExporter(name: "JaegerPrimary", configure: null)
+ .AddJaegerExporter(name: "JaegerSecondary", configure: null));
+```
diff --git a/docs/trace/extending-the-sdk/README.md b/docs/trace/extending-the-sdk/README.md
index d9324d21812..8d62577cb1b 100644
--- a/docs/trace/extending-the-sdk/README.md
+++ b/docs/trace/extending-the-sdk/README.md
@@ -1,10 +1,13 @@
# Extending the OpenTelemetry .NET SDK
+Quick links:
+
* [Building your own exporter](#exporter)
* [Building your own instrumentation library](#instrumentation-library)
* [Building your own processor](#processor)
* [Building your own sampler](#sampler)
* [Building your own resource detector](#resource-detector)
+* [Registration extension method guidance for library authors](#registration-extension-method-guidance-for-library-authors)
* [References](#references)
## Exporter
@@ -62,7 +65,9 @@ A demo exporter which simply writes activity name to the console is shown
Apart from the exporter itself, you should also provide extension methods as
shown [here](./MyExporterExtensions.cs). This allows users to add the Exporter
-to the `TracerProvider` as shown in the example [here](./Program.cs).
+to the `TracerProvider` as shown in the example [here](./Program.cs). See
+[here](#registration-extension-method-guidance-for-library-authors) for more
+detailed extension method guidance.
### Exporting Activity Status
@@ -114,40 +119,44 @@ Contrib](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/mai
If you are writing an instrumentation library yourself, use the following
guidelines.
-### Writing own instrumentation library
+### Writing a custom instrumentation library
-This section describes the steps required to write your own instrumentation
+This section describes the steps required to write a custom instrumentation
library.
-*If you are writing a new library or modifying an existing library, the
-recommendation is to use [ActivitySource API/OpenTelemetry
+**Note:** If you are writing a new library or modifying an existing library the
+recommendation is to use the [ActivitySource API/OpenTelemetry
API](../../../src/OpenTelemetry.Api/README.md#introduction-to-opentelemetry-net-tracing-api)
-to instrument it and emit activity/span. If a library is instrumented using
-ActivitySource API, then there is no need of writing a separate instrumentation
-library, as instrumented and instrumentation library become same in this case.
-For applications to collect traces from this library, all that is needed is to
-enable the ActivitySource for the library using `AddSource` method of the
-`TracerProviderBuilder`. The following section is applicable only if you are
-writing an instrumentation library for an instrumented library which you cannot
-modify to emit activities directly.*
+to emit activity/span instances directly. If a library is instrumented using the
+`ActivitySource` API then there isn't a need for a separate instrumentation
+library to exist. Users simply need to configure the OpenTelemetry SDK to listen
+to the `ActivitySource` used by the library by calling `AddSource` on the
+`TracerProviderBuilder` being configured. The following section is applicable
+only if you are writing an instrumentation library for something you cannot
+modify to emit activity/span instances directly.
Writing an instrumentation library typically involves 3 steps.
-1. First step involves "hijacking" into the target library. The exact mechanism
- of this depends on the target library itself. For example,
- System.Data.SqlClient for .NET Framework, which publishes events using
- `EventSource`. The [SqlClient instrumentation
- library](../../../src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs),
- in this case subscribes to the `EventSource` callbacks.
-
-2. Second step is to emit activities using the [ActivitySource
- API](../../../src/OpenTelemetry.Api/README.md#introduction-to-opentelemetry-net-tracing-api).
- In this step, the instrumentation library emits activities *on behalf of* the
- target instrumented library. Irrespective of the actual mechanism used in
- first step, this should be uniform across all instrumentation libraries. The
- `ActivitySource` must be created using the name and version of the
- instrumentation library (eg: "OpenTelemetry.Instrumentation.Http") and *not*
- the instrumented library (eg: "System.Net.Http")
+1. The first step involves attaching to the target library. The exact attachment
+ mechanism will depend on the implementation details of the target library
+ itself. For example, System.Data.SqlClient when running on .NET Framework
+ happens to publish events using an `EventSource` which the [SqlClient
+ instrumentation
+ library](../../../src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs)
+ listens to in order to trigger code as Sql commands are executed. The [.NET
+ Framework HttpWebRequest
+ instrumentation](../../../src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs)
+ patches the runtime code (using reflection) and swaps a static reference that
+ gets invoked as requests are processed for custom code. Every library will be
+ different.
+
+2. The second step is to emit activity instances using the [ActivitySource
+ API](../../../src/OpenTelemetry.Api/README.md#introduction-to-opentelemetry-net-tracing-api)
+ **on behalf of** the target library. Irrespective of the actual mechanism
+ used in first step, this should be uniform across all instrumentation
+ libraries. The `ActivitySource` must be created using the name and version of
+ the instrumentation library (eg: "OpenTelemetry.Instrumentation.Http") and
+ **NOT** the instrumented library (eg: "System.Net.Http")
1. [Context
Propagation](../../../src/OpenTelemetry.Api/README.md#context-propagation):
If your library initiates out of process requests or accepts them, the
@@ -161,33 +170,42 @@ Writing an instrumentation library typically involves 3 steps.
GrpcClient, this is already provided to you and **do not require**
injecting/extracting `PropagationContext` explicitly again.)
-3. Third step is an optional step, and involves providing extension methods on
- `TracerProviderBuilder`, to enable the instrumentation. This is optional, and
- the below guidance must be followed:
-
- 1. If the instrumentation library requires state management tied to that of
- `TracerProvider`, then it must register itself with the provider with the
- `AddInstrumentation` method on the `TracerProviderBuilder`. This causes
- the instrumentation to be created and disposed along with
- `TracerProvider`. If the above is required, then it must provide an
- extension method on `TracerProviderBuilder`. Inside this extension
- method, it should call the `AddInstrumentation` method, and `AddSource`
- method to enable its ActivitySource for the provider. An example
- instrumentation using this approach is [SqlClient
+3. The third step is an optional step, and involves providing extension methods
+ on `TracerProviderBuilder` and/or `IServiceCollection` to enable the
+ instrumentation. For help in choosing see: [Registration extension method
+ guidance for library
+ authors](#registration-extension-method-guidance-for-library-authors). This
+ is optional, and the below guidance should be followed:
+
+ * If the instrumentation library requires state management tied to that of
+ `TracerProvider` then it should:
+
+ * Implement `IDisposable`.
+
+ * Provide an extension method which calls `AddSource` (to enable its
+ `ActivitySource`) and `AddInstrumentation` (to enable state management)
+ on the `TracerProviderBuilder` being configured.
+
+ An example instrumentation using this approach is [SqlClient
instrumentation](../../../src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs).
- **CAUTION**: The instrumentation libraries requiring state management
- are usually hard to auto-instrument. Therefore, they take the risk of not
- being supported by [OpenTelemetry .NET Automatic Instrumentation](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation).
- 2. If the instrumentation library does not requires any state management
- tied to that of `TracerProvider`, then providing `TracerProviderBuilder`
- extension method is optional. If provided, then it must call `AddSource`
- to enable its ActivitySource for the provider.
+ **CAUTION**: The instrumentation libraries requiring state management are
+ usually hard to auto-instrument. Therefore, they take the risk of not
+ being supported by [OpenTelemetry .NET Automatic
+ Instrumentation](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation).
- 3. If instrumentation library does not require state management, and is not
- providing extension method, then the name of the `ActivitySource` used by
- the instrumented library must be documented so that end users can enable
- it using `AddSource` method on `TracerProviderBuilder`.
+ * If the instrumentation library does not require any state management, then
+ providing an extension method is optional.
+
+ * If an extension is provided it should call `AddSource` on the
+ `TracerProviderBuilder` being configured to enable its
+ `ActivitySource`.
+
+ * If an extension is not provided, then the name of the `ActivitySource`
+ used by the instrumented library must be documented so that end users
+ can enable it by calling `AddSource` on the `TracerProviderBuilder`
+ being configured. **Note:** Changing the name of the source should be
+ considered a breaking change.
### Special case : Instrumentation for libraries producing legacy Activity
@@ -334,6 +352,289 @@ Custom resource detectors can be implemented:
A demo ResourceDetector is shown [here](./MyResourceDetector.cs).
+## Registration extension method guidance for library authors
+
+**Note:** This information applies to the OpenTelemetry SDK version 1.4.0 and
+newer only.
+
+Library authors are encouraged to provide extension methods users may call to
+register custom OpenTelemetry components into their `TracerProvider`s. These
+extension methods can target either the `TracerProviderBuilder` or the
+`IServiceCollection` classes. Both of these patterns are described below.
+
+When providing registration extensions:
+
+* **DO** support the [.NET Options
+ pattern](https://learn.microsoft.com/dotnet/core/extensions/options) and
+ **DO** support [named
+ options](https://learn.microsoft.com/dotnet/core/extensions/options#named-options-support-using-iconfigurenamedoptions).
+ The Options pattern allows users to bind
+ [configuration](https://learn.microsoft.com/dotnet/core/extensions/configuration)
+ to options classes and provides extension points for working with instances as
+ they are created. Multiple providers may exist in the same application for a
+ single configuration and multiple components (for example exporters) may exist
+ in the same provider. Named options help users target configuration to
+ specific components.
+
+ * Use the
+ [Configure](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.optionsservicecollectionextensions.configure#microsoft-extensions-dependencyinjection-optionsservicecollectionextensions-configure-1(microsoft-extensions-dependencyinjection-iservicecollection-system-string-system-action((-0))))
+ extension to register configuration callbacks for a given name.
+
+ * Use the
+ [IOptionsMonitor<T>.Get](https://learn.microsoft.com/dotnet/api/microsoft.extensions.options.ioptionsmonitor-1.get)
+ method to access options class instances by name.
+
+* **DO** throw exceptions for issues that prevent the component being registered
+ from starting. The OpenTelemetry SDK is allowed to crash if it cannot be
+ started. It **MUST NOT** crash once running.
+
+**Note:** The SDK implementation of `TracerProviderBuilder` ensures that the
+[.NET
+Configuration](https://learn.microsoft.com/en-us/dotnet/core/extensions/configuration)
+engine is always available by creating a root `IConfiguration` from environment
+variables if it does not already exist in the `IServiceCollection` containing
+the `TracerProvider`. Library authors can rely on `IConfiguration` always being
+present in the final `IServiceProvider`.
+
+### TracerProviderBuilder extension methods
+
+When registering pipeline components (for example samplers, exporters, or
+resource detectors) it is recommended to use the `TracerProviderBuilder` as the
+target type for registration extension methods. These extensions will be highly
+discoverable for users interacting with the `TracerProviderBuilder` in their IDE
+of choice.
+
+The following example shows how to register a custom exporter with named options
+support using a `TracerProviderBuilder` extension.
+
+```csharp
+using System.Diagnostics;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Options;
+using MyLibrary;
+using OpenTelemetry;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Trace;
+
+namespace OpenTelemetry.Trace
+{
+ public static class MyLibraryTracerProviderBuilderRegistrationExtensions
+ {
+ public static TracerProviderBuilder AddMyLibraryExporter(
+ this TracerProviderBuilder builder,
+ string? name = null,
+ Action? configureExporterOptions = null,
+ Action? configureBatchProcessorOptions = null)
+ {
+ ArgumentNullException.ThrowIfNull(builder);
+
+ // Support named options.
+ name ??= Options.DefaultName;
+
+ builder.ConfigureServices(services =>
+ {
+ if (configureExporterOptions != null)
+ {
+ // Support configuration through Options API.
+ services.Configure(name, configureExporterOptions);
+ }
+
+ if (configureBatchProcessorOptions != null)
+ {
+ // Support configuration through Options API.
+ services.Configure(name, configureBatchProcessorOptions);
+ }
+
+ // Register custom service as a singleton.
+ services.TryAddSingleton();
+ });
+
+ builder.ConfigureBuilder((sp, builder) =>
+ {
+ // Retrieve MyExporterOptions instance using name.
+ var exporterOptions = serviceProvider.GetRequiredService>().Get(name);
+
+ // Retrieve BatchExportActivityProcessorOptions instance using name.
+ var batchOptions = serviceProvider.GetRequiredService>().Get(name);
+
+ // Retrieve MyCustomService singleton.
+ var myCustomService = sp.GetRequiredService();
+
+ // Registers MyCustomExporter with a batch processor.
+ builder.AddProcessor(
+ new BatchActivityExportProcessor(
+ new MyCustomExporter(exporterOptions, myCustomService),
+ batchOptions.MaxQueueSize,
+ batchOptions.ScheduledDelayMilliseconds,
+ batchOptions.ExporterTimeoutMilliseconds,
+ batchOptions.MaxExportBatchSize));
+ });
+
+ // Return builder for call chaining.
+ return builder;
+ }
+ }
+}
+
+namespace MyLibrary
+{
+ // Options class can be bound to IConfiguration or configured by code.
+ public class MyExporterOptions
+ {
+ public Uri? IngestionUri { get; set; }
+ }
+
+ internal sealed class MyCustomExporter : BaseExporter
+ {
+ public MyCustomExporter(
+ MyExporterOptions options,
+ MyCustomService myCustomService)
+ {
+ // Implementation not shown.
+ }
+
+ public override ExportResult Export(in Batch batch)
+ {
+ // Implementation not shown.
+
+ return ExportResult.Success;
+ }
+ }
+
+ internal sealed class MyCustomService
+ {
+ // Implementation not shown.
+ }
+}
+```
+
+When providing `TracerProviderBuilder` registration extensions:
+
+* **DO** Use the `OpenTelemetry.Trace` namespace for `TracerProviderBuilder`
+ registration extensions to help with discoverability.
+
+* **DO** Return the `TracerProviderBuilder` passed in to support call chaining
+ of registration methods.
+
+* **DO** Use the `TracerProviderBuilder.ConfigureServices` extension method to
+ register dependent services.
+
+* **DO** Use the `TracerProviderBuilder.ConfigureBuilder` extension method to
+ peform configuration once the final `IServiceProvider` is available.
+
+### IServiceCollection extension methods
+
+When registering instrumentation or listening to telemetry in a library
+providing other features it is recommended to use the `IServiceCollection` as
+the target type for registration extension methods.
+
+The following example shows how a library might enable tracing and metric
+support using an `IServiceCollection` extension by calling
+`ConfigureOpenTelemetryTracing`.
+
+```csharp
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Options;
+using MyLibrary;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Trace;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static class MyLibraryServiceCollectionRegistrationExtensions
+ {
+ public static IServiceCollection AddMyLibrary(
+ this IServiceCollection services,
+ string? name = null,
+ Action? configure = null)
+ {
+ ArgumentNullException.ThrowIfNull(services);
+
+ // Register library services.
+ services.TryAddSingleton();
+
+ // Support named options.
+ name ??= Options.DefaultName;
+
+ if (configure != null)
+ {
+ // Support configuration through Options API.
+ services.Configure(name, configure);
+ }
+
+ // Configure OpenTelemetry tracing.
+ services.ConfigureOpenTelemetryTracing(builder => builder.ConfigureBuilder((sp, builder) =>
+ {
+ var options = sp.GetRequiredService>().Get(name);
+ if (options.EnableTracing)
+ {
+ builder.AddSource("MyLibrary");
+ }
+ }));
+
+ // Configure OpenTelemetry metrics.
+ services.ConfigureOpenTelemetryMetrics(builder => builder.ConfigureBuilder((sp, builder) =>
+ {
+ var options = sp.GetRequiredService>().Get(name);
+ if (options.EnableMetrics)
+ {
+ builder.AddMeter("MyLibrary");
+ }
+ }));
+
+ return services;
+ }
+ }
+}
+
+namespace MyLibrary
+{
+ // Options class can be bound to IConfiguration or configured by code.
+ public class MyLibraryOptions
+ {
+ public bool EnableTracing { get; set; }
+
+ public bool EnableMetrics { get; set; }
+ }
+
+ internal sealed class MyLibraryService : IMyLibraryService
+ {
+ // Implementation not shown.
+ }
+
+ public interface IMyLibraryService
+ {
+ // Implementation not shown.
+ }
+}
+```
+
+The benefit to using the `IServiceCollection` style is users only need to call a
+single `AddMyLibrary` extension to configure the library itself and optionally
+turn on OpenTelemetry integration for multiple signals (tracing & metrics in
+this case).
+
+**Note:** `ConfigureOpenTelemetryTracing` does not automatically start
+OpenTelemetry. The host is responsible for either calling
+`AddOpenTelemetryTracing` in the
+[OpenTelemetry.Extensions.Hosting](../../../src/OpenTelemetry.Extensions.Hosting/README.md)
+package, calling `Build` when using the `Sdk.CreateTracerProviderBuilder`
+method, or by accessing the `TracerProvider` from the `IServiceCollection` where
+`ConfigureOpenTelemetryTracing` was performed.
+
+When providing `IServiceCollection` registration extensions:
+
+* **DO** Use the `Microsoft.Extensions.DependencyInjection` namespace for
+ `IServiceCollection` registration extensions to help with discoverability.
+
+* **DO** Return the `IServiceCollection` passed in to support call chaining of
+ registration methods.
+
+* **DO** Use the `IServiceCollection` directly to register dependent services.
+
+* **DO** Use the `TracerProviderBuilder.ConfigureBuilder` extension method to
+ peform configuration once the final `IServiceProvider` is available.
+
## References
* [Exporter
diff --git a/examples/AspNetCore/appsettings.json b/examples/AspNetCore/appsettings.json
index e2826c577b6..10f9feba43f 100644
--- a/examples/AspNetCore/appsettings.json
+++ b/examples/AspNetCore/appsettings.json
@@ -2,8 +2,7 @@
"Logging": {
"LogLevel": {
"Default": "Information",
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
diff --git a/global.json b/global.json
index 4dbb7aa3237..40b4707710e 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
"rollForward": "latestFeature",
- "version": "7.0.100-preview"
+ "version": "7.0.100"
}
}
diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md
index c09057cd125..49a72a0d579 100644
--- a/src/OpenTelemetry.Api/CHANGELOG.md
+++ b/src/OpenTelemetry.Api/CHANGELOG.md
@@ -2,6 +2,12 @@
## Unreleased
+* Updated to System.Diagnostics.DiagnosticSource version `7.0.0`.
+
+## 1.4.0-beta.3
+
+Released 2022-Nov-07
+
* Updated to System.Diagnostics.DiagnosticSource version `7.0.0-rc.2.22472.3`.
## 1.4.0-beta.2
diff --git a/src/OpenTelemetry.Api/README.md b/src/OpenTelemetry.Api/README.md
index 26da2644258..7148cbf8917 100644
--- a/src/OpenTelemetry.Api/README.md
+++ b/src/OpenTelemetry.Api/README.md
@@ -137,7 +137,7 @@ Processors/Exporters see the same data.
The recommended way of instrumenting is by using the [.NET Activity
API](#instrumenting-a-libraryapplication-with-net-activity-api). Users are
required to just take dependency on the
-[DiagnosticSource](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource/5.0.0).
+[DiagnosticSource](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource).
Adding dependency to
[OpenTelemetry.API](https://www.nuget.org/packages/opentelemetry.api) is
required only for the following scenarios:
@@ -160,7 +160,7 @@ required only for the following scenarios:
[Context propagation](#context-propagation) section.
3. You want to leverage
- [Baggage](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/baggage/api.md)
+ [Baggage](#baggage-api)
API.
## Instrumenting a library/application with .NET Activity API
@@ -172,16 +172,11 @@ is the .NET `Activity` API. Guidance for instrumenting using this API is
documented fully in the TBD(dotnet activity user guide link), but is described
here as well.
-1. Install the `System.Diagnostics.DiagnosticSource` package version `5.0.1` or
- above to your application or library.
+1. Install the latest stable `System.Diagnostics.DiagnosticSource` to your
+ application or library.
- ```xml
-
-
-
+ ```shell
+ dotnet add package System.Diagnostics.DiagnosticSource
```
2. Create an `ActivitySource`, providing the name and version of the
@@ -462,7 +457,7 @@ context.
Metrics in OpenTelemetry .NET are a somewhat unique implementation of the
OpenTelemetry project, as the Metrics API is incorporated directly into the .NET
runtime itself, as part of the
-[`System.Diagnostics.DiagnosticSource`](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource/6.0.0)
+[`System.Diagnostics.DiagnosticSource`](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource)
package. This means, users can instrument their applications/libraries to emit
metrics by simply using the `System.Diagnostics.DiagnosticSource` package. This
package can be used in applications targeting any of the officially supported
@@ -474,13 +469,11 @@ Windows-based .NET implementation).
### Basic metric usage
-1. Install the `System.Diagnostics.DiagnosticSource` package version `6.0.0` or
- above to your application or library.
+1. Install the latest stable version of `System.Diagnostics.DiagnosticSource` to
+ your application or library.
- ```xml
-
-
-
+ ```shell
+ dotnet add package System.Diagnostics.DiagnosticSource
```
2. Create a `Meter`, providing the name and version of the library/application
@@ -520,7 +513,7 @@ describes more kinds of instruments.
### Instrument types
-// TODO - add all instruments.
+See [this](../../docs/metrics/learning-more-instruments/README.md).
## Troubleshooting
diff --git a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md
index 1fc404b042e..4f202cb891d 100644
--- a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.4.0-beta.3
+
+Released 2022-Nov-07
+
* Bumped the minimum required version of `System.Text.Json` to 4.7.2 in response
to [CVE-2021-26701](https://github.com/dotnet/runtime/issues/49377).
([#3789](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3789))
diff --git a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md
index 948cd03d977..8f7cd2b278c 100644
--- a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.4.0-beta.3
+
+Released 2022-Nov-07
+
## 1.4.0-beta.2
Released 2022-Oct-17
diff --git a/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md b/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md
index 78c6c7bbddd..3dedfcc6166 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.4.0-beta.3
+
+Released 2022-Nov-07
+
* Bumped the minimum required version of `System.Text.Json` to 4.7.2 in response
to [CVE-2021-26701](https://github.com/dotnet/runtime/issues/49377).
([#3789](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3789))
diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs
index 6a6bd83efc0..df4c4180ccc 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs
+++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs
@@ -69,7 +69,10 @@ public static TracerProviderBuilder AddJaegerExporter(
services.Configure(name, configure);
}
- services.RegisterOptionsFactory(configuration => new JaegerExporterOptions(configuration));
+ services.RegisterOptionsFactory(
+ (sp, configuration) => new JaegerExporterOptions(
+ configuration,
+ sp.GetRequiredService>().Get(name)));
});
return builder.ConfigureBuilder((sp, builder) =>
diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs
index 592fd554330..a2286a71bc1 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs
+++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs
@@ -48,12 +48,17 @@ public class JaegerExporterOptions
/// Initializes a new instance of the class.
///
public JaegerExporterOptions()
- : this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
+ : this(new ConfigurationBuilder().AddEnvironmentVariables().Build(), new())
{
}
- internal JaegerExporterOptions(IConfiguration configuration)
+ internal JaegerExporterOptions(
+ IConfiguration configuration,
+ BatchExportActivityProcessorOptions defaultBatchOptions)
{
+ Debug.Assert(configuration != null, "configuration was null");
+ Debug.Assert(defaultBatchOptions != null, "defaultBatchOptions was null");
+
if (configuration.TryGetValue(
OTelProtocolEnvVarKey,
JaegerExporterProtocolParser.TryParse,
@@ -77,7 +82,7 @@ internal JaegerExporterOptions(IConfiguration configuration)
this.Endpoint = endpoint;
}
- this.BatchExportProcessorOptions = new BatchExportActivityProcessorOptions(configuration);
+ this.BatchExportProcessorOptions = defaultBatchOptions;
}
///
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md
index b5977bd237e..fbf1ac1c2b5 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.4.0-beta.3
+
+Released 2022-Nov-07
+
## 1.4.0-beta.2
Released 2022-Oct-17
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
index 2289b9a12f5..a9d38568311 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.4.0-beta.3
+
+Released 2022-Nov-07
+
* Log Exporter modified to no longer prefix scope-depth when exporting ILogger
scopes as attributes. Empty keys and {OriginalFormat} key will be ignored from
scopes.
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
index 2bf0f7e980f..00c7ab6ac3a 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
@@ -52,12 +52,16 @@ public class OtlpExporterOptions
/// Initializes a new instance of the class.
///
public OtlpExporterOptions()
- : this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
+ : this(new ConfigurationBuilder().AddEnvironmentVariables().Build(), new())
{
}
- internal OtlpExporterOptions(IConfiguration configuration)
+ internal OtlpExporterOptions(
+ IConfiguration configuration,
+ BatchExportActivityProcessorOptions defaultBatchOptions = null)
{
+ Debug.Assert(configuration != null, "configuration was null");
+
if (configuration.TryGetUriValue(EndpointEnvVarName, out var endpoint))
{
this.endpoint = endpoint;
@@ -89,7 +93,7 @@ internal OtlpExporterOptions(IConfiguration configuration)
};
};
- this.BatchExportProcessorOptions = new BatchExportActivityProcessorOptions(configuration);
+ this.BatchExportProcessorOptions = defaultBatchOptions;
}
///
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs
index 741314ab8b4..27695a881cd 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs
@@ -67,7 +67,8 @@ public static MeterProviderBuilder AddOtlpExporter(
services.Configure(name, configureExporter);
}
- services.RegisterOptionsFactory(configuration => new OtlpExporterOptions(configuration));
+ services.RegisterOptionsFactory(configuration
+ => new OtlpExporterOptions(configuration, defaultBatchOptions: null));
});
return builder.ConfigureBuilder((sp, builder) =>
@@ -113,7 +114,8 @@ public static MeterProviderBuilder AddOtlpExporter(
builder.ConfigureServices(services =>
{
- services.RegisterOptionsFactory(configuration => new OtlpExporterOptions(configuration));
+ services.RegisterOptionsFactory(configuration
+ => new OtlpExporterOptions(configuration, defaultBatchOptions: null));
});
return builder.ConfigureBuilder((sp, builder) =>
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs
index 889fe7fca5d..dab607ec5be 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs
@@ -70,7 +70,10 @@ public static TracerProviderBuilder AddOtlpExporter(
}
services.RegisterOptionsFactory(configuration => new SdkLimitOptions(configuration));
- services.RegisterOptionsFactory(configuration => new OtlpExporterOptions(configuration));
+ services.RegisterOptionsFactory(
+ (sp, configuration) => new OtlpExporterOptions(
+ configuration,
+ sp.GetRequiredService>().Get(name)));
});
return builder.ConfigureBuilder((sp, builder) =>
@@ -108,7 +111,7 @@ internal static TracerProviderBuilder AddOtlpExporter(
}
else
{
- var batchOptions = exporterOptions.BatchExportProcessorOptions ?? new();
+ var batchOptions = exporterOptions.BatchExportProcessorOptions ?? new BatchExportActivityProcessorOptions();
return builder.AddProcessor(new BatchActivityExportProcessor(
otlpExporter,
diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md
index 89f34d18923..c4675700423 100644
--- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.4.0-beta.3
+
+Released 2022-Nov-07
+
* Support named options in `UseOpenTelemetryPrometheusScrapingEndpoint` &
`MapPrometheusScrapingEndpoint` extensions
([#3780](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3780))
diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md
index 57270498735..ae1bd07664e 100644
--- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.4.0-beta.3
+
+Released 2022-Nov-07
+
## 1.4.0-beta.2
Released 2022-Oct-17
diff --git a/src/OpenTelemetry.Exporter.ZPages/CHANGELOG.md b/src/OpenTelemetry.Exporter.ZPages/CHANGELOG.md
index 27760d5ac4e..8e236b83aa2 100644
--- a/src/OpenTelemetry.Exporter.ZPages/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.ZPages/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.0.0-rc9.9
+
+Released 2022-Nov-07
+
## 1.0.0-rc9.8
Released 2022-Oct-17
diff --git a/src/OpenTelemetry.Exporter.ZPages/README.md b/src/OpenTelemetry.Exporter.ZPages/README.md
index 3f9c2ee0b37..28d49716560 100644
--- a/src/OpenTelemetry.Exporter.ZPages/README.md
+++ b/src/OpenTelemetry.Exporter.ZPages/README.md
@@ -6,7 +6,7 @@
## Installation
```shell
-dotnet add package OpenTelemetry.Exporter.ZPages
+dotnet add package --prerelease OpenTelemetry.Exporter.ZPages
```
## Configuration
diff --git a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md
index 4ea2b381680..53570ab853e 100644
--- a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.4.0-beta.3
+
+Released 2022-Nov-07
+
* Bumped the minimum required version of `System.Text.Json` to 4.7.2 in response
to [CVE-2021-26701](https://github.com/dotnet/runtime/issues/49377).
([#3789](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3789))
diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs
index 93a43014874..e4a1ecf2c9e 100644
--- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs
+++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs
@@ -69,7 +69,10 @@ public static TracerProviderBuilder AddZipkinExporter(
services.Configure(name, configure);
}
- services.RegisterOptionsFactory(configuration => new ZipkinExporterOptions(configuration));
+ services.RegisterOptionsFactory(
+ (sp, configuration) => new ZipkinExporterOptions(
+ configuration,
+ sp.GetRequiredService>().Get(name)));
});
return builder.ConfigureBuilder((sp, builder) =>
diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs
index f9d8e7c62c4..32f6a031ad4 100644
--- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs
+++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs
@@ -45,18 +45,23 @@ public sealed class ZipkinExporterOptions
/// Initializes zipkin endpoint.
///
public ZipkinExporterOptions()
- : this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
+ : this(new ConfigurationBuilder().AddEnvironmentVariables().Build(), new())
{
}
- internal ZipkinExporterOptions(IConfiguration configuration)
+ internal ZipkinExporterOptions(
+ IConfiguration configuration,
+ BatchExportActivityProcessorOptions defaultBatchOptions)
{
+ Debug.Assert(configuration != null, "configuration was null");
+ Debug.Assert(defaultBatchOptions != null, "defaultBatchOptions was null");
+
if (configuration.TryGetUriValue(ZipkinEndpointEnvVar, out var endpoint))
{
this.Endpoint = endpoint;
}
- this.BatchExportProcessorOptions = new BatchExportActivityProcessorOptions(configuration);
+ this.BatchExportProcessorOptions = defaultBatchOptions;
}
///
diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md
index 1f75cb9920c..8d31ce75b4e 100644
--- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md
+++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.0.0-rc9.9
+
+Released 2022-Nov-07
+
## 1.0.0-rc9.8
Released 2022-Oct-17
diff --git a/src/OpenTelemetry.Extensions.Hosting/README.md b/src/OpenTelemetry.Extensions.Hosting/README.md
index a1c8341958c..e8e35c03383 100644
--- a/src/OpenTelemetry.Extensions.Hosting/README.md
+++ b/src/OpenTelemetry.Extensions.Hosting/README.md
@@ -6,95 +6,69 @@
## Installation
```shell
-dotnet add package OpenTelemetry.Extensions.Hosting
+dotnet add package --prerelease OpenTelemetry.Extensions.Hosting
```
-## Usage
-
-### Tracing
+## Overview
-#### Simple Configuration
+The OpenTelemetry.Extensions.Hosting package provides extension methods for
+automatically starting (and stopping) OpenTelemetry tracing (`TracerProvider`)
+and metrics (`MeterProvider`) in [ASP.NET
+ Core](https://learn.microsoft.com/aspnet/core/fundamentals/host/web-host) and
+ [.NET Generic](https://learn.microsoft.com/dotnet/core/extensions/generic-host)
+ hosts. These are completely optional extensions meant to simplify the
+ management of the OpenTelemetry SDK lifecycle.
-The following example registers tracing using the `ZipkinExporter` and binds
-options to the "Zipkin" configuration section:
+## Extension method reference
-```csharp
-services.AddOpenTelemetryTracing((builder) => builder
- .AddAspNetCoreInstrumentation()
- .AddHttpClientInstrumentation()
- .AddZipkinExporter());
+**Note:** The below extension methods target
+`Microsoft.Extensions.DependencyInjection.IServiceCollection`.
-services.Configure(this.Configuration.GetSection("Zipkin"));
-```
+**Note:** The below extension methods should be called by application host code
+only. Library authors see: [Registration extension method guidance for library
+authors](../../docs/trace/extending-the-sdk/README.md#registration-extension-method-guidance-for-library-authors).
-#### Using Dependency Injection
+**Note:** Multiple calls to the below extensions will **NOT** result in multiple
+providers. To establish multiple providers use the
+`Sdk.CreateTracerProviderBuilder()` and/or `Sdk.CreateMeterProviderBuilder()`
+methods. See [TracerProvider
+configuration](../../docs/trace/customizing-the-sdk/README.md#tracerprovider-configuration)
+and [Building a
+MeterProvider](../../docs/metrics/customizing-the-sdk/README.md#building-a-meterprovider)
+for more details.
-The following example registers a processor of the type "MyProcessor" which has
-been registered as a singleton with the `IServiceCollection`:
+* `AddOpenTelemetryTracing`: Configure OpenTelemetry and register an
+ [IHostedService](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.ihostedservice)
+ to automatically start tracing services in the supplied
+ [IServiceCollection](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection).
-```csharp
-services.AddSingleton();
-
-services.AddOpenTelemetryTracing((builder) => builder
- .AddAspNetCoreInstrumentation()
- .AddHttpClientInstrumentation()
- .AddProcessor());
-```
+* `AddOpenTelemetryMetrics`: Configure OpenTelemetry and register an
+ [IHostedService](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.ihostedservice)
+ to automatically start metric services in the supplied
+ [IServiceCollection](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection).
-Similar methods exist for registering instrumentation (`AddInstrumentation`)
-and setting a sampler (`SetSampler`).
+## Usage
-You can also access the application `IServiceProvider` directly and accomplish
-the same registration using the `ConfigureBuilder` extension like this:
+The following example shows how to register OpenTelemetry tracing & metrics in
+an ASP.NET Core host using the OpenTelemetry.Extensions.Hosting extensions.
```csharp
-services.AddSingleton();
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Trace;
-services.AddOpenTelemetryTracing(hostingBuilder => hostingBuilder
- .ConfigureBuilder((sp, builder) => builder
- .AddAspNetCoreInstrumentation()
- .AddHttpClientInstrumentation()
- .AddProcessor(sp.GetRequiredService())));
-```
+var appBuilder = WebApplication.CreateBuilder(args);
-**Note:** `ConfigureBuilder` is called _after_ the `IServiceProvider` has been built
-from the application `IServiceCollection` so any services registered in the
-`ConfigureBuilder` callback will be ignored.
+appBuilder.Services.AddOpenTelemetryTracing(
+ builder => builder.AddConsoleExporter());
-#### Building Extension Methods
+appBuilder.Services.AddOpenTelemetryMetrics(
+ builder => builder.AddConsoleExporter());
-Library authors may want to configure the OpenTelemetry `TracerProvider` and
-register application services to provide more complex features. This can be
-accomplished concisely by using the `TracerProviderBuilder.ConfigureServices`
-extension method inside of a more general `TracerProviderBuilder` configuration
-extension like this:
+var app = appBuilder.Build();
-```csharp
-public static class MyLibraryExtensions
-{
- public static TracerProviderBuilder AddMyFeature(this TracerProviderBuilder tracerProviderBuilder)
- {
- return tracerProviderBuilder
- .ConfigureServices(services =>
- services
- .AddHostedService()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton())
- .AddProcessor()
- .SetSampler();
- }
-}
-```
-
-Such an extension method can be consumed like this:
-
-```csharp
-services.AddOpenTelemetryTracing((builder) => builder
- .AddAspNetCoreInstrumentation()
- .AddHttpClientInstrumentation()
- .AddMyFeature()
- .AddZipkinExporter());
+app.Run();
```
## References
diff --git a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md
index 130ef3aa83a..93710084119 100644
--- a/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md
+++ b/src/OpenTelemetry.Extensions.Propagators/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.4.0-beta.3
+
+Released 2022-Nov-07
+
## 1.4.0-beta.2
Released 2022-Oct-17
diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md
index 5b3b1e04bf1..65fdeb38f39 100644
--- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md
+++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md
@@ -2,6 +2,14 @@
## Unreleased
+* **Breaking change** `http.host` will no longer be populated on activity.
+ `net.host.name` and `net.host.port` attributes will be populated instead.
+ ([#3858](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3858))
+
+## 1.0.0-rc9.9
+
+Released 2022-Nov-07
+
* **Breaking change** The `Enrich` callback option has been removed.
For better usability, it has been replaced by three separate options:
`EnrichWithHttpRequest`, `EnrichWithHttpResponse` and `EnrichWithException`.
diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs
index 3be0d4065ef..836a24deb19 100644
--- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs
+++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs
@@ -198,14 +198,14 @@ public void OnStartActivity(Activity activity, object payload)
activity.DisplayName = path;
// see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md
-
- if (request.Host.Port is null or 80 or 443)
- {
- activity.SetTag(SemanticConventions.AttributeHttpHost, request.Host.Host);
- }
- else
+ if (request.Host.HasValue)
{
- activity.SetTag(SemanticConventions.AttributeHttpHost, request.Host.Host + ":" + request.Host.Port);
+ activity.SetTag(SemanticConventions.AttributeNetHostName, request.Host.Host);
+
+ if (request.Host.Port is not null && request.Host.Port != 80 && request.Host.Port != 443)
+ {
+ activity.SetTag(SemanticConventions.AttributeNetHostPort, request.Host.Port);
+ }
}
activity.SetTag(SemanticConventions.AttributeHttpMethod, request.Method);
diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md
index d27566f0419..a5801839648 100644
--- a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md
+++ b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md
@@ -31,7 +31,7 @@ Add a reference to the
package. Also, add any other instrumentations & exporters you will need.
```shell
-dotnet add package OpenTelemetry.Instrumentation.AspNetCore
+dotnet add package --prerelease OpenTelemetry.Instrumentation.AspNetCore
```
### Step 2: Enable ASP.NET Core Instrumentation at application startup
diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md
index 08545533222..d90c0780fba 100644
--- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md
+++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 1.0.0-rc9.9
+
+Released 2022-Nov-07
+
**Breaking change** The `Enrich` callback option has been removed. For better
usability, it has been replaced by two separate options:
`EnrichWithHttpRequestMessage`and `EnrichWithHttpResponseMessage`. Previously,
diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md
index 462f5439321..9f39c155ada 100644
--- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md
+++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md
@@ -32,7 +32,7 @@ Add a reference to the
package. Also, add any other instrumentations & exporters you will need.
```shell
-dotnet add package OpenTelemetry.Instrumentation.GrpcNetClient
+dotnet add package --prerelease OpenTelemetry.Instrumentation.GrpcNetClient
```
### Step 2: Enable Grpc.Net.Client Instrumentation at application startup
diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md
index bf596e774fc..f7d6a98cd2f 100644
--- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md
+++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md
@@ -2,6 +2,18 @@
## Unreleased
+* Added `net.peer.name` and `net.peer.port` as dimensions on
+ `http.client.duration` metric.
+ ([#3907](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3907))
+
+* **Breaking change** `http.host` will no longer be populated on activity.
+ `net.peer.name` and `net.peer.port` attributes will be populated instead.
+ ([#3832](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3832))
+
+## 1.0.0-rc9.9
+
+Released 2022-Nov-07
+
* Added back `netstandard2.0` target.
([#3787](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3787))
diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs
index 2c5b478c8aa..a4ef77bdb53 100644
--- a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs
+++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs
@@ -33,12 +33,12 @@ public class HttpClientInstrumentationOptions
/// collect telemetry about requests on a per request basis.
///
///
- /// Notes:
- ///
- /// FilterHttpRequestMessage is only executed on .NET and .NET
+ /// FilterHttpRequestMessage is only executed on .NET and .NET
/// Core runtimes. and on .NET and .NET Core are both implemented
- /// using .
+ /// using .
+ /// Notes:
+ ///
/// The return value for the filter function is interpreted as:
///
/// If filter returns , the request is
@@ -51,38 +51,32 @@ public class HttpClientInstrumentationOptions
public Func FilterHttpRequestMessage { get; set; }
///
- /// Gets or sets an action to enrich an Activity with .
+ /// Gets or sets an action to enrich an with .
///
///
/// EnrichWithHttpRequestMessage is only executed on .NET and .NET
/// Core runtimes. and on .NET and .NET Core are both implemented
/// using .
- /// : the activity being enriched.
- /// object from which additional information can be extracted to enrich the activity.
///
public Action EnrichWithHttpRequestMessage { get; set; }
///
- /// Gets or sets an action to enrich an Activity with .
+ /// Gets or sets an action to enrich an with .
///
///
/// EnrichWithHttpResponseMessage is only executed on .NET and .NET
/// Core runtimes. and on .NET and .NET Core are both implemented
/// using .
- /// : the activity being enriched.
- /// object from which additional information can be extracted to enrich the activity.
///
public Action EnrichWithHttpResponseMessage { get; set; }
///
- /// Gets or sets an action to enrich an Activity with .
+ /// Gets or sets an action to enrich an with .
///
///
/// EnrichWithException is called for all runtimes.
- /// : the activity being enriched.
- /// object from which additional information can be extracted to enrich the activity.
///
public Action EnrichWithException { get; set; }
@@ -91,12 +85,12 @@ public class HttpClientInstrumentationOptions
/// collect telemetry about requests on a per request basis.
///
///
- /// Notes:
- ///
- /// FilterHttpWebRequest is only executed on .NET Framework
+ /// FilterHttpWebRequest is only executed on .NET Framework
/// runtimes. and
/// on .NET Framework are both implemented using .
+ /// cref="HttpWebRequest"/>.
+ /// Notes:
+ ///
/// The return value for the filter function is interpreted as:
///
/// If filter returns , the request is
@@ -109,36 +103,37 @@ public class HttpClientInstrumentationOptions
public Func FilterHttpWebRequest { get; set; }
///
- /// Gets or sets an action to enrich an Activity with .
+ /// Gets or sets an action to enrich an with .
///
///
/// EnrichWithHttpWebRequest is only executed on .NET Framework
/// runtimes. and
/// on .NET Framework are both implemented using .
- /// : the activity being enriched.
- /// object from which additional information can be extracted to enrich the activity.
///
public Action EnrichWithHttpWebRequest { get; set; }
///
- /// Gets or sets an action to enrich an Activity with .
+ /// Gets or sets an action to enrich an with .
///
///
/// EnrichWithHttpWebResponse is only executed on .NET Framework
/// runtimes. and
/// on .NET Framework are both implemented using .
- /// : the activity being enriched.
- /// object from which additional information can be extracted to enrich the activity.
///
public Action EnrichWithHttpWebResponse { get; set; }
///
- /// Gets or sets a value indicating whether exception will be recorded as an or not.
+ /// Gets or sets a value indicating whether exception will be recorded
+ /// as an or not. Default value: .
///
///
- /// See: .
+ /// RecordException is supported on all runtimes.
+ /// For specification details see: .
///
public bool RecordException { get; set; }
diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs
index 5e0b2fae944..f2ac51c6432 100644
--- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs
+++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs
@@ -159,7 +159,12 @@ public void OnStartActivity(Activity activity, object payload)
activity.SetTag(SemanticConventions.AttributeHttpScheme, request.RequestUri.Scheme);
activity.SetTag(SemanticConventions.AttributeHttpMethod, HttpTagHelper.GetNameForHttpMethod(request.Method));
- activity.SetTag(SemanticConventions.AttributeHttpHost, HttpTagHelper.GetHostTagValueFromRequestUri(request.RequestUri));
+ activity.SetTag(SemanticConventions.AttributeNetPeerName, request.RequestUri.Host);
+ if (!request.RequestUri.IsDefaultPort)
+ {
+ activity.SetTag(SemanticConventions.AttributeNetPeerPort, request.RequestUri.Port);
+ }
+
activity.SetTag(SemanticConventions.AttributeHttpUrl, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri));
activity.SetTag(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version));
diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs
index 8b2ebf0a678..c1924529108 100644
--- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs
+++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs
@@ -49,15 +49,17 @@ public override void OnEventWritten(string name, object payload)
{
var request = response.RequestMessage;
- // TODO: This is just a minimal set of attributes. See the spec for additional attributes:
- // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-client
- var tags = new KeyValuePair[]
+ TagList tags = default;
+ tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpMethod, HttpTagHelper.GetNameForHttpMethod(request.Method)));
+ tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpScheme, request.RequestUri.Scheme));
+ tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpStatusCode, (int)response.StatusCode));
+ tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version)));
+ tags.Add(new KeyValuePair(SemanticConventions.AttributeNetPeerName, request.RequestUri.Host));
+
+ if (!request.RequestUri.IsDefaultPort)
{
- new KeyValuePair(SemanticConventions.AttributeHttpMethod, HttpTagHelper.GetNameForHttpMethod(request.Method)),
- new KeyValuePair(SemanticConventions.AttributeHttpScheme, request.RequestUri.Scheme),
- new KeyValuePair(SemanticConventions.AttributeHttpStatusCode, (int)response.StatusCode),
- new KeyValuePair(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version)),
- };
+ tags.Add(new KeyValuePair(SemanticConventions.AttributeNetPeerPort, request.RequestUri.Port));
+ }
this.httpClientDuration.Record(activity.Duration.TotalMilliseconds, tags);
}
diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs
index 52bf6dada5c..6616029ef4e 100644
--- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs
+++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs
@@ -27,7 +27,6 @@ internal static class HttpTagHelper
private static readonly ConcurrentDictionary MethodOperationNameCache = new();
private static readonly ConcurrentDictionary HttpMethodOperationNameCache = new();
private static readonly ConcurrentDictionary HttpMethodNameCache = new();
- private static readonly ConcurrentDictionary> HostAndPortToStringCache = new();
private static readonly ConcurrentDictionary ProtocolVersionToStringCache = new();
private static readonly Func ConvertMethodToOperationNameRef = ConvertMethodToOperationName;
@@ -63,37 +62,6 @@ internal static class HttpTagHelper
/// Span flavor value.
public static string GetFlavorTagValueFromProtocolVersion(Version protocolVersion) => ProtocolVersionToStringCache.GetOrAdd(protocolVersion, ConvertProtocolVersionToStringRef);
- ///
- /// Gets the OpenTelemetry standard host tag value for a span based on its request .
- ///
- /// .
- /// Span host value.
- public static string GetHostTagValueFromRequestUri(Uri requestUri)
- {
- string host = requestUri.Host;
-
- if (requestUri.IsDefaultPort)
- {
- return host;
- }
-
- int port = requestUri.Port;
-
- if (!HostAndPortToStringCache.TryGetValue(host, out ConcurrentDictionary portCache))
- {
- portCache = new ConcurrentDictionary();
- HostAndPortToStringCache.TryAdd(host, portCache);
- }
-
- if (!portCache.TryGetValue(port, out string hostTagValue))
- {
- hostTagValue = $"{requestUri.Host}:{requestUri.Port}";
- portCache.TryAdd(port, hostTagValue);
- }
-
- return hostTagValue;
- }
-
///
/// Gets the OpenTelemetry standard uri tag value for a span based on its request .
///
diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs
index 078997b1b10..b011719cb6f 100644
--- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs
+++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs
@@ -99,8 +99,13 @@ private static void AddRequestTagsAndInstrumentRequest(HttpWebRequest request, A
if (activity.IsAllDataRequested)
{
activity.SetTag(SemanticConventions.AttributeHttpMethod, request.Method);
+ activity.SetTag(SemanticConventions.AttributeNetPeerName, request.RequestUri.Host);
+ if (!request.RequestUri.IsDefaultPort)
+ {
+ activity.SetTag(SemanticConventions.AttributeNetPeerPort, request.RequestUri.Port);
+ }
+
activity.SetTag(SemanticConventions.AttributeHttpScheme, request.RequestUri.Scheme);
- activity.SetTag(SemanticConventions.AttributeHttpHost, HttpTagHelper.GetHostTagValueFromRequestUri(request.RequestUri));
activity.SetTag(SemanticConventions.AttributeHttpUrl, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri));
activity.SetTag(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.ProtocolVersion));
diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md
index d7375f467a4..36135841716 100644
--- a/src/OpenTelemetry.Instrumentation.Http/README.md
+++ b/src/OpenTelemetry.Instrumentation.Http/README.md
@@ -33,7 +33,7 @@ Add a reference to the
package. Also, add any other instrumentations & exporters you will need.
```shell
-dotnet add package OpenTelemetry.Instrumentation.Http
+dotnet add package --prerelease OpenTelemetry.Instrumentation.Http
```
### Step 2: Enable HTTP Instrumentation at application startup
diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net462/PublicAPI.Unshipped.txt
index 83aa554a2e0..4958bb839fd 100644
--- a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net462/PublicAPI.Unshipped.txt
+++ b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net462/PublicAPI.Unshipped.txt
@@ -3,8 +3,14 @@ OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.EnableCo
OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.EnableConnectionLevelAttributes.set -> void
OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.Enrich.get -> System.Action
OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.Enrich.set -> void
-OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetDbStatement.get -> bool
-OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetDbStatement.set -> void
+OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.Filter.get -> System.Func