Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[docs] Updates for DI tweaks #4127

Merged
merged 2 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 16 additions & 27 deletions docs/trace/customizing-the-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -446,45 +446,34 @@ it is shutdown.
`TracerProvider`. Only a single `TraceProvider` may exist in an
`IServiceCollection` \ `IServiceProvider`.

### Dependency injection `TracerProviderBuilder` extension method reference
### Dependency injection TracerProviderBuilder extension method reference

* `AddInstrumentation<T>`: Adds instrumentation of type `T` into the
`TracerProvider`.

* `AddInstrumentation<T>(Func<IServiceProvider, T> instrumentationFactory)`:
cijothomas marked this conversation as resolved.
Show resolved Hide resolved
Adds instrumentation of type `T` into the
`TracerProvider` using a factory function to create the instrumentation
instance.

* `AddProcessor<T>`: Adds a processor of type `T` (must derive from
`BaseProcessor<Activity>`) into the `TracerProvider`.

* `SetSampler<T>`: Register type `T` (must derive from `Sampler`) as the sampler
for the `TracerProvider`.
* `AddProcessor(Func<IServiceProvider, BaseProcessor<Activity>>
implementationFactory)`: Adds a processor into the `TracerProvider` using a
cijothomas marked this conversation as resolved.
Show resolved Hide resolved
factory function to create the processor instance.

* `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
CodeBlanch marked this conversation as resolved.
Show resolved Hide resolved
`TracerProviderBuilder` once the `IServiceProvider` is available.

```csharp
var appBuilder = WebApplication.CreateBuilder(args);

appBuilder.Services.AddOpenTelemetry()
.WithTracing(builder => builder
.ConfigureBuilder((sp, builder) =>
{
builder.AddProcessor(
new MyCustomProcessor(
// Note: This example uses the final IServiceProvider once it is available.
sp.GetRequiredService<MyCustomService>(),
sp.GetRequiredService<IOptions<MyOptions>>().Value));
}))
.StartWithHost();
```
created after which point services can no longer be added.

* `SetSampler<T>`: Register type `T` (must derive from `Sampler`) as the sampler
cijothomas marked this conversation as resolved.
Show resolved Hide resolved
for the `TracerProvider`.

**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.
* `SetSampler(Func<IServiceProvider, Sampler>
implementationFactory)`: Adds a sampler into the `TracerProvider` using a
factory function to create the sampler instance.

## Configuration files and environment variables

Expand Down
62 changes: 38 additions & 24 deletions docs/trace/extending-the-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,14 @@ 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.

**Note:** Libraries providing SDK plugins such as exporters, resource detectors,
and/or samplers should take a dependency on the SDK (`OpenTelemetry.dll`)
CodeBlanch marked this conversation as resolved.
Show resolved Hide resolved
package. Library authors providing instrumentation should take a dependency on
`OpenTelemetry.Api` or `OpenTelemetry.Api.ProviderBuilderExtensions` package.
`OpenTelemetry.Api.ProviderBuilderExtensions` exposes interfaces for accessing
the `IServiceCollection` which is a requirement for supporting the [.NET Options
pattern](https://learn.microsoft.com/dotnet/core/extensions/options).
cijothomas marked this conversation as resolved.
Show resolved Hide resolved
cijothomas marked this conversation as resolved.
Show resolved Hide resolved

When providing registration extensions:

* **DO** support the [.NET Options
Expand Down Expand Up @@ -449,7 +457,7 @@ namespace OpenTelemetry.Trace
services.TryAddSingleton<MyCustomService>();
});

builder.ConfigureBuilder((sp, builder) =>
builder.AddProcessor(serviceProvider =>
{
// Retrieve MyExporterOptions instance using name.
var exporterOptions = serviceProvider.GetRequiredService<IOptionsMonitor<MyExporterOptions>>().Get(name);
Expand All @@ -458,16 +466,15 @@ namespace OpenTelemetry.Trace
var batchOptions = serviceProvider.GetRequiredService<IOptionsMonitor<BatchExportActivityProcessorOptions>>().Get(name);

// Retrieve MyCustomService singleton.
var myCustomService = sp.GetRequiredService<MyCustomService>();

// Registers MyCustomExporter with a batch processor.
builder.AddProcessor(
new BatchActivityExportProcessor(
new MyCustomExporter(exporterOptions, myCustomService),
batchOptions.MaxQueueSize,
batchOptions.ScheduledDelayMilliseconds,
batchOptions.ExporterTimeoutMilliseconds,
batchOptions.MaxExportBatchSize));
var myCustomService = serviceProvider.GetRequiredService<MyCustomService>();

// Return a batch export processor using MyCustomExporter.
return new BatchActivityExportProcessor(
new MyCustomExporter(exporterOptions, myCustomService),
batchOptions.MaxQueueSize,
batchOptions.ScheduledDelayMilliseconds,
batchOptions.ExporterTimeoutMilliseconds,
batchOptions.MaxExportBatchSize);
});

// Return builder for call chaining.
Expand Down Expand Up @@ -519,8 +526,10 @@ When providing `TracerProviderBuilder` registration extensions:
* **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.
* **DO** Use [the dependency injection extension
methods](../customizing-the-sdk/README.md#dependency-injection-tracerproviderbuilder-extension-method-reference)
utilizing factory patterns to perform configuration once the final
`IServiceProvider` is available.

### IServiceCollection extension methods

Expand All @@ -530,7 +539,8 @@ 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
`ConfigureOpenTelemetryTracerProvider`.
`ConfigureOpenTelemetryTracerProvider` and
`ConfigureOpenTelemetryMeterProvider`.

```csharp
using Microsoft.Extensions.DependencyInjection.Extensions;
Expand All @@ -554,7 +564,7 @@ namespace Microsoft.Extensions.DependencyInjection
services.TryAddSingleton<IMyLibraryService, MyLibraryService>();

