diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt
index e69de29bb2d..b0659b798bb 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt
@@ -0,0 +1,3 @@
+OpenTelemetry.OpenTelemetryBuilderOtlpExporterExtensions
+static OpenTelemetry.OpenTelemetryBuilderOtlpExporterExtensions.UseOtlpExporter(this OpenTelemetry.IOpenTelemetryBuilder! builder) -> OpenTelemetry.IOpenTelemetryBuilder!
+static OpenTelemetry.OpenTelemetryBuilderOtlpExporterExtensions.UseOtlpExporter(this OpenTelemetry.IOpenTelemetryBuilder! builder, OpenTelemetry.Exporter.OtlpExportProtocol protocol, System.Uri! baseEndpoint) -> OpenTelemetry.IOpenTelemetryBuilder!
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OpenTelemetryBuilderOtlpExporterExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OpenTelemetryBuilderOtlpExporterExtensions.cs
new file mode 100644
index 00000000000..c0368cd4ae1
--- /dev/null
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OpenTelemetryBuilderOtlpExporterExtensions.cs
@@ -0,0 +1,149 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#nullable enable
+
+using Microsoft.Extensions.Configuration;
+using OpenTelemetry.Exporter;
+using OpenTelemetry.Internal;
+
+namespace OpenTelemetry;
+
+///
+/// Contains extension methods to facilitate registration of the OpenTelemetry
+/// Protocol (OTLP) exporter into an
+/// instance.
+///
+public static class OpenTelemetryBuilderOtlpExporterExtensions
+{
+ ///
+ /// Uses OpenTelemetry Protocol (OTLP) exporter for all signals.
+ ///
+ ///
+ /// Notes:
+ ///
+ /// - Calling this method automatically enables logging, metrics, and
+ /// tracing.
+ /// - The exporter registered by this method will be added as the last
+ /// processor in the pipeline established for logging and tracing.
+ /// - This method can only be called once. Subsequent calls will results
+ /// in a being thrown.
+ /// - This method cannot be called in addition to signal-specific
+ /// AddOtlpExporter methods. If this method is called signal-specific
+ /// AddOtlpExporter calls will result in a being thrown.
+ ///
+ ///
+ /// .
+ /// Supplied for chaining calls.
+ public static IOpenTelemetryBuilder UseOtlpExporter(
+ this IOpenTelemetryBuilder builder)
+ => UseOtlpExporter(builder, name: null, configuration: null, configure: null);
+
+ ///
+ ///
+ ///
+ /// .
+ /// .
+ ///
+ /// Base endpoint to use.
+ /// Note: A signal-specific path will be appended to the base endpoint for
+ /// each signal automatically if the protocol is set to .
+ ///
+ public static IOpenTelemetryBuilder UseOtlpExporter(
+ this IOpenTelemetryBuilder builder,
+ OtlpExportProtocol protocol,
+ Uri baseEndpoint)
+ {
+ Guard.ThrowIfNull(baseEndpoint);
+
+ return UseOtlpExporter(builder, name: null, configuration: null, configure: otlpBuilder =>
+ {
+ otlpBuilder.ConfigureDefaultExporterOptions(o =>
+ {
+ o.Protocol = protocol;
+ o.Endpoint = baseEndpoint;
+ });
+ });
+ }
+
+ ///
+ ///
+ ///
+ /// .
+ /// Callback action for configuring .
+ internal static IOpenTelemetryBuilder UseOtlpExporter(
+ this IOpenTelemetryBuilder builder,
+ Action configure)
+ {
+ Guard.ThrowIfNull(configure);
+
+ return UseOtlpExporter(builder, name: null, configuration: null, configure);
+ }
+
+ ///
+ ///
+ ///
+ /// .
+ ///
+ /// to bind onto .
+ /// Notes:
+ ///
+ /// - See [TODO:Add doc link] for details on the configuration
+ /// schema.
+ /// - The instance will be
+ /// named "otlp" by default when calling this method.
+ ///
+ ///
+ ///
+ internal static IOpenTelemetryBuilder UseOtlpExporter(
+ this IOpenTelemetryBuilder builder,
+ IConfiguration configuration)
+ {
+ Guard.ThrowIfNull(configuration);
+
+ return UseOtlpExporter(builder, name: null, configuration, configure: null);
+ }
+
+ ///
+ ///
+ ///
+ /// .
+ /// Optional name which is used when retrieving options.
+ ///
+ /// Optional to bind onto .
+ /// Notes:
+ ///
+ ///
+ /// - If is not set the instance will be named "otlp" by
+ /// default when is used.
+ ///
+ ///
+ ///
+ /// Optional callback action for configuring .
+ internal static IOpenTelemetryBuilder UseOtlpExporter(
+ this IOpenTelemetryBuilder builder,
+ string? name,
+ IConfiguration? configuration,
+ Action? configure)
+ {
+ Guard.ThrowIfNull(builder);
+
+ // Note: We automatically turn on signals for "UseOtlpExporter"
+ builder
+ .WithLogging()
+ .WithMetrics()
+ .WithTracing();
+
+ var otlpBuilder = new OtlpExporterBuilder(builder.Services, name, configuration);
+
+ configure?.Invoke(otlpBuilder);
+
+ return builder;
+ }
+}
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OpenTelemetryBuilderServiceProviderExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OpenTelemetryBuilderServiceProviderExtensions.cs
new file mode 100644
index 00000000000..afa534f4160
--- /dev/null
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OpenTelemetryBuilderServiceProviderExtensions.cs
@@ -0,0 +1,27 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using Microsoft.Extensions.DependencyInjection;
+
+namespace OpenTelemetry.Exporter;
+
+internal static class OpenTelemetryBuilderServiceProviderExtensions
+{
+ public static void EnsureSingleUseOtlpExporterRegistration(this IServiceProvider serviceProvider)
+ {
+ var registrations = serviceProvider.GetServices();
+ if (registrations.Count() > 1)
+ {
+ throw new NotSupportedException("Multiple calls to UseOtlpExporter on the same IServiceCollection are not supported.");
+ }
+ }
+
+ public static void EnsureNoUseOtlpExporterRegistrations(this IServiceProvider serviceProvider)
+ {
+ var registrations = serviceProvider.GetServices();
+ if (registrations.Any())
+ {
+ throw new NotSupportedException("Signal-specific AddOtlpExporter methods and the cross-cutting UseOtlpExporter method being invoked on the same IServiceCollection is not supported.");
+ }
+ }
+}
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OtlpExporterBuilder.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OtlpExporterBuilder.cs
new file mode 100644
index 00000000000..4c3d37cf282
--- /dev/null
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OtlpExporterBuilder.cs
@@ -0,0 +1,260 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#nullable enable
+
+using System.Diagnostics;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
+using OpenTelemetry.Internal;
+using OpenTelemetry.Logs;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Trace;
+
+namespace OpenTelemetry.Exporter;
+
+internal sealed class OtlpExporterBuilder
+{
+ private const int DefaultProcessorPipelineWeight = 10_000;
+
+ private readonly string name;
+
+ internal OtlpExporterBuilder(
+ IServiceCollection services,
+ string? name,
+ IConfiguration? configuration)
+ {
+ Debug.Assert(services != null, "services was null");
+
+ if (configuration != null)
+ {
+ if (string.IsNullOrEmpty(name))
+ {
+ name = "otlp";
+ }
+
+ BindConfigurationToOptions(services!, name!, configuration);
+ }
+
+ name ??= Options.DefaultName;
+
+ RegisterOtlpExporterServices(services!, name!);
+
+ this.name = name;
+ this.Services = services!;
+ }
+
+ public IServiceCollection Services { get; }
+
+ public OtlpExporterBuilder ConfigureDefaultExporterOptions(
+ Action configure)
+ {
+ Guard.ThrowIfNull(configure);
+
+ this.Services.Configure(
+ this.name,
+ o => configure(o.DefaultOptions));
+ return this;
+ }
+
+ public OtlpExporterBuilder ConfigureLoggingExporterOptions(
+ Action configure)
+ {
+ Guard.ThrowIfNull(configure);
+
+ this.Services.Configure(
+ this.name,
+ o => configure(o.LoggingOptions));
+ return this;
+ }
+
+ public OtlpExporterBuilder ConfigureLoggingProcessorOptions(
+ Action configure)
+ {
+ Guard.ThrowIfNull(configure);
+
+ this.Services.Configure(this.name, configure);
+ return this;
+ }
+
+ public OtlpExporterBuilder ConfigureMetricsExporterOptions(
+ Action configure)
+ {
+ Guard.ThrowIfNull(configure);
+
+ this.Services.Configure(
+ this.name,
+ o => configure(o.MetricsOptions));
+ return this;
+ }
+
+ public OtlpExporterBuilder ConfigureMetricsReaderOptions(
+ Action configure)
+ {
+ Guard.ThrowIfNull(configure);
+
+ this.Services.Configure(this.name, configure);
+ return this;
+ }
+
+ public OtlpExporterBuilder ConfigureTracingExporterOptions(
+ Action configure)
+ {
+ Guard.ThrowIfNull(configure);
+
+ this.Services.Configure(
+ this.name,
+ o => configure(o.TracingOptions));
+ return this;
+ }
+
+ public OtlpExporterBuilder ConfigureTracingProcessorOptions(
+ Action configure)
+ {
+ Guard.ThrowIfNull(configure);
+
+ this.Services.Configure(this.name, configure);
+ return this;
+ }
+
+ private static void BindConfigurationToOptions(IServiceCollection services, string name, IConfiguration configuration)
+ {
+ Debug.Assert(services != null, "services was null");
+ Debug.Assert(!string.IsNullOrEmpty(name), "name was null or empty");
+ Debug.Assert(configuration != null, "configuration was null");
+
+ /* Config JSON structure is expected to be something like this:
+ {
+ "DefaultOptions": {
+ "Endpoint": "http://default_endpoint/"
+ },
+ "LoggingOptions": {
+ "Endpoint": "http://logs_endpoint/"
+ "ExportProcessorType": Batch,
+ "BatchExportProcessorOptions": {
+ "ScheduledDelayMilliseconds": 5000
+ }
+ },
+ "MetricsOptions": {
+ "Endpoint": "http://metrics_endpoint/",
+ "TemporalityPreference": "Delta",
+ "PeriodicExportingMetricReaderOptions": {
+ "ExportIntervalMilliseconds": 5000
+ }
+ },
+ "TracingOptions": {
+ "Endpoint": "http://trcing_endpoint/"
+ "ExportProcessorType": Batch,
+ "BatchExportProcessorOptions": {
+ "ScheduledDelayMilliseconds": 5000
+ }
+ }
+ }
+ */
+
+ services!.Configure(name, configuration!);
+
+ services!.Configure(
+ name, configuration!.GetSection(nameof(OtlpExporterBuilderOptions.LoggingOptions)));
+
+ services!.Configure(
+ name, configuration.GetSection(nameof(OtlpExporterBuilderOptions.MetricsOptions)));
+
+ services!.Configure(
+ name, configuration.GetSection(nameof(OtlpExporterBuilderOptions.TracingOptions)));
+ }
+
+ private static void RegisterOtlpExporterServices(IServiceCollection services, string name)
+ {
+ Debug.Assert(services != null, "services was null");
+ Debug.Assert(name != null, "name was null");
+
+ services!.AddOtlpExporterLoggingServices();
+ services!.AddOtlpExporterMetricsServices(name!);
+ services!.AddOtlpExporterTracingServices();
+
+ // Note: UseOtlpExporterRegistration is added to the service collection
+ // to detect repeated calls to "UseOtlpExporter" and to throw if
+ // "AddOtlpExporter" extensions are called
+ services!.AddSingleton();
+
+ services!.RegisterOptionsFactory((sp, configuration, name) => new OtlpExporterBuilderOptions(
+ configuration,
+ /* Note: We don't use name for SdkLimitOptions. There should only be
+ one provider for a given service collection so SdkLimitOptions is
+ treated as a single default instance. */
+ sp.GetRequiredService>().CurrentValue,
+ sp.GetRequiredService>().Get(name),
+ /* Note: We allow LogRecordExportProcessorOptions,
+ MetricReaderOptions, & ActivityExportProcessorOptions to be null
+ because those only exist if the corresponding signal is turned on.
+ Currently this extension turns on all signals so they will always be
+ there but that may change in the future so it is handled
+ defensively. */
+ sp.GetService>()?.Get(name),
+ sp.GetService>()?.Get(name),
+ sp.GetService>()?.Get(name)));
+
+ services!.ConfigureOpenTelemetryLoggerProvider(
+ (sp, logging) =>
+ {
+ var builderOptions = GetBuilderOptionsAndValidateRegistrations(sp, name!);
+
+ var processor = OtlpLogExporterHelperExtensions.BuildOtlpLogExporter(
+ sp,
+ builderOptions.LoggingOptionsInstance.ApplyDefaults(builderOptions.DefaultOptionsInstance),
+ builderOptions.LogRecordExportProcessorOptions ?? throw new InvalidOperationException("LogRecordExportProcessorOptions were missing with logging enabled"),
+ builderOptions.SdkLimitOptions,
+ builderOptions.ExperimentalOptions,
+ skipUseOtlpExporterRegistrationCheck: true);
+
+ processor.PipelineWeight = DefaultProcessorPipelineWeight;
+
+ logging.AddProcessor(processor);
+ });
+
+ services!.ConfigureOpenTelemetryMeterProvider(
+ (sp, metrics) =>
+ {
+ var builderOptions = GetBuilderOptionsAndValidateRegistrations(sp, name!);
+
+ metrics.AddReader(
+ OtlpMetricExporterExtensions.BuildOtlpExporterMetricReader(
+ sp,
+ builderOptions.MetricsOptionsInstance.ApplyDefaults(builderOptions.DefaultOptionsInstance),
+ builderOptions.MetricReaderOptions ?? throw new InvalidOperationException("MetricReaderOptions were missing with metrics enabled"),
+ builderOptions.ExperimentalOptions,
+ skipUseOtlpExporterRegistrationCheck: true));
+ });
+
+ services!.ConfigureOpenTelemetryTracerProvider(
+ (sp, tracing) =>
+ {
+ var builderOptions = GetBuilderOptionsAndValidateRegistrations(sp, name!);
+
+ var processorOptions = builderOptions.ActivityExportProcessorOptions ?? throw new InvalidOperationException("ActivityExportProcessorOptions were missing with tracing enabled");
+
+ var processor = OtlpTraceExporterHelperExtensions.BuildOtlpExporterProcessor(
+ sp,
+ builderOptions.TracingOptionsInstance.ApplyDefaults(builderOptions.DefaultOptionsInstance),
+ builderOptions.SdkLimitOptions,
+ builderOptions.ExperimentalOptions,
+ processorOptions.ExportProcessorType,
+ processorOptions.BatchExportProcessorOptions,
+ skipUseOtlpExporterRegistrationCheck: true);
+
+ processor.PipelineWeight = DefaultProcessorPipelineWeight;
+
+ tracing.AddProcessor(processor);
+ });
+
+ static OtlpExporterBuilderOptions GetBuilderOptionsAndValidateRegistrations(IServiceProvider sp, string name)
+ {
+ sp.EnsureSingleUseOtlpExporterRegistration();
+
+ return sp.GetRequiredService>().Get(name);
+ }
+ }
+}
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OtlpExporterBuilderOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OtlpExporterBuilderOptions.cs
new file mode 100644
index 00000000000..e3ba3541ffb
--- /dev/null
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/OtlpExporterBuilderOptions.cs
@@ -0,0 +1,64 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#nullable enable
+
+using System.Diagnostics;
+using Microsoft.Extensions.Configuration;
+using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
+using OpenTelemetry.Logs;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Trace;
+
+namespace OpenTelemetry.Exporter;
+
+internal sealed class OtlpExporterBuilderOptions
+{
+ internal readonly SdkLimitOptions SdkLimitOptions;
+ internal readonly ExperimentalOptions ExperimentalOptions;
+ internal readonly LogRecordExportProcessorOptions? LogRecordExportProcessorOptions;
+ internal readonly MetricReaderOptions? MetricReaderOptions;
+ internal readonly ActivityExportProcessorOptions? ActivityExportProcessorOptions;
+
+ internal readonly OtlpExporterOptions DefaultOptionsInstance;
+ internal readonly OtlpExporterOptions LoggingOptionsInstance;
+ internal readonly OtlpExporterOptions MetricsOptionsInstance;
+ internal readonly OtlpExporterOptions TracingOptionsInstance;
+
+ internal OtlpExporterBuilderOptions(
+ IConfiguration configuration,
+ SdkLimitOptions sdkLimitOptions,
+ ExperimentalOptions experimentalOptions,
+ LogRecordExportProcessorOptions? logRecordExportProcessorOptions,
+ MetricReaderOptions? metricReaderOptions,
+ ActivityExportProcessorOptions? activityExportProcessorOptions)
+ {
+ Debug.Assert(configuration != null, "configuration was null");
+ Debug.Assert(sdkLimitOptions != null, "sdkLimitOptions was null");
+ Debug.Assert(experimentalOptions != null, "experimentalOptions was null");
+
+ this.SdkLimitOptions = sdkLimitOptions!;
+ this.ExperimentalOptions = experimentalOptions!;
+ this.LogRecordExportProcessorOptions = logRecordExportProcessorOptions;
+ this.MetricReaderOptions = metricReaderOptions;
+ this.ActivityExportProcessorOptions = activityExportProcessorOptions;
+
+ var defaultBatchOptions = this.ActivityExportProcessorOptions!.BatchExportProcessorOptions;
+
+ this.DefaultOptionsInstance = new OtlpExporterOptions(configuration!, OtlpExporterOptionsConfigurationType.Default, defaultBatchOptions);
+
+ this.LoggingOptionsInstance = new OtlpExporterOptions(configuration!, OtlpExporterOptionsConfigurationType.Logs, defaultBatchOptions);
+
+ this.MetricsOptionsInstance = new OtlpExporterOptions(configuration!, OtlpExporterOptionsConfigurationType.Metrics, defaultBatchOptions);
+
+ this.TracingOptionsInstance = new OtlpExporterOptions(configuration!, OtlpExporterOptionsConfigurationType.Traces, defaultBatchOptions);
+ }
+
+ public IOtlpExporterOptions DefaultOptions => this.DefaultOptionsInstance;
+
+ public IOtlpExporterOptions LoggingOptions => this.LoggingOptionsInstance;
+
+ public IOtlpExporterOptions MetricsOptions => this.MetricsOptionsInstance;
+
+ public IOtlpExporterOptions TracingOptions => this.TracingOptionsInstance;
+}
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/UseOtlpExporterRegistration.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/UseOtlpExporterRegistration.cs
new file mode 100644
index 00000000000..ad0ad9fbc90
--- /dev/null
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Builder/UseOtlpExporterRegistration.cs
@@ -0,0 +1,13 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#nullable enable
+
+namespace OpenTelemetry.Exporter;
+
+// Note: This class is added to the IServiceCollection when UseOtlpExporter is
+// called. Its purpose is to detect registrations so that subsequent calls and
+// calls to signal-specific AddOtlpExporter can throw.
+internal sealed class UseOtlpExporterRegistration
+{
+}
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
index bbd390269d7..d698acf9a6f 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
@@ -45,6 +45,30 @@
variable to true.
([#5435](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5435))
+* Added `IOpenTelemetryBuilder.UseOtlpExporter` extension to simplify setup of
+ the OTLP Exporter when all three signals are used (logs, metrics, and traces).
+ The new extension has the following behaviors:
+
+ * Calling `UseOtlpExporter` will automatically enable logging, tracing, and
+ metrics. Additional calls to `WithLogging`, `WithMetrics`, and `WithTracing`
+ are NOT required however for metrics and tracing sources/meters still need
+ to be enabled.
+
+ * `UseOtlpExporter` can only be called once and cannot be used with the
+ existing `AddOtlpExporter` extensions. Extra calls will result in
+ `NotSupportedException`s being thrown.
+
+ * `UseOtlpExporter` will register the OTLP Exporter at the end of the
+ processor pipeline for logging and tracing.
+
+ * The OTLP Exporters added for logging, tracing, and metrics can be configured
+ using environment variables or `IConfiguration`.
+
+ For details see: [README > Enable OTLP Exporter for all
+ signals](./README.md#enable-otlp-exporter-for-all-signals).
+
+ PR: [#5400](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5400)
+
## 1.7.0
Released 2023-Dec-08
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/IOtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/IOtlpExporterOptions.cs
new file mode 100644
index 00000000000..4c394759a13
--- /dev/null
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/IOtlpExporterOptions.cs
@@ -0,0 +1,108 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#nullable enable
+
+#if NETFRAMEWORK
+using System.Net.Http;
+#endif
+
+namespace OpenTelemetry.Exporter;
+
+///
+/// Describes the OpenTelemetry Protocol (OTLP) exporter options shared by all
+/// signals.
+///
+internal interface IOtlpExporterOptions
+{
+ ///
+ /// Gets or sets the the OTLP transport protocol.
+ ///
+ OtlpExportProtocol Protocol { get; set; }
+
+ ///
+ /// Gets or sets the target to which the exporter is going to send
+ /// telemetry.
+ ///
+ ///
+ /// Notes:
+ ///
+ /// - When setting the value must be a valid with scheme (http or https) and host, and may contain a
+ /// port and path.
+ /// - The default value when not set is based on the property:
+ ///
+ /// - http://localhost:4317 for .
+ /// - http://localhost:4318 for
.
+ ///
+ /// - When is set to and has
+ /// not been set the default value (http://localhost:4318) will have
+ /// a signal-specific path appended. The final default endpoint values will
+ /// be constructed as:
+ ///
+ /// - Logging: http://localhost:4318/v1/logs
+ /// - Metrics: http://localhost:4318/v1/metrics
+ /// - Tracing: http://localhost:4318/v1/traces
+ ///
+ ///
+ ///
+ ///
+ ///
+ Uri Endpoint { get; set; }
+
+ ///
+ /// Gets or sets optional headers for the connection.
+ ///
+ ///
+ /// Note: Refer to the
+ /// OpenTelemetry Specification for details on the format of .
+ ///
+ string? Headers { get; set; }
+
+ ///
+ /// Gets or sets the max waiting time (in milliseconds) for the backend to
+ /// process each batch. Default value: 10000.
+ ///
+ int TimeoutMilliseconds { get; set; }
+
+ ///
+ /// Gets or sets the factory function called to create the instance that will be used at runtime to
+ /// transmit telemetry over HTTP. The returned instance will be reused
+ /// for all export invocations.
+ ///
+ ///
+ /// Notes:
+ ///
+ /// - This is only invoked for the protocol.
+ /// - The default behavior when using tracing registration extensions is
+ /// if an IHttpClientFactory
+ /// instance can be resolved through the application then an will be
+ /// created through the factory with the name "OtlpTraceExporter" otherwise
+ /// an will be instantiated directly.
+ /// - The default behavior when using metrics registration extensions is
+ /// if an IHttpClientFactory
+ /// instance can be resolved through the application then an will be
+ /// created through the factory with the name "OtlpMetricExporter" otherwise
+ /// an will be instantiated directly.
+ /// -
+ /// The default behavior when using logging registration extensions is an
+ /// will be instantiated directly. IHttpClientFactory
+ /// is not currently supported for logging.
+ ///
+ ///
+ ///
+ Func HttpClientFactory { get; set; }
+}
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpServiceCollectionExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpServiceCollectionExtensions.cs
new file mode 100644
index 00000000000..9aeaa7bf7df
--- /dev/null
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpServiceCollectionExtensions.cs
@@ -0,0 +1,62 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#nullable enable
+
+using System.Diagnostics;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
+using OpenTelemetry.Internal;
+using OpenTelemetry.Metrics;
+
+namespace OpenTelemetry.Exporter;
+
+internal static class OtlpServiceCollectionExtensions
+{
+ public static void AddOtlpExporterLoggingServices(this IServiceCollection services)
+ {
+ Debug.Assert(services != null, "services was null");
+
+ AddOtlpExporterSharedServices(services!, registerSdkLimitOptions: true);
+ }
+
+ public static void AddOtlpExporterMetricsServices(this IServiceCollection services, string name)
+ {
+ Debug.Assert(services != null, "services was null");
+ Debug.Assert(name != null, "name was null");
+
+ AddOtlpExporterSharedServices(services!, registerSdkLimitOptions: false);
+
+ services!.AddOptions(name).Configure(
+ (readerOptions, config) =>
+ {
+ var otlpTemporalityPreference = config[OtlpSpecConfigDefinitions.MetricsTemporalityPreferenceEnvVarName];
+ if (!string.IsNullOrWhiteSpace(otlpTemporalityPreference)
+ && Enum.TryParse(otlpTemporalityPreference, ignoreCase: true, out var enumValue))
+ {
+ readerOptions.TemporalityPreference = enumValue;
+ }
+ });
+ }
+
+ public static void AddOtlpExporterTracingServices(this IServiceCollection services)
+ {
+ Debug.Assert(services != null, "services was null");
+
+ AddOtlpExporterSharedServices(services!, registerSdkLimitOptions: true);
+ }
+
+ private static void AddOtlpExporterSharedServices(
+ IServiceCollection services,
+ bool registerSdkLimitOptions)
+ {
+ services.RegisterOptionsFactory(OtlpExporterOptions.CreateOtlpExporterOptions);
+ services.RegisterOptionsFactory(configuration => new ExperimentalOptions(configuration));
+
+ if (registerSdkLimitOptions)
+ {
+ services.RegisterOptionsFactory(configuration => new SdkLimitOptions(configuration));
+ }
+ }
+}
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj
index bed60120451..f4de3db506a 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj
@@ -35,14 +35,10 @@
NOT required because this project sees API + SDK internals -->
-
-
-
-
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
index 9c912b6b731..2a49efb1db7 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
@@ -4,14 +4,13 @@
#nullable enable
using System.Diagnostics;
-using System.Reflection;
#if NETFRAMEWORK
using System.Net.Http;
#endif
+using System.Reflection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
-using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
using OpenTelemetry.Internal;
using OpenTelemetry.Trace;
@@ -25,7 +24,7 @@ namespace OpenTelemetry.Exporter;
/// OTEL_EXPORTER_OTLP_TIMEOUT, and OTEL_EXPORTER_OTLP_PROTOCOL environment
/// variables are parsed during object construction.
///
-public class OtlpExporterOptions
+public class OtlpExporterOptions : IOtlpExporterOptions
{
internal const string DefaultGrpcEndpoint = "http://localhost:4317";
internal const string DefaultHttpEndpoint = "http://localhost:4318";
@@ -40,7 +39,9 @@ public class OtlpExporterOptions
private const string UserAgentProduct = "OTel-OTLP-Exporter-Dotnet";
+ private OtlpExportProtocol? protocol;
private Uri? endpoint;
+ private int? timeoutMilliseconds;
private Func? httpClientFactory;
///
@@ -80,38 +81,7 @@ internal OtlpExporterOptions(
this.BatchExportProcessorOptions = defaultBatchOptions!;
}
- ///
- /// Gets or sets the target to which the exporter is going to send
- /// telemetry.
- ///
- ///
- /// Notes:
- ///
- /// - When setting the value must be a valid with scheme (http or https) and host, and may contain a
- /// port and path.
- /// - The default value when not set is based on the property:
- ///
- /// - http://localhost:4317 for .
- /// - http://localhost:4318 for
.
- ///
- /// - When is set to and has
- /// not been set the default value (http://localhost:4318) will have
- /// a signal-specific path appended. The final default endpoint values will
- /// be constructed as:
- ///
- /// - Logging: http://localhost:4318/v1/logs
- /// - Metrics: http://localhost:4318/v1/metrics
- /// - Tracing: http://localhost:4318/v1/traces
- ///
- ///
- ///
- ///
- ///
+ ///
public Uri Endpoint
{
get
@@ -135,27 +105,22 @@ public Uri Endpoint
}
}
- ///
- /// Gets or sets optional headers for the connection.
- ///
- ///
- /// Note: Refer to the
- /// OpenTelemetry Specification for details on the format of .
- ///
+ ///
public string? Headers { get; set; }
- ///
- /// Gets or sets the max waiting time (in milliseconds) for the backend to
- /// process each batch. Default value: 10000.
- ///
- public int TimeoutMilliseconds { get; set; } = 10000;
+ ///
+ public int TimeoutMilliseconds
+ {
+ get => this.timeoutMilliseconds ?? 10000;
+ set => this.timeoutMilliseconds = value;
+ }
- ///
- /// Gets or sets the the OTLP transport protocol.
- ///
- public OtlpExportProtocol Protocol { get; set; } = DefaultOtlpExportProtocol;
+ ///
+ public OtlpExportProtocol Protocol
+ {
+ get => this.protocol ?? DefaultOtlpExportProtocol;
+ set => this.protocol = value;
+ }
///
/// Gets or sets the export processor type to be used with the OpenTelemetry Protocol Exporter. The default value is .
@@ -169,39 +134,7 @@ public Uri Endpoint
/// Note: This only applies when exporting traces.
public BatchExportProcessorOptions BatchExportProcessorOptions { get; set; }
- ///
- /// Gets or sets the factory function called to create the instance that will be used at runtime to
- /// transmit telemetry over HTTP. The returned instance will be reused
- /// for all export invocations.
- ///
- ///
- /// Notes:
- ///
- /// - This is only invoked for the protocol.
- /// - The default behavior when using tracing registration extensions is
- /// if an IHttpClientFactory
- /// instance can be resolved through the application then an will be
- /// created through the factory with the name "OtlpTraceExporter" otherwise
- /// an will be instantiated directly.
- /// - The default behavior when using metrics registration extensions is
- /// if an IHttpClientFactory
- /// instance can be resolved through the application then an will be
- /// created through the factory with the name "OtlpMetricExporter" otherwise
- /// an will be instantiated directly.
- /// -
- /// The default behavior when using logging registration extensions is an
- /// will be instantiated directly. IHttpClientFactory
- /// is not currently supported for logging.
- ///
- ///
- ///
+ ///
public Func HttpClientFactory
{
get => this.httpClientFactory ?? this.DefaultHttpClientFactory;
@@ -223,11 +156,11 @@ public Func HttpClientFactory
///
internal bool AppendSignalPathToEndpoint { get; private set; } = true;
- internal static void RegisterOtlpExporterOptionsFactory(IServiceCollection services)
- {
- services.RegisterOptionsFactory(CreateOtlpExporterOptions);
- services.RegisterOptionsFactory(configuration => new ExperimentalOptions(configuration));
- }
+ internal bool HasData
+ => this.protocol.HasValue
+ || this.endpoint != null
+ || this.timeoutMilliseconds.HasValue
+ || this.httpClientFactory != null;
internal static OtlpExporterOptions CreateOtlpExporterOptions(
IServiceProvider serviceProvider,
@@ -271,6 +204,25 @@ internal void ApplyConfigurationUsingSpecificationEnvVars(
}
}
+ internal OtlpExporterOptions ApplyDefaults(OtlpExporterOptions defaultExporterOptions)
+ {
+ this.protocol ??= defaultExporterOptions.protocol;
+
+ this.endpoint ??= defaultExporterOptions.endpoint;
+
+ // Note: We leave AppendSignalPathToEndpoint set to true here because we
+ // want to append the signal if the endpoint came from the default
+ // endpoint.
+
+ this.Headers ??= defaultExporterOptions.Headers;
+
+ this.timeoutMilliseconds ??= defaultExporterOptions.timeoutMilliseconds;
+
+ this.httpClientFactory ??= defaultExporterOptions.httpClientFactory;
+
+ return this;
+ }
+
private static string GetUserAgentString()
{
try
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs
index dbf156c1a0b..ca5a759caf4 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs
@@ -224,7 +224,7 @@ static LoggerProviderBuilder AddOtlpExporter(
services.Configure(finalOptionsName, configureExporter);
}
- RegisterOptions(services);
+ services.AddOtlpExporterLoggingServices();
});
return builder.AddProcessor(sp =>
@@ -299,7 +299,7 @@ static LoggerProviderBuilder AddOtlpExporter(
{
var finalOptionsName = name ?? Options.DefaultName;
- builder.ConfigureServices(RegisterOptions);
+ builder.ConfigureServices(services => services.AddOtlpExporterLoggingServices());
return builder.AddProcessor(sp =>
{
@@ -342,21 +342,25 @@ static LoggerProviderBuilder AddOtlpExporter(
}
internal static BaseProcessor BuildOtlpLogExporter(
- IServiceProvider sp,
+ IServiceProvider serviceProvider,
OtlpExporterOptions exporterOptions,
LogRecordExportProcessorOptions processorOptions,
SdkLimitOptions sdkLimitOptions,
ExperimentalOptions experimentalOptions,
+ bool skipUseOtlpExporterRegistrationCheck = false,
Func, BaseExporter>? configureExporterInstance = null)
{
- // Note: sp is not currently used by this method but it should be used
- // at some point for IHttpClientFactory integration.
- Debug.Assert(sp != null, "sp was null");
+ Debug.Assert(serviceProvider != null, "serviceProvider was null");
Debug.Assert(exporterOptions != null, "exporterOptions was null");
Debug.Assert(processorOptions != null, "processorOptions was null");
Debug.Assert(sdkLimitOptions != null, "sdkLimitOptions was null");
Debug.Assert(experimentalOptions != null, "experimentalOptions was null");
+ if (!skipUseOtlpExporterRegistrationCheck)
+ {
+ serviceProvider.EnsureNoUseOtlpExporterRegistrations();
+ }
+
/*
* Note:
*
@@ -400,12 +404,6 @@ internal static BaseProcessor BuildOtlpLogExporter(
}
}
- private static void RegisterOptions(IServiceCollection services)
- {
- OtlpExporterOptions.RegisterOtlpExporterOptionsFactory(services);
- services.RegisterOptionsFactory(configuration => new SdkLimitOptions(configuration));
- }
-
private static T GetOptions(
IServiceProvider sp,
string? name,
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs
index 38cb1a44a66..57ad3dd47ec 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs
@@ -3,7 +3,7 @@
#nullable enable
-using Microsoft.Extensions.Configuration;
+using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OpenTelemetry.Exporter;
@@ -59,18 +59,7 @@ public static MeterProviderBuilder AddOtlpExporter(
services.Configure(finalOptionsName, configure);
}
- OtlpExporterOptions.RegisterOtlpExporterOptionsFactory(services);
-
- services.AddOptions(finalOptionsName).Configure(
- (readerOptions, config) =>
- {
- var otlpTemporalityPreference = config[OtlpSpecConfigDefinitions.MetricsTemporalityPreferenceEnvVarName];
- if (!string.IsNullOrWhiteSpace(otlpTemporalityPreference)
- && Enum.TryParse(otlpTemporalityPreference, ignoreCase: true, out var enumValue))
- {
- readerOptions.TemporalityPreference = enumValue;
- }
- });
+ services.AddOtlpExporterMetricsServices(finalOptionsName);
});
return builder.AddReader(sp =>
@@ -97,10 +86,10 @@ public static MeterProviderBuilder AddOtlpExporter(
}
return BuildOtlpExporterMetricReader(
+ sp,
exporterOptions,
sp.GetRequiredService>().Get(finalOptionsName),
- sp.GetRequiredService>().Get(finalOptionsName),
- sp);
+ sp.GetRequiredService>().Get(finalOptionsName));
});
}
@@ -137,18 +126,7 @@ public static MeterProviderBuilder AddOtlpExporter(
builder.ConfigureServices(services =>
{
- OtlpExporterOptions.RegisterOtlpExporterOptionsFactory(services);
-
- services.AddOptions(finalOptionsName).Configure(
- (readerOptions, config) =>
- {
- var otlpTemporalityPreference = config[OtlpSpecConfigDefinitions.MetricsTemporalityPreferenceEnvVarName];
- if (!string.IsNullOrWhiteSpace(otlpTemporalityPreference)
- && Enum.TryParse(otlpTemporalityPreference, ignoreCase: true, out var enumValue))
- {
- readerOptions.TemporalityPreference = enumValue;
- }
- });
+ services.AddOtlpExporterMetricsServices(finalOptionsName);
});
return builder.AddReader(sp =>
@@ -172,20 +150,31 @@ public static MeterProviderBuilder AddOtlpExporter(
configureExporterAndMetricReader?.Invoke(exporterOptions, metricReaderOptions);
return BuildOtlpExporterMetricReader(
+ sp,
exporterOptions,
metricReaderOptions,
- sp.GetRequiredService>().Get(finalOptionsName),
- sp);
+ sp.GetRequiredService>().Get(finalOptionsName));
});
}
internal static MetricReader BuildOtlpExporterMetricReader(
+ IServiceProvider serviceProvider,
OtlpExporterOptions exporterOptions,
MetricReaderOptions metricReaderOptions,
ExperimentalOptions experimentalOptions,
- IServiceProvider serviceProvider,
+ bool skipUseOtlpExporterRegistrationCheck = false,
Func, BaseExporter>? configureExporterInstance = null)
{
+ Debug.Assert(serviceProvider != null, "serviceProvider was null");
+ Debug.Assert(exporterOptions != null, "exporterOptions was null");
+ Debug.Assert(metricReaderOptions != null, "metricReaderOptions was null");
+ Debug.Assert(experimentalOptions != null, "experimentalOptions was null");
+
+ if (!skipUseOtlpExporterRegistrationCheck)
+ {
+ serviceProvider.EnsureNoUseOtlpExporterRegistrations();
+ }
+
exporterOptions.TryEnableIHttpClientFactoryIntegration(serviceProvider, "OtlpMetricExporter");
BaseExporter metricExporter = new OtlpMetricExporter(exporterOptions, experimentalOptions);
@@ -197,6 +186,6 @@ internal static MetricReader BuildOtlpExporterMetricReader(
return PeriodicExportingMetricReaderHelper.CreatePeriodicExportingMetricReader(
metricExporter,
- metricReaderOptions);
+ metricReaderOptions!);
}
}
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs
index 4e2ee7cebcb..1497276feac 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs
@@ -38,10 +38,10 @@ public OtlpTraceExporter(OtlpExporterOptions options)
/// .
/// .
internal OtlpTraceExporter(
- OtlpExporterOptions exporterOptions,
- SdkLimitOptions sdkLimitOptions,
- ExperimentalOptions experimentalOptions,
- OtlpExporterTransmissionHandler transmissionHandler = null)
+ OtlpExporterOptions exporterOptions,
+ SdkLimitOptions sdkLimitOptions,
+ ExperimentalOptions experimentalOptions,
+ OtlpExporterTransmissionHandler transmissionHandler = null)
{
Debug.Assert(exporterOptions != null, "exporterOptions was null");
Debug.Assert(sdkLimitOptions != null, "sdkLimitOptions was null");
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs
index 7ccbdd33472..036e9a90dd3 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs
@@ -59,8 +59,7 @@ public static TracerProviderBuilder AddOtlpExporter(
services.Configure(finalOptionsName, configure);
}
- OtlpExporterOptions.RegisterOtlpExporterOptionsFactory(services);
- services.RegisterOptionsFactory(configuration => new SdkLimitOptions(configuration));
+ services.AddOtlpExporterTracingServices();
});
return builder.AddProcessor(sp =>
@@ -90,23 +89,53 @@ public static TracerProviderBuilder AddOtlpExporter(
// There should only be one provider for a given service
// collection so SdkLimitOptions is treated as a single default
// instance.
- var sdkOptionsManager = sp.GetRequiredService>().CurrentValue;
+ var sdkLimitOptions = sp.GetRequiredService>().CurrentValue;
return BuildOtlpExporterProcessor(
+ sp,
exporterOptions,
- sdkOptionsManager,
- sp.GetRequiredService>().Get(finalOptionsName),
- sp);
+ sdkLimitOptions,
+ sp.GetRequiredService>().Get(finalOptionsName));
});
}
internal static BaseProcessor BuildOtlpExporterProcessor(
+ IServiceProvider serviceProvider,
OtlpExporterOptions exporterOptions,
SdkLimitOptions sdkLimitOptions,
ExperimentalOptions experimentalOptions,
+ Func, BaseExporter>? configureExporterInstance = null)
+ => BuildOtlpExporterProcessor(
+ serviceProvider,
+ exporterOptions,
+ sdkLimitOptions,
+ experimentalOptions,
+ exporterOptions.ExportProcessorType,
+ exporterOptions.BatchExportProcessorOptions ?? new BatchExportActivityProcessorOptions(),
+ skipUseOtlpExporterRegistrationCheck: false,
+ configureExporterInstance: configureExporterInstance);
+
+ internal static BaseProcessor BuildOtlpExporterProcessor(
IServiceProvider serviceProvider,
+ OtlpExporterOptions exporterOptions,
+ SdkLimitOptions sdkLimitOptions,
+ ExperimentalOptions experimentalOptions,
+ ExportProcessorType exportProcessorType,
+ BatchExportProcessorOptions batchExportProcessorOptions,
+ bool skipUseOtlpExporterRegistrationCheck = false,
Func, BaseExporter>? configureExporterInstance = null)
{
+ Debug.Assert(serviceProvider != null, "serviceProvider was null");
+ Debug.Assert(exporterOptions != null, "exporterOptions was null");
+ Debug.Assert(sdkLimitOptions != null, "sdkLimitOptions was null");
+ Debug.Assert(experimentalOptions != null, "experimentalOptions was null");
+ Debug.Assert(batchExportProcessorOptions != null, "batchExportProcessorOptions was null");
+
+ if (!skipUseOtlpExporterRegistrationCheck)
+ {
+ serviceProvider.EnsureNoUseOtlpExporterRegistrations();
+ }
+
exporterOptions.TryEnableIHttpClientFactoryIntegration(serviceProvider, "OtlpTraceExporter");
BaseExporter otlpExporter = new OtlpTraceExporter(exporterOptions, sdkLimitOptions, experimentalOptions);
@@ -116,20 +145,18 @@ internal static BaseProcessor BuildOtlpExporterProcessor(
otlpExporter = configureExporterInstance(otlpExporter);
}
- if (exporterOptions.ExportProcessorType == ExportProcessorType.Simple)
+ if (exportProcessorType == ExportProcessorType.Simple)
{
return new SimpleActivityExportProcessor(otlpExporter);
}
else
{
- var batchOptions = exporterOptions.BatchExportProcessorOptions ?? new BatchExportActivityProcessorOptions();
-
return new BatchActivityExportProcessor(
otlpExporter,
- batchOptions.MaxQueueSize,
- batchOptions.ScheduledDelayMilliseconds,
- batchOptions.ExporterTimeoutMilliseconds,
- batchOptions.MaxExportBatchSize);
+ batchExportProcessorOptions!.MaxQueueSize,
+ batchExportProcessorOptions.ScheduledDelayMilliseconds,
+ batchExportProcessorOptions.ExporterTimeoutMilliseconds,
+ batchExportProcessorOptions.MaxExportBatchSize);
}
}
}
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md
index 763c2d54deb..a670487e5f7 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md
@@ -14,6 +14,7 @@ implementation.
* [Enable Log Exporter](#enable-log-exporter)
* [Enable Metric Exporter](#enable-metric-exporter)
* [Enable Trace Exporter](#enable-trace-exporter)
+* [Enable OTLP Exporter for all signals](#enable-otlp-exporter-for-all-signals)
* [Configuration](#configuration)
* [OtlpExporterOptions](#otlpexporteroptions)
* [LogRecordExportProcessorOptions](#logrecordexportprocessoroptions)
@@ -109,6 +110,10 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder()
See the [`TestOtlpExporter.cs`](../../examples/Console/TestOtlpExporter.cs) for
runnable example.
+## Enable OTLP Exporter for all signals
+
+Content coming soon.
+
## Configuration
You can configure the `OtlpExporter` through `OtlpExporterOptions`
diff --git a/src/OpenTelemetry/AssemblyInfo.cs b/src/OpenTelemetry/AssemblyInfo.cs
index 90823131448..45c008955ad 100644
--- a/src/OpenTelemetry/AssemblyInfo.cs
+++ b/src/OpenTelemetry/AssemblyInfo.cs
@@ -5,6 +5,8 @@
[assembly: InternalsVisibleTo("OpenTelemetry.Tests" + AssemblyInfo.PublicKey)]
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.InMemory" + AssemblyInfo.PublicKey)]
+[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.OpenTelemetryProtocol" + AssemblyInfo.PublicKey)]
+[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests" + AssemblyInfo.PublicKey)]
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.AspNetCore" + AssemblyInfo.PublicKey)]
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests" + AssemblyInfo.PublicKey)]
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.HttpListener.Tests" + AssemblyInfo.PublicKey)]
@@ -14,8 +16,6 @@
#if !EXPOSE_EXPERIMENTAL_FEATURES
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Console" + AssemblyInfo.PublicKey)]
-[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.OpenTelemetryProtocol" + AssemblyInfo.PublicKey)]
-[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests" + AssemblyInfo.PublicKey)]
[assembly: InternalsVisibleTo("OpenTelemetry.Tests.Stress.Metrics" + AssemblyInfo.PublicKey)]
#endif
diff --git a/src/OpenTelemetry/CompositeProcessor.cs b/src/OpenTelemetry/CompositeProcessor.cs
index 614e0dd3b13..d59936ee87e 100644
--- a/src/OpenTelemetry/CompositeProcessor.cs
+++ b/src/OpenTelemetry/CompositeProcessor.cs
@@ -86,6 +86,18 @@ internal override void SetParentProvider(BaseProvider parentProvider)
}
}
+ internal IReadOnlyList> ToReadOnlyList()
+ {
+ var list = new List>();
+
+ for (var cur = this.Head; cur != null; cur = cur.Next)
+ {
+ list.Add(cur.Value);
+ }
+
+ return list;
+ }
+
///
protected override bool OnForceFlush(int timeoutMilliseconds)
{
diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Http2UnencryptedSupportTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Http2UnencryptedSupportTests.cs
index 673260f281d..7ef14595f06 100644
--- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Http2UnencryptedSupportTests.cs
+++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Http2UnencryptedSupportTests.cs
@@ -14,10 +14,15 @@ public Http2UnencryptedSupportTests()
public void Dispose()
{
- AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", this.initialFlagStatus);
+ this.Dispose(true);
GC.SuppressFinalize(this);
}
+ protected virtual void Dispose(bool disposing)
+ {
+ AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", this.initialFlagStatus);
+ }
+
private static bool DetermineInitialFlagStatus()
{
if (AppContext.TryGetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", out var flag))
diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs
index e7bb7822fba..49c0e054237 100644
--- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs
+++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs
@@ -21,6 +21,7 @@ public sealed class IntegrationTests : IDisposable
private const string CollectorHostnameEnvVarName = "OTEL_COLLECTOR_HOSTNAME";
private const int ExportIntervalMilliseconds = 10000;
private static readonly SdkLimitOptions DefaultSdkLimitOptions = new();
+ private static readonly ExperimentalOptions DefaultExperimentalOptions = new();
private static readonly string CollectorHostname = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(CollectorHostnameEnvVarName);
private readonly OpenTelemetryEventListener openTelemetryEventListener;
@@ -69,11 +70,11 @@ public void TraceExportResultIsSuccess(OtlpExportProtocol protocol, string endpo
var builder = Sdk.CreateTracerProviderBuilder()
.AddSource(activitySourceName);
- builder.AddProcessor(OtlpTraceExporterHelperExtensions.BuildOtlpExporterProcessor(
- exporterOptions,
- DefaultSdkLimitOptions,
- experimentalOptions: new(),
- serviceProvider: null,
+ builder.AddProcessor(sp => OtlpTraceExporterHelperExtensions.BuildOtlpExporterProcessor(
+ serviceProvider: sp,
+ exporterOptions: exporterOptions,
+ sdkLimitOptions: DefaultSdkLimitOptions,
+ experimentalOptions: DefaultExperimentalOptions,
configureExporterInstance: otlpExporter =>
{
delegatingExporter = new DelegatingExporter
@@ -151,11 +152,11 @@ public void MetricExportResultIsSuccess(OtlpExportProtocol protocol, string endp
var readerOptions = new MetricReaderOptions();
readerOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = useManualExport ? Timeout.Infinite : ExportIntervalMilliseconds;
- builder.AddReader(OtlpMetricExporterExtensions.BuildOtlpExporterMetricReader(
- exporterOptions,
- readerOptions,
- experimentalOptions: new(),
- serviceProvider: null,
+ builder.AddReader(sp => OtlpMetricExporterExtensions.BuildOtlpExporterMetricReader(
+ serviceProvider: sp,
+ exporterOptions: exporterOptions,
+ metricReaderOptions: readerOptions,
+ experimentalOptions: DefaultExperimentalOptions,
configureExporterInstance: otlpExporter =>
{
delegatingExporter = new DelegatingExporter
@@ -240,8 +241,8 @@ public void LogExportResultIsSuccess(OtlpExportProtocol protocol, string endpoin
sp,
exporterOptions,
processorOptions,
- new SdkLimitOptions(),
- new ExperimentalOptions(),
+ DefaultSdkLimitOptions,
+ DefaultExperimentalOptions,
configureExporterInstance: otlpExporter =>
{
delegatingExporter = new DelegatingExporter
diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs
index bf55abb4795..dc79c95c07b 100644
--- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs
+++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs
@@ -6,60 +6,17 @@
namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests;
+[Collection("EnvVars")]
public class OtlpExporterOptionsTests : IDisposable
{
public OtlpExporterOptionsTests()
{
- ClearEnvVars();
- }
-
- public static IEnumerable