Tweak AddExporter to work better with Options API. (#3870)

Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
This commit is contained in:
Mikel Blanchard 2022-11-08 08:46:53 -08:00 committed by GitHub
parent 273c20580a
commit 51f6cb7675
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 34 deletions

View File

@ -126,10 +126,21 @@ namespace OpenTelemetry.Trace
internal TracerProviderBuilder AddExporter<T>(ExportProcessorType exportProcessorType, string? name, Action<ExportActivityProcessorOptions>? configure)
where T : BaseExporter<Activity>
{
name ??= Options.DefaultName;
this.TryAddSingleton<T>();
if (configure != null)
{
this.ConfigureServices(services =>
{
services.Configure(name, configure);
});
}
this.ConfigureState((sp, state)
=> state.AddProcessor(
BuildExportProcessor(state.ServiceProvider, exportProcessorType, sp.GetRequiredService<T>(), name, configure)));
BuildExportProcessor(exportProcessorType, sp.GetRequiredService<IOptionsMonitor<ExportActivityProcessorOptions>>().Get(name), sp.GetRequiredService<T>())));
return this;
}
@ -138,9 +149,19 @@ namespace OpenTelemetry.Trace
{
Guard.ThrowIfNull(exporter);
name ??= Options.DefaultName;
if (configure != null)
{
this.ConfigureServices(services =>
{
services.Configure(name, configure);
});
}
this.ConfigureState((sp, state)
=> state.AddProcessor(
BuildExportProcessor(state.ServiceProvider, exportProcessorType, exporter, name, configure)));
BuildExportProcessor(exportProcessorType, sp.GetRequiredService<IOptionsMonitor<ExportActivityProcessorOptions>>().Get(name), exporter)));
return this;
}
@ -278,26 +299,16 @@ namespace OpenTelemetry.Trace
}
private static BaseProcessor<Activity> BuildExportProcessor(
IServiceProvider serviceProvider,
ExportProcessorType exportProcessorType,
BaseExporter<Activity> exporter,
string? name,
Action<ExportActivityProcessorOptions>? configure)
ExportActivityProcessorOptions processorOptions,
BaseExporter<Activity> exporter)
{
name ??= Options.DefaultName;
switch (exportProcessorType)
{
case ExportProcessorType.Simple:
return new SimpleActivityExportProcessor(exporter);
case ExportProcessorType.Batch:
var options = serviceProvider.GetRequiredService<IOptionsMonitor<ExportActivityProcessorOptions>>().Get(name);
options.ExportProcessorType = ExportProcessorType.Batch;
configure?.Invoke(options);
var batchOptions = options.BatchExportProcessorOptions;
var batchOptions = processorOptions.BatchExportProcessorOptions;
return new BatchActivityExportProcessor(
exporter,

View File

@ -19,6 +19,7 @@
using System;
using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Internal;
using OpenTelemetry.Resources;
namespace OpenTelemetry.Trace
@ -174,14 +175,19 @@ namespace OpenTelemetry.Trace
/// <param name="tracerProviderBuilder"><see cref="TracerProviderBuilder"/>.</param>
/// <param name="exportProcessorType"><see cref="ExportProcessorType"/>.</param>
/// <param name="exporter">Activity exporter to add.</param>
/// <param name="configure"><inheritdoc cref="AddExporter{T}(TracerProviderBuilder, ExportProcessorType, string?, Action{ExportActivityProcessorOptions}?)" path="/param[@name='configure']"/></param>
/// <param name="configure">Callback action to configure <see
/// cref="ExportActivityProcessorOptions"/>.</param>
/// <returns>Returns <see cref="TracerProviderBuilder"/> for chaining.</returns>
public static TracerProviderBuilder AddExporter(
this TracerProviderBuilder tracerProviderBuilder,
ExportProcessorType exportProcessorType,
BaseExporter<Activity> exporter,
Action<ExportActivityProcessorOptions> configure)
=> AddExporter(tracerProviderBuilder, exportProcessorType, exporter, name: null, configure);
{
Guard.ThrowIfNull(configure);
return AddExporter(tracerProviderBuilder, exportProcessorType, exporter, name: null, configure);
}
/// <summary>
/// Adds an exporter to the provider.
@ -189,8 +195,9 @@ namespace OpenTelemetry.Trace
/// <param name="tracerProviderBuilder"><see cref="TracerProviderBuilder"/>.</param>
/// <param name="exportProcessorType"><see cref="ExportProcessorType"/>.</param>
/// <param name="exporter">Activity exporter to add.</param>
/// <param name="name">Name which is used when retrieving options.</param>
/// <param name="configure"><inheritdoc cref="AddExporter{T}(TracerProviderBuilder, ExportProcessorType, string?, Action{ExportActivityProcessorOptions}?)" path="/param[@name='configure']"/></param>
/// <param name="name">Optional name which is used when retrieving options.</param>
/// <param name="configure">Optional callback action to configure <see
/// cref="ExportActivityProcessorOptions"/>.</param>
/// <returns>Returns <see cref="TracerProviderBuilder"/> for chaining.</returns>
public static TracerProviderBuilder AddExporter(
this TracerProviderBuilder tracerProviderBuilder,
@ -228,14 +235,19 @@ namespace OpenTelemetry.Trace
/// <typeparam name="T">Exporter type.</typeparam>
/// <param name="tracerProviderBuilder"><see cref="TracerProviderBuilder"/>.</param>
/// <param name="exportProcessorType"><see cref="ExportProcessorType"/>.</param>
/// <param name="configure"><inheritdoc cref="AddExporter{T}(TracerProviderBuilder, ExportProcessorType, string?, Action{ExportActivityProcessorOptions}?)" path="/param[@name='configure']"/></param>
/// <param name="configure">Callback action to configure <see
/// cref="ExportActivityProcessorOptions"/>.</param>
/// <returns>The supplied <see cref="TracerProviderBuilder"/> for chaining.</returns>
public static TracerProviderBuilder AddExporter<T>(
this TracerProviderBuilder tracerProviderBuilder,
ExportProcessorType exportProcessorType,
Action<ExportActivityProcessorOptions> configure)
where T : BaseExporter<Activity>
=> AddExporter<T>(tracerProviderBuilder, exportProcessorType, name: null, configure);
{
Guard.ThrowIfNull(configure);
return AddExporter<T>(tracerProviderBuilder, exportProcessorType, name: null, configure);
}
/// <summary>
/// Adds an exporter to the provider which will be retrieved using dependency injection.
@ -247,11 +259,9 @@ namespace OpenTelemetry.Trace
/// <typeparam name="T">Exporter type.</typeparam>
/// <param name="tracerProviderBuilder"><see cref="TracerProviderBuilder"/>.</param>
/// <param name="exportProcessorType"><see cref="ExportProcessorType"/>.</param>
/// <param name="name">Name which is used when retrieving options.</param>
/// <param name="configure">Callback action to configure <see
/// cref="ExportActivityProcessorOptions"/>. Only invoked when <paramref
/// name="exportProcessorType"/> is <see
/// cref="ExportProcessorType.Batch"/>.</param>
/// <param name="name">Optional name which is used when retrieving options.</param>
/// <param name="configure">Optional callback action to configure <see
/// cref="ExportActivityProcessorOptions"/>.</param>
/// <returns>The supplied <see cref="TracerProviderBuilder"/> for chaining.</returns>
public static TracerProviderBuilder AddExporter<T>(
this TracerProviderBuilder tracerProviderBuilder,

View File

@ -21,6 +21,7 @@ using System.Linq;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using OpenTelemetry.Resources;
using Xunit;
@ -319,17 +320,19 @@ namespace OpenTelemetry.Trace.Tests
[Fact]
public void AddExporterWithOptionsTest()
{
int optionsInvocations = 0;
int allOptionsInvocations = 0;
int exporter1Invocations = 0;
int exporter2Invocations = 0;
var builder = Sdk.CreateTracerProviderBuilder();
builder.ConfigureServices(services =>
{
services.Configure<ExportActivityProcessorOptions>(options =>
services.ConfigureAll<ExportActivityProcessorOptions>(options =>
{
// Note: This is testing options integration
// Note: This fires for exporter1 & exporter2.
optionsInvocations++;
allOptionsInvocations++;
options.BatchExportProcessorOptions.MaxExportBatchSize = 18;
});
@ -338,19 +341,30 @@ namespace OpenTelemetry.Trace.Tests
builder.AddExporter(
ExportProcessorType.Simple,
new MyExporter(),
"exporter1",
options =>
{
// Note: Options delegate isn't invoked for simple processor type
Assert.True(false);
exporter1Invocations++;
Assert.Equal(18, options.BatchExportProcessorOptions.MaxExportBatchSize);
// Note: This will be ignored. Type can't be changed from what is passed to AddExporter.
options.ExportProcessorType = ExportProcessorType.Batch;
options.BatchExportProcessorOptions.MaxExportBatchSize = 19;
});
builder.AddExporter<MyExporter>(
ExportProcessorType.Batch,
"exporter2",
options =>
{
optionsInvocations++;
exporter2Invocations++;
Assert.Equal(18, options.BatchExportProcessorOptions.MaxExportBatchSize);
// Note: This will be ignored. Type can't be changed from what is passed to AddExporter.
options.ExportProcessorType = ExportProcessorType.Simple;
options.BatchExportProcessorOptions.MaxExportBatchSize = 100;
});
@ -358,7 +372,21 @@ namespace OpenTelemetry.Trace.Tests
Assert.NotNull(provider);
Assert.Equal(2, optionsInvocations);
var unknownOptions = provider.ServiceProvider.GetRequiredService<IOptionsMonitor<ExportActivityProcessorOptions>>().Get("unknownExporter");
Assert.Equal(18, unknownOptions.BatchExportProcessorOptions.MaxExportBatchSize);
var exporter1Options = provider.ServiceProvider.GetRequiredService<IOptionsMonitor<ExportActivityProcessorOptions>>().Get("exporter1");
Assert.Equal(19, exporter1Options.BatchExportProcessorOptions.MaxExportBatchSize);
var exporter2Options = provider.ServiceProvider.GetRequiredService<IOptionsMonitor<ExportActivityProcessorOptions>>().Get("exporter2");
Assert.Equal(100, exporter2Options.BatchExportProcessorOptions.MaxExportBatchSize);
Assert.Equal(3, allOptionsInvocations);
Assert.Equal(1, exporter1Invocations);
Assert.Equal(1, exporter2Invocations);
var processor = provider.Processor as CompositeProcessor<Activity>;