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

[sdk + otlp] Add log processor factory overload #4916

Merged
merged 37 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
8fa8315
WIP supporting options through DI.
CodeBlanch Oct 3, 2023
7890043
Fix up public api files.
CodeBlanch Oct 3, 2023
d5fe070
Fixes.
CodeBlanch Oct 3, 2023
31d362d
merge main
Yun-Ting Nov 8, 2023
5384937
api files
Yun-Ting Nov 8, 2023
594897c
fix issue about null
Yun-Ting Nov 8, 2023
8a61c5a
added some unit tests
Yun-Ting Nov 9, 2023
65e23e1
Merge branch 'main' into otlp-logs-options-di
Yun-Ting Nov 9, 2023
f0eb125
changelog and small fixes
Yun-Ting Nov 9, 2023
0ecadec
Merge branch 'main' into otlp-logs-options-di
Yun-Ting Nov 9, 2023
7f042e7
CHANGELOG tweak.
CodeBlanch Nov 13, 2023
5ba7042
XML comment tweak.
CodeBlanch Nov 13, 2023
a2e935e
CHANGELOG tweak.
CodeBlanch Nov 13, 2023
fd2d4b4
Support named options.
CodeBlanch Nov 13, 2023
7ad1594
Doc updates.
CodeBlanch Nov 13, 2023
0b024df
Lint.
CodeBlanch Nov 13, 2023
afea760
Tweaks and nullable decorations.
CodeBlanch Nov 13, 2023
8cd1574
Lint.
CodeBlanch Nov 13, 2023
cb1da67
Code review.
CodeBlanch Nov 14, 2023
6fc8cca
Tweaks.
CodeBlanch Nov 14, 2023
9f8d737
Merge branch 'main' into otlp-logs-options-di
Yun-Ting Nov 14, 2023
97e31a2
Bug fixes and tests.
CodeBlanch Nov 15, 2023
7ebbff6
Merge branch 'otlp-logs-options-di' of https://github.com/CodeBlanch/…
CodeBlanch Nov 15, 2023
f43b8ad
Merge remote-tracking branch 'upstream/main' into otlp-logs-options-di
CodeBlanch Nov 15, 2023
6dc6f04
addressed comment
Yun-Ting Nov 15, 2023
3b00b5f
A bit of cleanup.
CodeBlanch Nov 15, 2023
5b987c8
Merge branch 'main' into otlp-logs-options-di
Yun-Ting Nov 15, 2023
9f46d13
Merge branch 'otlp-logs-options-di' of https://github.com/CodeBlanch/…
Yun-Ting Nov 15, 2023
fcd2dff
add test paths for optional name
Yun-Ting Nov 15, 2023
a505998
Merge branch 'main' into otlp-logs-options-di
Yun-Ting Nov 15, 2023
810ac75
Merge branch 'main' into otlp-logs-options-di
Yun-Ting Nov 16, 2023
ae4d3f8
Test refactor.
CodeBlanch Nov 16, 2023
87f6405
Test tweaks.
CodeBlanch Nov 16, 2023
d8dece2
Merge from main.
CodeBlanch Nov 21, 2023
a65af27
Merge from main.
CodeBlanch Nov 22, 2023
532101f
README tweaks.
CodeBlanch Nov 22, 2023
3477837
Merge branch 'main' into otlp-logs-options-di
Yun-Ting Nov 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#nullable enable
OpenTelemetry.Exporter.OtlpExporterOptions
OpenTelemetry.Exporter.OtlpExporterOptions.BatchExportProcessorOptions.get -> OpenTelemetry.BatchExportProcessorOptions<System.Diagnostics.Activity>
OpenTelemetry.Exporter.OtlpExporterOptions.BatchExportProcessorOptions.set -> void
OpenTelemetry.Exporter.OtlpExporterOptions.Endpoint.get -> System.Uri
OpenTelemetry.Exporter.OtlpExporterOptions.Endpoint.set -> void
~OpenTelemetry.Exporter.OtlpExporterOptions.BatchExportProcessorOptions.get -> OpenTelemetry.BatchExportProcessorOptions<System.Diagnostics.Activity>
~OpenTelemetry.Exporter.OtlpExporterOptions.BatchExportProcessorOptions.set -> void
~OpenTelemetry.Exporter.OtlpExporterOptions.Endpoint.get -> System.Uri
~OpenTelemetry.Exporter.OtlpExporterOptions.Endpoint.set -> void
OpenTelemetry.Exporter.OtlpExporterOptions.ExportProcessorType.get -> OpenTelemetry.ExportProcessorType
OpenTelemetry.Exporter.OtlpExporterOptions.ExportProcessorType.set -> void
OpenTelemetry.Exporter.OtlpExporterOptions.Headers.get -> string
OpenTelemetry.Exporter.OtlpExporterOptions.Headers.set -> void
OpenTelemetry.Exporter.OtlpExporterOptions.HttpClientFactory.get -> System.Func<System.Net.Http.HttpClient>
OpenTelemetry.Exporter.OtlpExporterOptions.HttpClientFactory.set -> void
~OpenTelemetry.Exporter.OtlpExporterOptions.Headers.get -> string
~OpenTelemetry.Exporter.OtlpExporterOptions.Headers.set -> void
~OpenTelemetry.Exporter.OtlpExporterOptions.HttpClientFactory.get -> System.Func<System.Net.Http.HttpClient>
~OpenTelemetry.Exporter.OtlpExporterOptions.HttpClientFactory.set -> void
OpenTelemetry.Exporter.OtlpExporterOptions.OtlpExporterOptions() -> void
OpenTelemetry.Exporter.OtlpExporterOptions.Protocol.get -> OpenTelemetry.Exporter.OtlpExportProtocol
OpenTelemetry.Exporter.OtlpExporterOptions.Protocol.set -> void
Expand All @@ -18,24 +19,24 @@ OpenTelemetry.Exporter.OtlpExportProtocol
OpenTelemetry.Exporter.OtlpExportProtocol.Grpc = 0 -> OpenTelemetry.Exporter.OtlpExportProtocol
OpenTelemetry.Exporter.OtlpExportProtocol.HttpProtobuf = 1 -> OpenTelemetry.Exporter.OtlpExportProtocol
OpenTelemetry.Exporter.OtlpMetricExporter
OpenTelemetry.Exporter.OtlpMetricExporter.OtlpMetricExporter(OpenTelemetry.Exporter.OtlpExporterOptions options) -> void
~OpenTelemetry.Exporter.OtlpMetricExporter.OtlpMetricExporter(OpenTelemetry.Exporter.OtlpExporterOptions options) -> void
OpenTelemetry.Exporter.OtlpTraceExporter
OpenTelemetry.Exporter.OtlpTraceExporter.OtlpTraceExporter(OpenTelemetry.Exporter.OtlpExporterOptions options) -> void
~OpenTelemetry.Exporter.OtlpTraceExporter.OtlpTraceExporter(OpenTelemetry.Exporter.OtlpExporterOptions options) -> void
OpenTelemetry.Logs.OtlpLogExporterHelperExtensions
OpenTelemetry.Metrics.OtlpMetricExporterExtensions
OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions
override OpenTelemetry.Exporter.OtlpMetricExporter.Export(in OpenTelemetry.Batch<OpenTelemetry.Metrics.Metric> metrics) -> OpenTelemetry.ExportResult
~override OpenTelemetry.Exporter.OtlpMetricExporter.Export(in OpenTelemetry.Batch<OpenTelemetry.Metrics.Metric> metrics) -> OpenTelemetry.ExportResult
override OpenTelemetry.Exporter.OtlpMetricExporter.OnShutdown(int timeoutMilliseconds) -> bool
override OpenTelemetry.Exporter.OtlpTraceExporter.Export(in OpenTelemetry.Batch<System.Diagnostics.Activity> activityBatch) -> OpenTelemetry.ExportResult
~override OpenTelemetry.Exporter.OtlpTraceExporter.Export(in OpenTelemetry.Batch<System.Diagnostics.Activity> activityBatch) -> OpenTelemetry.ExportResult
override OpenTelemetry.Exporter.OtlpTraceExporter.OnShutdown(int timeoutMilliseconds) -> bool
static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions
static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions, OpenTelemetry.Logs.LogRecordExportProcessorOptions> configureExporterAndProcessor) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions
static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions> configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions
static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder
static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions, OpenTelemetry.Metrics.MetricReaderOptions> configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder
static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions> configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder
static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions, OpenTelemetry.Metrics.MetricReaderOptions> configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder
static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions> configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder
static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder
static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions> configure) -> OpenTelemetry.Trace.TracerProviderBuilder
static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions> configure) -> OpenTelemetry.Trace.TracerProviderBuilder
static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions!
static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions!, OpenTelemetry.Logs.LogRecordExportProcessorOptions!>? configureExporterAndProcessor) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions!
static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions!>? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions!
~static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder
~static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions, OpenTelemetry.Metrics.MetricReaderOptions> configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder
~static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions> configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder
~static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions, OpenTelemetry.Metrics.MetricReaderOptions> configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder
~static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions> configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder
~static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder
~static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions> configure) -> OpenTelemetry.Trace.TracerProviderBuilder
~static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action<OpenTelemetry.Exporter.OtlpExporterOptions> configure) -> OpenTelemetry.Trace.TracerProviderBuilder
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#nullable enable
OpenTelemetry.Exporter.OtlpLogExporter
OpenTelemetry.Exporter.OtlpLogExporter.OtlpLogExporter(OpenTelemetry.Exporter.OtlpExporterOptions options) -> void
override OpenTelemetry.Exporter.OtlpLogExporter.Export(in OpenTelemetry.Batch<OpenTelemetry.Logs.LogRecord> logRecordBatch) -> OpenTelemetry.ExportResult
OpenTelemetry.Exporter.OtlpLogExporter.OtlpLogExporter(OpenTelemetry.Exporter.OtlpExporterOptions! options) -> void
override OpenTelemetry.Exporter.OtlpLogExporter.Export(in OpenTelemetry.Batch<OpenTelemetry.Logs.LogRecord!> logRecordBatch) -> OpenTelemetry.ExportResult
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@