// Support named options.
name ??= Options.DefaultName;
name ??= Options.Options.DefaultName;

if (configure != null)
{
Expand All @@ -570,7 +580,7 @@ namespace Microsoft.Extensions.DependencyInjection
{
builder.AddSource("MyLibrary");
}
}));
});

// Configure OpenTelemetry metrics.
services.ConfigureOpenTelemetryMeterProvider((sp, builder) =>
Expand All @@ -580,7 +590,7 @@ namespace Microsoft.Extensions.DependencyInjection
{
builder.AddMeter("MyLibrary");
}
}));
});

return services;
}
Expand Down Expand Up @@ -614,12 +624,14 @@ single `AddMyLibrary` extension to configure the library itself and optionally
turn on OpenTelemetry integration for multiple signals (tracing & metrics in
this case).

**Note:** `ConfigureOpenTelemetryTracerProvider` does not automatically start
OpenTelemetry. The host is responsible for either calling `StartWithHost` in the
**Note:** `ConfigureOpenTelemetryTracerProvider` and
`ConfigureOpenTelemetryMeterProvider` do not automatically start OpenTelemetry.
The host is responsible for either calling `StartWithHost` 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
`ConfigureOpenTelemetryTracerProvider` was performed.
package, calling `Build` when using the `Sdk.CreateTracerProviderBuilder` and
`Sdk.CreateMeterProviderBuilder` methods, or by accessing the `TracerProvider`
and `MeterProvider` from the `IServiceCollection` where configuration was
performed.

When providing `IServiceCollection` registration extensions:

Expand All @@ -631,8 +643,10 @@ When providing `IServiceCollection` registration extensions:

* **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.
* **DO** Use [the dependency injection extension
methods](../customizing-the-sdk/README.md#dependency-injection-tracerproviderbuilder-extension-method-reference)
utilizing factory patterns to perform configuration once the final
`IServiceProvider` is available.

## References

Expand Down