## Unreleased

* Made `OpenTelemetry.Exporter.OtlpLogExporter` public. ([#4979](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4979))
* Updated `AddOtlpExporter` function to use
`AddProcessor(Func<IServiceProvider, BaseProcessor<LogRecord>> implementationFactory)`
overload for configuring `OpenTelemetryLoggerOptions` in OTLP log exporter
registration to support options being configured through `IConfiguration`.
([#4916](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4916))

* Made `OpenTelemetry.Exporter.OtlpLogExporter` public.
([#4979](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4979))

## 1.7.0-alpha.1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
// limitations under the License.
// </copyright>

#nullable enable

using System.Diagnostics;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient;
Expand All @@ -33,14 +35,14 @@ public sealed class OtlpLogExporter : BaseExporter<LogRecord>
private readonly IExportClient<OtlpCollector.ExportLogsServiceRequest> exportClient;
private readonly OtlpLogRecordTransformer otlpLogRecordTransformer;

private OtlpResource.Resource processResource;
private OtlpResource.Resource? processResource;

/// <summary>
/// Initializes a new instance of the <see cref="OtlpLogExporter"/> class.
/// </summary>
/// <param name="options">Configuration options for the exporter.</param>
public OtlpLogExporter(OtlpExporterOptions options)
: this(options, new(), null)
: this(options, sdkLimitOptions: new(), experimentalOptions: new(), exportClient: null)
{
}

Expand All @@ -49,14 +51,17 @@ public OtlpLogExporter(OtlpExporterOptions options)
/// </summary>
/// <param name="exporterOptions">Configuration options for the exporter.</param>
/// <param name="sdkLimitOptions"><see cref="SdkLimitOptions"/>.</param>
/// <param name="experimentalOptions"><see cref="ExperimentalOptions"/>.</param>
/// <param name="exportClient">Client used for sending export request.</param>
internal OtlpLogExporter(
OtlpExporterOptions exporterOptions,
SdkLimitOptions sdkLimitOptions,
IExportClient<OtlpCollector.ExportLogsServiceRequest> exportClient = null)
ExperimentalOptions experimentalOptions,
IExportClient<OtlpCollector.ExportLogsServiceRequest>? exportClient = null)
{
Debug.Assert(exporterOptions != null, "exporterOptions was null");
Debug.Assert(sdkLimitOptions != null, "sdkLimitOptions was null");
Debug.Assert(experimentalOptions != null, "experimentalOptions was null");

// Each of the Otlp exporters: Traces, Metrics, and Logs set the same value for `OtlpKeyValueTransformer.LogUnsupportedAttributeType`
// and `ConfigurationExtensions.LogInvalidEnvironmentVariable` so it should be fine even if these exporters are used together.
Expand All @@ -76,21 +81,22 @@ public OtlpLogExporter(OtlpExporterOptions options)
}
else
{
this.exportClient = exporterOptions.GetLogExportClient();
this.exportClient = exporterOptions!.GetLogExportClient();
}

this.otlpLogRecordTransformer = new OtlpLogRecordTransformer(sdkLimitOptions, new());
this.otlpLogRecordTransformer = new OtlpLogRecordTransformer(sdkLimitOptions!, experimentalOptions!);
}

internal OtlpResource.Resource ProcessResource => this.processResource ??= this.ParentProvider.GetResource().ToOtlpResource();
internal OtlpResource.Resource ProcessResource
=> this.processResource ??= this.ParentProvider.GetResource().ToOtlpResource();

/// <inheritdoc/>
public override ExportResult Export(in Batch<LogRecord> logRecordBatch)
{
// Prevents the exporter's gRPC and HTTP operations from being instrumented.
using var scope = SuppressInstrumentationScope.Begin();

OtlpCollector.ExportLogsServiceRequest request = null;
OtlpCollector.ExportLogsServiceRequest? request = null;

try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,16 @@
// limitations under the License.
// </copyright>

#nullable enable

using System.Diagnostics;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OpenTelemetry.Exporter;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
using OpenTelemetry.Internal;

namespace OpenTelemetry.Logs;

Expand All @@ -31,7 +39,7 @@ public static class OtlpLogExporterHelperExtensions
/// <param name="loggerOptions"><see cref="OpenTelemetryLoggerOptions"/> options to use.</param>
/// <returns>The instance of <see cref="OpenTelemetryLoggerOptions"/> to chain the calls.</returns>
public static OpenTelemetryLoggerOptions AddOtlpExporter(this OpenTelemetryLoggerOptions loggerOptions)
=> AddOtlpExporterInternal(loggerOptions, configure: null);
=> AddOtlpExporter(loggerOptions, configure: null);

/// <summary>
/// Adds an OTLP Exporter to the OpenTelemetry <see cref="ILoggerProvider"/>.
Expand All @@ -41,8 +49,22 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter(this OpenTelemetryLogge
/// <returns>The instance of <see cref="OpenTelemetryLoggerOptions"/> to chain the calls.</returns>
public static OpenTelemetryLoggerOptions AddOtlpExporter(
this OpenTelemetryLoggerOptions loggerOptions,
Action<OtlpExporterOptions> configure)
=> AddOtlpExporterInternal(loggerOptions, configure);
Action<OtlpExporterOptions>? configure)
{
Guard.ThrowIfNull(loggerOptions);

var name = Options.DefaultName;

return loggerOptions.AddProcessor(sp =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From end user perspective: This scenario of enabling IConfiguration/SdkLimitOptions/BatchOptions will only be possible when they have the servicecollection already available like in ASP.NET Core apps. Unlike in case of tracing/metrics where they can call ConfigureServices extension. Is my understanding correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically I would expect only host users (AspNetCore or generic host) to care about deep IConfiguration integration. But it is also available for manual scenarios too if users want it.

Here is how you would do it manually for traces & logs:

var config = new ConfigurationBuilder()
    .AddJsonFile("appSettings.json")
    .AddEnvironmentVariables()
    .AddCommandLine(args)
    .Build();

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .ConfigureServices(services => services.AddSingleton<IConfiguration>(config))
    .AddOtlpExporter()
    .Build();

using var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.Services.AddSingleton<IConfiguration>(config);

    builder.AddOpenTelemetry(logging => logging.AddOtlpExporter());
});

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a test to validate this scenario?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see:

public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggerFactoryCreate(string name, bool optionalNameMatch)

{
var exporterOptions = sp.GetRequiredService<IOptionsFactory<OtlpExporterOptions>>().Create(name);
var processorOptions = sp.GetRequiredService<IOptionsMonitor<LogRecordExportProcessorOptions>>().Get(name);

configure?.Invoke(exporterOptions);

return BuildOtlpLogExporter(sp, exporterOptions, processorOptions);
});
}

/// <summary>
/// Adds an OTLP Exporter to the OpenTelemetry <see cref="ILoggerProvider"/>.
Expand All @@ -52,29 +74,53 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter(this OpenTelemetryLogge
/// <returns>The instance of <see cref="OpenTelemetryLoggerOptions"/> to chain the calls.</returns>
public static OpenTelemetryLoggerOptions AddOtlpExporter(
this OpenTelemetryLoggerOptions loggerOptions,
Action<OtlpExporterOptions, LogRecordExportProcessorOptions> configureExporterAndProcessor)
Action<OtlpExporterOptions, LogRecordExportProcessorOptions>? configureExporterAndProcessor)
{
var exporterOptions = new OtlpExporterOptions();
var processorOptions = new LogRecordExportProcessorOptions();
Guard.ThrowIfNull(loggerOptions);

var name = Options.DefaultName;

return loggerOptions.AddProcessor(sp =>
{
var exporterOptions = sp.GetRequiredService<IOptionsFactory<OtlpExporterOptions>>().Create(name);
var processorOptions = sp.GetRequiredService<IOptionsMonitor<LogRecordExportProcessorOptions>>().Get(name);

configureExporterAndProcessor?.Invoke(exporterOptions, processorOptions);
configureExporterAndProcessor?.Invoke(exporterOptions, processorOptions);

return loggerOptions.AddProcessor(BuildOtlpLogExporter(exporterOptions, processorOptions));
return BuildOtlpLogExporter(sp, exporterOptions, processorOptions);
});
}

internal static BaseProcessor<LogRecord> BuildOtlpLogExporter(
IServiceProvider sp,
OtlpExporterOptions exporterOptions,
LogRecordExportProcessorOptions processorOptions,
Func<BaseExporter<LogRecord>, BaseExporter<LogRecord>> configureExporterInstance = null)
Func<BaseExporter<LogRecord>, BaseExporter<LogRecord>>? configureExporterInstance = null)
{
BaseExporter<LogRecord> otlpExporter = new OtlpLogExporter(exporterOptions);
if (sp == null)
{
throw new ArgumentNullException(nameof(sp));
}

Debug.Assert(exporterOptions != null, "exporterOptions was null");
Debug.Assert(processorOptions != null, "processorOptions was null");

var config = sp.GetRequiredService<IConfiguration>();

var sdkLimitOptions = new SdkLimitOptions(config);
var experimentalOptions = new ExperimentalOptions(config);

BaseExporter<LogRecord> otlpExporter = new OtlpLogExporter(
exporterOptions!,
sdkLimitOptions,
experimentalOptions);

if (configureExporterInstance != null)
{
otlpExporter = configureExporterInstance(otlpExporter);
}

if (processorOptions.ExportProcessorType == ExportProcessorType.Simple)
if (processorOptions!.ExportProcessorType == ExportProcessorType.Simple)
{
return new SimpleLogRecordExportProcessor(otlpExporter);
}
Expand All @@ -90,15 +136,4 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter(this OpenTelemetryLogge
batchOptions.MaxExportBatchSize);
}
}

private static OpenTelemetryLoggerOptions AddOtlpExporterInternal(
OpenTelemetryLoggerOptions loggerOptions,
Action<OtlpExporterOptions> configure)
{
var exporterOptions = new OtlpExporterOptions();

configure?.Invoke(exporterOptions);

return loggerOptions.AddProcessor(BuildOtlpLogExporter(exporterOptions, new()));
}
}