diff --git a/docs/file-based-configuration.md b/docs/file-based-configuration.md
index 34da8f7d24..c5ee3fd538 100644
--- a/docs/file-based-configuration.md
+++ b/docs/file-based-configuration.md
@@ -49,6 +49,69 @@ fail_fast: false
flush_on_unhandled_exception: false
```
+### Tracer Provider Configuration
+
+``` yaml
+tracer_provider:
+ processors:
+ # Batch processor for OTLP HTTP
+ - batch:
+ # Configure delay interval (in milliseconds) between two consecutive exports.
+ # Value must be non-negative.
+ # If omitted or null, 5000 is used.
+ schedule_delay: 5000
+ # Configure maximum allowed time (in milliseconds) to export data.
+ # Value must be non-negative. A value of 0 indicates no limit (infinity).
+ # If omitted or null, 30000 is used.
+ export_timeout: 30000
+ # Configure maximum queue size. Value must be positive.
+ # If omitted or null, 2048 is used.
+ max_queue_size: 2048
+ # Configure maximum batch size. Value must be positive.
+ # If omitted or null, 512 is used.
+ max_export_batch_size: 512
+ # Configure exporters.
+ exporter:
+ # Configure the OTLP with HTTP transport exporter to enable it.
+ otlp_http:
+ # Configure endpoint, including the trace specific path.
+ # If omitted or null, http://localhost:4318/v1/traces is used
+ endpoint: http://localhost:4318/v1/traces
+ # Configure max time (in milliseconds) to wait for each export.
+ # Value must be non-negative. A value of 0 indicates no limit (infinity).
+ # If omitted or null, 10000 is used.
+ timeout: 10000
+ # Configure headers. Entries have higher priority than entries from .headers_list.
+ # If an entry's .value is null, the entry is ignored.
+ headers:
+ - name: api-key
+ value: "1234"
+ # Configure headers. Entries have lower priority than entries from .headers.
+ # The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.
+ # If omitted or null, no headers are added.
+ headers_list: ${OTEL_EXPORTER_OTLP_TRACES_HEADERS}
+
+ # Batch processor for OTLP gRPC
+ - batch:
+ otlp_grpc:
+ # Configuration otlp_grpc is the same as otlp_http.
+ # if otlp_http is used it will override otlp_grpc.
+ # On .NET Framework, the grpc OTLP exporter protocol is not supported.
+
+ # Batch processor for Zipkin
+ - batch:
+ exporter:
+ zipkin:
+ # Configure endpoint.
+ # If omitted or null, http://localhost:9411/api/v2/spans is used.
+ endpoint: http://localhost:9411/api/v2/spans
+
+ # Simple processor for Console
+ - simple:
+ exporter:
+ console:
+```
+
### Resource Configuration
You can configure resource attributes directly in YAML or via the
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/EnvironmentConfigurationTracerHelper.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/EnvironmentConfigurationTracerHelper.cs
index a2d3fe08cc..48fc7b6441 100644
--- a/src/OpenTelemetry.AutoInstrumentation/Configurations/EnvironmentConfigurationTracerHelper.cs
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/EnvironmentConfigurationTracerHelper.cs
@@ -2,7 +2,10 @@
// SPDX-License-Identifier: Apache-2.0
using System.Runtime.CompilerServices;
+using OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+using OpenTelemetry.AutoInstrumentation.Configurations.Otlp;
using OpenTelemetry.AutoInstrumentation.Loading;
+using OpenTelemetry.AutoInstrumentation.Logging;
using OpenTelemetry.AutoInstrumentation.Plugins;
using OpenTelemetry.Trace;
@@ -10,6 +13,8 @@ namespace OpenTelemetry.AutoInstrumentation.Configurations;
internal static class EnvironmentConfigurationTracerHelper
{
+ private static readonly IOtelLogger Logger = OtelLogging.GetLogger();
+
public static TracerProviderBuilder UseEnvironmentVariables(
this TracerProviderBuilder builder,
LazyInstrumentationLoader lazyInstrumentationLoader,
@@ -88,15 +93,147 @@ private static TracerProviderBuilder AddWcfIfNeeded(
private static TracerProviderBuilder SetExporter(this TracerProviderBuilder builder, TracerSettings settings, PluginManager pluginManager)
{
- foreach (var traceExporter in settings.TracesExporters)
+ // If no exporters are specified, it means to use processors (file-based configuration).
+ if (settings.TracesExporters.Count == 0)
{
- builder = traceExporter switch
+ if (settings.Processors != null)
{
- TracesExporter.Zipkin => Wrappers.AddZipkinExporter(builder, pluginManager),
- TracesExporter.Otlp => Wrappers.AddOtlpExporter(builder, settings, pluginManager),
- TracesExporter.Console => Wrappers.AddConsoleExporter(builder, pluginManager),
- _ => throw new ArgumentOutOfRangeException($"Traces exporter '{traceExporter}' is incorrect")
- };
+ foreach (var processor in settings.Processors)
+ {
+ if (processor.Batch != null && processor.Simple != null)
+ {
+ Logger.Debug("Both batch and simple processors are configured. It is not supported. Skipping.");
+ continue;
+ }
+
+ if (processor.Batch == null && processor.Simple == null)
+ {
+ Logger.Debug("No valid processor configured, skipping.");
+ continue;
+ }
+
+ if (processor.Batch != null)
+ {
+ var exporter = processor.Batch.Exporter;
+ if (exporter != null)
+ {
+ var exportersCount = 0;
+
+ if (exporter.OtlpHttp != null)
+ {
+ exportersCount++;
+ }
+
+ if (exporter.OtlpGrpc != null)
+ {
+ exportersCount++;
+ }
+
+ if (exporter.Zipkin != null)
+ {
+ exportersCount++;
+ }
+
+ switch (exportersCount)
+ {
+ case 0:
+ Logger.Debug("No valid exporter configured for batch processor. Skipping.");
+ continue;
+ case > 1:
+ Logger.Debug("Multiple exporters are configured for batch processor. Only one exporter is supported. Skipping.");
+ continue;
+ }
+
+ if (exporter.OtlpHttp != null)
+ {
+ if (exporter.OtlpGrpc != null || exporter.Zipkin != null)
+ {
+ Logger.Debug("Both gRPC and Zipkin exporters are configured, using gRPC.");
+ continue;
+ }
+
+ builder = Wrappers.AddOtlpHttpExporter(builder, pluginManager, processor.Batch, exporter.OtlpHttp);
+ }
+ else if (exporter.OtlpGrpc != null)
+ {
+ builder = Wrappers.AddOtlpGrpcExporter(builder, pluginManager, processor.Batch, exporter.OtlpGrpc);
+ }
+ else if (exporter.Zipkin != null)
+ {
+ builder = Wrappers.AddZipkinExporter(builder, pluginManager, processor.Batch, exporter.Zipkin);
+ }
+ }
+ }
+ else if (processor.Simple != null)
+ {
+ var exporter = processor.Simple.Exporter;
+ if (exporter != null)
+ {
+ var exportersCount = 0;
+
+ if (exporter.OtlpHttp != null)
+ {
+ exportersCount++;
+ }
+
+ if (exporter.OtlpGrpc != null)
+ {
+ exportersCount++;
+ }
+
+ if (exporter.Zipkin != null)
+ {
+ exportersCount++;
+ }
+
+ if (exporter.Console != null)
+ {
+ exportersCount++;
+ }
+
+ switch (exportersCount)
+ {
+ case 0:
+ Logger.Debug("No valid exporter configured for batch processor. Skipping.");
+ continue;
+ case > 1:
+ Logger.Debug("Multiple exporters are configured for batch processor. Only one exporter is supported. Skipping.");
+ continue;
+ }
+
+ if (exporter.OtlpHttp != null)
+ {
+ builder = Wrappers.AddOtlpHttpExporter(builder, pluginManager, exporter.OtlpHttp);
+ }
+ else if (exporter.OtlpGrpc != null)
+ {
+ builder = Wrappers.AddOtlpGrpcExporter(builder, pluginManager, exporter.OtlpGrpc);
+ }
+ else if (exporter.Zipkin != null)
+ {
+ builder = Wrappers.AddZipkinExporter(builder, pluginManager, exporter.Zipkin);
+ }
+ else if (exporter.Console != null)
+ {
+ builder = Wrappers.AddConsoleExporter(builder, pluginManager);
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ foreach (var traceExporter in settings.TracesExporters)
+ {
+ builder = traceExporter switch
+ {
+ TracesExporter.Zipkin => Wrappers.AddZipkinExporter(builder, pluginManager),
+ TracesExporter.Otlp => Wrappers.AddOtlpExporter(builder, settings, pluginManager),
+ TracesExporter.Console => Wrappers.AddConsoleExporter(builder, pluginManager),
+ _ => throw new ArgumentOutOfRangeException($"Traces exporter '{traceExporter}' is incorrect")
+ };
+ }
}
return builder;
@@ -228,11 +365,92 @@ public static TracerProviderBuilder AddOtlpExporter(TracerProviderBuilder builde
{
return builder.AddOtlpExporter(options =>
{
- // Copy Auto settings to SDK settings
settings.OtlpSettings?.CopyTo(options);
pluginManager.ConfigureTracesOptions(options);
});
}
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static TracerProviderBuilder AddOtlpHttpExporter(TracerProviderBuilder builder, PluginManager pluginManager, BatchProcessorConfig batch, OtlpHttpExporterConfig otlpHttp)
+ {
+ var otlpSettings = new OtlpSettings(OtlpSignalType.Traces, otlpHttp);
+ return builder.AddOtlpExporter(options =>
+ {
+ // Copy Auto settings to SDK settings
+ batch?.CopyTo(options.BatchExportProcessorOptions);
+ otlpSettings?.CopyTo(options);
+
+ pluginManager.ConfigureTracesOptions(options);
+ });
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static TracerProviderBuilder AddOtlpGrpcExporter(TracerProviderBuilder builder, PluginManager pluginManager, BatchProcessorConfig batch, OtlpGrpcExporterConfig otlpGrpc)
+ {
+ var otlpSettings = new OtlpSettings(otlpGrpc);
+ return builder.AddOtlpExporter(options =>
+ {
+ // Copy Auto settings to SDK settings
+ batch?.CopyTo(options.BatchExportProcessorOptions);
+ otlpSettings?.CopyTo(options);
+
+ pluginManager.ConfigureTracesOptions(options);
+ });
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static TracerProviderBuilder AddZipkinExporter(TracerProviderBuilder builder, PluginManager pluginManager, BatchProcessorConfig batch, ZipkinExporterConfig zipkin)
+ {
+ return builder.AddZipkinExporter(options =>
+ {
+ // Copy Auto settings to SDK settings
+ batch?.CopyTo(options.BatchExportProcessorOptions);
+ zipkin?.CopyTo(options);
+
+ pluginManager.ConfigureTracesOptions(options);
+ });
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static TracerProviderBuilder AddOtlpHttpExporter(TracerProviderBuilder builder, PluginManager pluginManager, OtlpHttpExporterConfig otlpHttp)
+ {
+ var otlpSettings = new OtlpSettings(OtlpSignalType.Traces, otlpHttp);
+ return builder.AddOtlpExporter(options =>
+ {
+ // Copy Auto settings to SDK settings
+ options.ExportProcessorType = ExportProcessorType.Simple;
+ otlpSettings?.CopyTo(options);
+
+ pluginManager.ConfigureTracesOptions(options);
+ });
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static TracerProviderBuilder AddOtlpGrpcExporter(TracerProviderBuilder builder, PluginManager pluginManager, OtlpGrpcExporterConfig otlpGrpc)
+ {
+ var otlpSettings = new OtlpSettings(otlpGrpc);
+ return builder.AddOtlpExporter(options =>
+ {
+ // Copy Auto settings to SDK settings
+ options.ExportProcessorType = ExportProcessorType.Simple;
+ otlpSettings?.CopyTo(options);
+
+ pluginManager.ConfigureTracesOptions(options);
+ });
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static TracerProviderBuilder AddZipkinExporter(TracerProviderBuilder builder, PluginManager pluginManager, ZipkinExporterConfig zipkin)
+ {
+ return builder.AddZipkinExporter(options =>
+ {
+ // Copy Auto settings to SDK settings
+ options.ExportProcessorType = ExportProcessorType.Simple;
+ zipkin?.CopyTo(options);
+
+ pluginManager.ConfigureTracesOptions(options);
+ });
+ }
}
}
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/BatchProcessorConfig.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/BatchProcessorConfig.cs
new file mode 100644
index 0000000000..de31d367fb
--- /dev/null
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/BatchProcessorConfig.cs
@@ -0,0 +1,56 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using System.Diagnostics;
+using Vendors.YamlDotNet.Serialization;
+
+namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+
+internal class BatchProcessorConfig
+{
+ ///
+ /// Gets or sets the delay interval (in milliseconds) between two consecutive exports.
+ /// Value must be non-negative.
+ /// If omitted or null, 5000 is used.
+ ///
+ [YamlMember(Alias = "schedule_delay")]
+ public int ScheduleDelay { get; set; } = 5000;
+
+ ///
+ /// Gets or sets the maximum allowed time (in milliseconds) to export data.
+ /// Value must be non-negative. A value of 0 indicates no limit (infinity).
+ /// If omitted or null, 30000 is used.
+ ///
+ [YamlMember(Alias = "export_timeout")]
+ public int ExportTimeout { get; set; } = 30000;
+
+ ///
+ /// Gets or sets the maximum queue size.
+ /// Value must be positive.
+ /// If omitted or null, 2048 is used.
+ ///
+ [YamlMember(Alias = "max_queue_size")]
+ public int MaxQueueSize { get; set; } = 2048;
+
+ ///
+ /// Gets or sets the maximum batch size.
+ /// Value must be positive.
+ /// If omitted or null, 512 is used.
+ ///
+ [YamlMember(Alias = "max_export_batch_size")]
+ public int MaxExportBatchSize { get; set; } = 512;
+
+ ///
+ /// Gets or sets the exporters.
+ ///
+ [YamlMember(Alias = "exporter")]
+ public BatchTracerExporterConfig? Exporter { get; set; }
+
+ public void CopyTo(BatchExportProcessorOptions options)
+ {
+ options.ScheduledDelayMilliseconds = ScheduleDelay;
+ options.ExporterTimeoutMilliseconds = ExportTimeout;
+ options.MaxQueueSize = MaxQueueSize;
+ options.MaxExportBatchSize = MaxExportBatchSize;
+ }
+}
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/BatchTracerExporterConfig.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/BatchTracerExporterConfig.cs
new file mode 100644
index 0000000000..86235ed440
--- /dev/null
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/BatchTracerExporterConfig.cs
@@ -0,0 +1,27 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using Vendors.YamlDotNet.Serialization;
+
+namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+
+internal class BatchTracerExporterConfig
+{
+ ///
+ /// Gets or sets the OTLP HTTP exporter configuration.
+ ///
+ [YamlMember(Alias = "otlp_http")]
+ public OtlpHttpExporterConfig? OtlpHttp { get; set; }
+
+ ///
+ /// Gets or sets the OTLP gRPC exporter configuration.
+ ///
+ [YamlMember(Alias = "otlp_grpc")]
+ public OtlpGrpcExporterConfig? OtlpGrpc { get; set; }
+
+ ///
+ /// Gets or sets the Zipkin exporter configuration.
+ ///
+ [YamlMember(Alias = "zipkin")]
+ public ZipkinExporterConfig? Zipkin { get; set; }
+}
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/Header.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/Header.cs
new file mode 100644
index 0000000000..fcb10a6686
--- /dev/null
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/Header.cs
@@ -0,0 +1,21 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using Vendors.YamlDotNet.Serialization;
+
+namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+
+internal class Header
+{
+ ///
+ /// Gets or sets the name of the header.
+ ///
+ [YamlMember(Alias = "name")]
+ public string? Name { get; set; }
+
+ ///
+ /// Gets or sets the value of the header.
+ ///
+ [YamlMember(Alias = "value")]
+ public string? Value { get; set; }
+}
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/OtlpGrpcExporterConfig.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/OtlpGrpcExporterConfig.cs
new file mode 100644
index 0000000000..fde622939f
--- /dev/null
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/OtlpGrpcExporterConfig.cs
@@ -0,0 +1,42 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using Vendors.YamlDotNet.Serialization;
+
+namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+
+internal class OtlpGrpcExporterConfig
+{
+ ///
+ /// Gets or sets the endpoint for the OTLP gRPC exporter.
+ /// Configure endpoint.
+ /// If omitted or null, http://localhost:4317 is used.
+ ///
+ [YamlMember(Alias = "endpoint")]
+ public string Endpoint { get; set; } = "http://localhost:4317";
+
+ ///
+ /// Gets or sets the headers for the exporter.
+ /// Configure headers. Entries have higher priority than entries from headers_list.
+ /// If an entry's value is null, the entry is ignored.
+ ///
+ [YamlMember(Alias = "headers")]
+ public List? Headers { get; set; }
+
+ ///
+ /// Gets or sets the headers list for the exporter.
+ /// Configure headers. Entries have lower priority than entries from headers.
+ /// The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS.
+ /// If omitted or null, no headers are added.
+ ///
+ [YamlMember(Alias = "headers_list")]
+ public string? HeadersList { get; set; }
+
+ ///
+ /// Gets or sets the maximum time (in milliseconds) to wait for each export.
+ /// Value must be non-negative. A value of 0 indicates no limit (infinity).
+ /// If omitted or null, 10000 is used.
+ ///
+ [YamlMember(Alias = "timeout")]
+ public int? Timeout { get; set; } = 10000;
+}
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/OtlpHttpExporterConfig.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/OtlpHttpExporterConfig.cs
new file mode 100644
index 0000000000..1e6ada71b2
--- /dev/null
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/OtlpHttpExporterConfig.cs
@@ -0,0 +1,42 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using Vendors.YamlDotNet.Serialization;
+
+namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+
+internal class OtlpHttpExporterConfig
+{
+ ///
+ /// Gets or sets the endpoint for the OTLP HTTP exporter.
+ /// Configure endpoint.
+ /// If omitted or null, http://localhost:4318/v1/signal will be is used.
+ ///
+ [YamlMember(Alias = "endpoint")]
+ public string? Endpoint { get; set; }
+
+ ///
+ /// Gets or sets the headers for the exporter.
+ /// Configure headers. Entries have higher priority than entries from headers_list.
+ /// If an entry's value is null, the entry is ignored.
+ ///
+ [YamlMember(Alias = "headers")]
+ public List? Headers { get; set; }
+
+ ///
+ /// Gets or sets the headers list for the exporter.
+ /// Configure headers. Entries have lower priority than entries from headers.
+ /// The value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS.
+ /// If omitted or null, no headers are added.
+ ///
+ [YamlMember(Alias = "headers_list")]
+ public string? HeadersList { get; set; }
+
+ ///
+ /// Gets or sets the maximum time (in milliseconds) to wait for each export.
+ /// Value must be non-negative. A value of 0 indicates no limit (infinity).
+ /// If omitted or null, 10000 is used.
+ ///
+ [YamlMember(Alias = "timeout")]
+ public int? Timeout { get; set; } = 10000;
+}
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/ProcessorConfig.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/ProcessorConfig.cs
new file mode 100644
index 0000000000..3ee9cd858c
--- /dev/null
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/ProcessorConfig.cs
@@ -0,0 +1,15 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using Vendors.YamlDotNet.Serialization;
+
+namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+
+internal class ProcessorConfig
+{
+ [YamlMember(Alias = "batch")]
+ public BatchProcessorConfig? Batch { get; set; }
+
+ [YamlMember(Alias = "simple")]
+ public SimpleProcessorConfig? Simple { get; set; }
+}
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/SimpleProcessorConfig.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/SimpleProcessorConfig.cs
new file mode 100644
index 0000000000..c73b238508
--- /dev/null
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/SimpleProcessorConfig.cs
@@ -0,0 +1,12 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using Vendors.YamlDotNet.Serialization;
+
+namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+
+internal class SimpleProcessorConfig
+{
+ [YamlMember(Alias = "exporter")]
+ public SimpleTracerExporterConfig? Exporter { get; set; }
+}
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/SimpleTracerExporterConfig.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/SimpleTracerExporterConfig.cs
new file mode 100644
index 0000000000..6c25677238
--- /dev/null
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/SimpleTracerExporterConfig.cs
@@ -0,0 +1,33 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using Vendors.YamlDotNet.Serialization;
+
+namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+
+internal class SimpleTracerExporterConfig
+{
+ ///
+ /// Gets or sets the OTLP HTTP exporter configuration.
+ ///
+ [YamlMember(Alias = "otlp_http")]
+ public OtlpHttpExporterConfig? OtlpHttp { get; set; }
+
+ ///
+ /// Gets or sets the OTLP gRPC exporter configuration.
+ ///
+ [YamlMember(Alias = "otlp_grpc")]
+ public OtlpGrpcExporterConfig? OtlpGrpc { get; set; }
+
+ ///
+ /// Gets or sets the Zipkin exporter configuration.
+ ///
+ [YamlMember(Alias = "zipkin")]
+ public ZipkinExporterConfig? Zipkin { get; set; }
+
+ ///
+ /// Gets or sets the console exporter configuration.
+ ///
+ [YamlMember(Alias = "console")]
+ public object? Console { get; set; }
+}
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/TracerProviderConfiguration.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/TracerProviderConfiguration.cs
new file mode 100644
index 0000000000..1d52312968
--- /dev/null
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/TracerProviderConfiguration.cs
@@ -0,0 +1,12 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using Vendors.YamlDotNet.Serialization;
+
+namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+
+internal class TracerProviderConfiguration
+{
+ [YamlMember(Alias = "processors")]
+ public List Processors { get; set; } = new();
+}
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/YamlConfiguration.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/YamlConfiguration.cs
index 2d072bd787..11502f813a 100644
--- a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/YamlConfiguration.cs
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/YamlConfiguration.cs
@@ -23,6 +23,14 @@ internal class YamlConfiguration
[YamlMember(Alias = "resource")]
public ResourceConfiguration? Resource { get; set; }
+ ///
+ /// Gets or sets the tracer provider configuration.
+ /// Configure tracer provider.
+ /// If omitted, a noop tracer provider is used.
+ ///
+ [YamlMember(Alias = "tracer_provider")]
+ public TracerProviderConfiguration? TracerProvider { get; set; }
+
///
/// Gets or sets the text map context propagator configuration.
/// If omitted, a noop propagator is used.
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/ZipkinExporterConfig.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/ZipkinExporterConfig.cs
new file mode 100644
index 0000000000..bf53cce689
--- /dev/null
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/FileBasedConfiguration/ZipkinExporterConfig.cs
@@ -0,0 +1,22 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using OpenTelemetry.Exporter;
+using Vendors.YamlDotNet.Serialization;
+
+namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+
+internal class ZipkinExporterConfig
+{
+ ///
+ /// Gets or sets the Zipkin endpoint URL to which spans are exported.
+ /// If omitted or null, the default value "http://localhost:9411/api/v2/spans" is used.
+ ///
+ [YamlMember(Alias = "endpoint")]
+ public string Endpoint { get; set; } = "http://localhost:9411/api/v2/spans";
+
+ public void CopyTo(ZipkinExporterOptions options)
+ {
+ options.Endpoint = new Uri(Endpoint);
+ }
+}
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/Otlp/OtlpSettings.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/Otlp/OtlpSettings.cs
index 366ad01c8d..9d5be2854a 100644
--- a/src/OpenTelemetry.AutoInstrumentation/Configurations/Otlp/OtlpSettings.cs
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/Otlp/OtlpSettings.cs
@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
+using OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
using OpenTelemetry.Exporter;
namespace OpenTelemetry.AutoInstrumentation.Configurations.Otlp;
@@ -25,6 +26,30 @@ public OtlpSettings(OtlpSignalType signalType, Configuration configuration)
Endpoint = configuration.GetUri(priorityVar);
}
+ public OtlpSettings(OtlpSignalType signalType, OtlpHttpExporterConfig configuration)
+ {
+ Protocol = OtlpExportProtocol.HttpProtobuf;
+
+ Headers = CombineHeaders(configuration.Headers, configuration.HeadersList);
+
+ TimeoutMilliseconds = configuration.Timeout;
+
+ Endpoint = GetOtlpHttpEndpoint(configuration.Endpoint, signalType);
+ }
+
+ public OtlpSettings(OtlpGrpcExporterConfig configuration)
+ {
+#pragma warning disable CS0618 // OtlpExportProtocol.Grpc is obsolete
+ Protocol = OtlpExportProtocol.Grpc;
+#pragma warning restore CS0618 // OtlpExportProtocol.Grpc is obsolete
+
+ Headers = CombineHeaders(configuration.Headers, configuration.HeadersList);
+
+ TimeoutMilliseconds = configuration.Timeout;
+
+ Endpoint = new Uri(configuration.Endpoint);
+ }
+
///
/// Gets the OTLP transport protocol. Supported values: Grpc and HttpProtobuf.
///
@@ -70,6 +95,65 @@ public void CopyTo(OtlpExporterOptions options)
}
}
+ private static Uri GetOtlpHttpEndpoint(string? endpoint, OtlpSignalType signalType)
+ {
+ if (string.IsNullOrWhiteSpace(endpoint))
+ {
+ endpoint = signalType switch
+ {
+ OtlpSignalType.Logs => "http://localhost:4318/v1/logs",
+ OtlpSignalType.Metrics => "http://localhost:4318/v1/metrics",
+ OtlpSignalType.Traces => "http://localhost:4318/v1/traces",
+ _ => throw new ArgumentOutOfRangeException(nameof(signalType), "Unknown signal type")
+ };
+ }
+
+ if (!Uri.TryCreate(endpoint, UriKind.Absolute, out var uri))
+ {
+ throw new ArgumentException($"Invalid endpoint URI: {endpoint}", nameof(endpoint));
+ }
+
+ return uri;
+ }
+
+ private static string? CombineHeaders(List? headers, string? headersList)
+ {
+ var headerDict = new Dictionary(StringComparer.OrdinalIgnoreCase);
+
+ if (!string.IsNullOrWhiteSpace(headersList))
+ {
+ var pairs = headersList!.Split([','], StringSplitOptions.RemoveEmptyEntries);
+ foreach (var pair in pairs)
+ {
+ var parts = pair.Split('=');
+ if (parts.Length == 2)
+ {
+ var key = parts[0];
+ var value = parts[1];
+ if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
+ {
+ headerDict[key] = value;
+ }
+ }
+ }
+ }
+
+ if (headers != null)
+ {
+ foreach (var header in headers)
+ {
+ if (!string.IsNullOrWhiteSpace(header?.Name) && !string.IsNullOrWhiteSpace(header?.Value))
+ {
+ headerDict[header!.Name!] = header!.Value!;
+ }
+ }
+ }
+
+ return headerDict.Count == 0
+ ? null
+ : string.Join(",", headerDict.Select(kvp => $"{kvp.Key}={kvp.Value}"));
+ }
+
private static OtlpExportProtocol? GetExporterOtlpProtocol(OtlpSignalType signalType, Configuration configuration)
{
// the default in SDK is grpc. http/protobuf should be default for our purposes
diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/TracerSettings.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/TracerSettings.cs
index 78732e0da8..bb3d6b01bf 100644
--- a/src/OpenTelemetry.AutoInstrumentation/Configurations/TracerSettings.cs
+++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/TracerSettings.cs
@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
+using OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
using OpenTelemetry.AutoInstrumentation.Configurations.Otlp;
using OpenTelemetry.AutoInstrumentation.Logging;
@@ -25,23 +26,25 @@ internal class TracerSettings : Settings
///
/// Gets the list of enabled traces exporters.
+ /// For File based configuration, this must be empty,
+ /// and the configuration will be handled by Processors.
///
- public IReadOnlyList TracesExporters { get; private set; } = new List();
+ public IReadOnlyList TracesExporters { get; private set; } = [];
///
/// Gets the list of enabled instrumentations.
///
- public IReadOnlyList EnabledInstrumentations { get; private set; } = new List();
+ public IReadOnlyList EnabledInstrumentations { get; private set; } = [];
///
/// Gets the list of activity configurations to be added to the tracer at the startup.
///
- public IList ActivitySources { get; } = new List { "OpenTelemetry.AutoInstrumentation.*" };
+ public IList ActivitySources { get; } = ["OpenTelemetry.AutoInstrumentation.*"];
///
/// Gets the list of legacy configurations to be added to the tracer at the startup.
///
- public IList AdditionalLegacySources { get; } = new List();
+ public IList AdditionalLegacySources { get; } = [];
///
/// Gets the instrumentation options.
@@ -53,6 +56,13 @@ internal class TracerSettings : Settings
///
public OtlpSettings? OtlpSettings { get; private set; }
+ ///
+ /// Gets tracing OTLP Settings.
+ /// For environment variable configuration, this must be null,
+ /// and the configuration will be handled by TracesExporters
+ ///
+ public IReadOnlyList? Processors { get; private set; } = null;
+
protected override void OnLoadEnvVar(Configuration configuration)
{
TracesExporters = ParseTracesExporter(configuration);
@@ -93,7 +103,18 @@ protected override void OnLoadEnvVar(Configuration configuration)
InstrumentationOptions = new InstrumentationOptions(configuration);
}
- private static IReadOnlyList ParseTracesExporter(Configuration configuration)
+ protected override void OnLoadFile(YamlConfiguration configuration)
+ {
+ var processors = configuration.TracerProvider?.Processors;
+ if (processors != null && processors.Count > 0)
+ {
+ TracesEnabled = true;
+ }
+
+ Processors = processors;
+ }
+
+ private static List ParseTracesExporter(Configuration configuration)
{
var tracesExporterEnvVar = configuration.GetString(ConfigurationKeys.Traces.Exporter);
var exporters = new List();
diff --git a/test/IntegrationTests/Helpers/TestHelper.cs b/test/IntegrationTests/Helpers/TestHelper.cs
index e986e8ad81..72cf64c9c4 100644
--- a/test/IntegrationTests/Helpers/TestHelper.cs
+++ b/test/IntegrationTests/Helpers/TestHelper.cs
@@ -59,6 +59,12 @@ public void SetExporter(MockSpansCollector collector)
SetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT", $"http://localhost:{collector.Port}");
}
+ public void SetFileBasedExporter(MockSpansCollector collector)
+ {
+ SetEnvironmentVariable("OTEL_TRACES_EXPORTER", "otlp");
+ SetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT", $"http://localhost:{collector.Port}/v1/traces");
+ }
+
public void SetExporter(MockMetricsCollector collector)
{
SetEnvironmentVariable("OTEL_METRICS_EXPORTER", "otlp");
diff --git a/test/IntegrationTests/NoCodeTests.cs b/test/IntegrationTests/NoCodeTests.cs
index 8dfd03f9e7..2f6a60f343 100644
--- a/test/IntegrationTests/NoCodeTests.cs
+++ b/test/IntegrationTests/NoCodeTests.cs
@@ -22,7 +22,7 @@ public void SubmitsTraces()
EnableBytecodeInstrumentation();
EnableFileBasedConfigWithDefaultPath();
using var collector = new MockSpansCollector(Output);
- SetExporter(collector);
+ SetFileBasedExporter(collector);
List allTypeOfAttributes = [
new() { Key = "attribute_key_string", Value = new AnyValue { StringValue = "string_value" } },
diff --git a/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/FilebasedTracesSettingsTests.cs b/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/FilebasedTracesSettingsTests.cs
new file mode 100644
index 0000000000..d3adca198d
--- /dev/null
+++ b/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/FilebasedTracesSettingsTests.cs
@@ -0,0 +1,361 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using OpenTelemetry.AutoInstrumentation.Configurations;
+using OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
+using Xunit;
+
+namespace OpenTelemetry.AutoInstrumentation.Tests.Configurations.FileBased;
+
+public class FilebasedTracesSettingsTests
+{
+ public static TheoryData LoadMethod_SkipWrongExporterConfiguration_Data()
+ {
+ return
+ [
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors = []
+ }
+ }),
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors = [new ProcessorConfig()]
+ }
+ }),
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Batch = new BatchProcessorConfig(),
+ Simple = new SimpleProcessorConfig()
+ }
+ ]
+ }
+ }),
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Batch = new BatchProcessorConfig
+ {
+ Exporter = new BatchTracerExporterConfig
+ {
+ OtlpHttp = new OtlpHttpExporterConfig(),
+ OtlpGrpc = new OtlpGrpcExporterConfig(),
+ }
+ },
+ }
+ ]
+ }
+ }),
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Batch = new BatchProcessorConfig
+ {
+ Exporter = new BatchTracerExporterConfig
+ {
+ OtlpHttp = new OtlpHttpExporterConfig(),
+ Zipkin = new ZipkinExporterConfig()
+ }
+ },
+ }
+ ]
+ }
+ }),
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Batch = new BatchProcessorConfig
+ {
+ Exporter = new BatchTracerExporterConfig
+ {
+ OtlpGrpc = new OtlpGrpcExporterConfig(),
+ Zipkin = new ZipkinExporterConfig()
+ }
+ },
+ }
+ ]
+ }
+ }),
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Simple = new SimpleProcessorConfig
+ {
+ Exporter = new SimpleTracerExporterConfig
+ {
+ OtlpHttp = new OtlpHttpExporterConfig(),
+ OtlpGrpc = new OtlpGrpcExporterConfig()
+ }
+ },
+ }
+ ]
+ }
+ }),
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Simple = new SimpleProcessorConfig
+ {
+ Exporter = new SimpleTracerExporterConfig
+ {
+ OtlpHttp = new OtlpHttpExporterConfig(),
+ Zipkin = new ZipkinExporterConfig()
+ }
+ },
+ }
+ ]
+ }
+ }),
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Simple = new SimpleProcessorConfig
+ {
+ Exporter = new SimpleTracerExporterConfig
+ {
+ OtlpHttp = new OtlpHttpExporterConfig(),
+ Console = new object()
+ }
+ },
+ }
+ ]
+ }
+ }),
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Simple = new SimpleProcessorConfig
+ {
+ Exporter = new SimpleTracerExporterConfig
+ {
+ OtlpGrpc = new OtlpGrpcExporterConfig(),
+ Zipkin = new ZipkinExporterConfig()
+ }
+ },
+ }
+ ]
+ }
+ }),
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Simple = new SimpleProcessorConfig
+ {
+ Exporter = new SimpleTracerExporterConfig
+ {
+ OtlpGrpc = new OtlpGrpcExporterConfig(),
+ Console = new object()
+ }
+ },
+ }
+ ]
+ }
+ }),
+ new(new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Simple = new SimpleProcessorConfig
+ {
+ Exporter = new SimpleTracerExporterConfig
+ {
+ Zipkin = new ZipkinExporterConfig(),
+ Console = new object()
+ }
+ },
+ }
+ ]
+ }
+ }),
+ ];
+ }
+
+ [Fact]
+ public void LoadFile_SetsBatchProcessorAndExportersCorrectly()
+ {
+ var exporter1 = new BatchTracerExporterConfig
+ {
+ OtlpGrpc = new OtlpGrpcExporterConfig
+ {
+ Endpoint = "http://localhost:4317/"
+ }
+ };
+
+ var exporter2 = new BatchTracerExporterConfig
+ {
+ Zipkin = new ZipkinExporterConfig
+ {
+ Endpoint = "http://localhost:9411/"
+ }
+ };
+
+ var batchProcessorConfig1 = new BatchProcessorConfig
+ {
+ ScheduleDelay = 1000,
+ ExportTimeout = 30000,
+ MaxQueueSize = 2048,
+ MaxExportBatchSize = 512,
+ Exporter = exporter1
+ };
+
+ var batchProcessorConfig2 = new BatchProcessorConfig
+ {
+ Exporter = exporter2
+ };
+
+ var conf = new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Batch = batchProcessorConfig1
+ },
+ new ProcessorConfig
+ {
+ Batch = batchProcessorConfig2
+ }
+ ]
+ }
+ };
+
+ var settings = new TracerSettings();
+
+ settings.LoadFile(conf);
+
+ Assert.True(settings.TracesEnabled);
+ Assert.NotNull(settings.Processors);
+ Assert.Equal(2, settings.Processors.Count);
+
+ Assert.Empty(settings.TracesExporters);
+ }
+
+ [Fact]
+ public void LoadFile_DisablesTraces_WhenNoBatchProcessorConfigured()
+ {
+ var conf = new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors = []
+ }
+ };
+
+ var settings = new TracerSettings();
+
+ settings.LoadFile(conf);
+
+ Assert.False(settings.TracesEnabled);
+ Assert.Empty(settings.TracesExporters);
+ Assert.Null(settings.OtlpSettings);
+ Assert.NotNull(settings.Processors);
+ Assert.Empty(settings.Processors);
+ }
+
+ [Fact]
+ public void LoadFile_HandlesNullExporterGracefully()
+ {
+ var batchProcessorConfig = new BatchProcessorConfig
+ {
+ Exporter = null
+ };
+
+ var conf = new YamlConfiguration
+ {
+ TracerProvider = new TracerProviderConfiguration
+ {
+ Processors =
+ [
+ new ProcessorConfig
+ {
+ Batch = batchProcessorConfig
+ }
+ ]
+ }
+ };
+
+ var settings = new TracerSettings();
+
+ settings.LoadFile(conf);
+
+ Assert.True(settings.TracesEnabled);
+ Assert.Empty(settings.TracesExporters);
+ }
+
+ [Theory]
+ [MemberData(nameof(LoadMethod_SkipWrongExporterConfiguration_Data))]
+ public void LoadMethod_SkipWrongExporterConfiguration(SkipConfigurationTestCase skipConfigurationTestCase)
+ {
+ var settings = new TracerSettings();
+
+ settings.LoadFile(skipConfigurationTestCase.Configuration);
+
+ Assert.Empty(settings.TracesExporters);
+ }
+
+ public class SkipConfigurationTestCase
+ {
+ internal SkipConfigurationTestCase(YamlConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ internal YamlConfiguration Configuration { get; }
+ }
+}
diff --git a/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/Files/TestTracesFile.yaml b/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/Files/TestTracesFile.yaml
new file mode 100644
index 0000000000..514737454e
--- /dev/null
+++ b/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/Files/TestTracesFile.yaml
@@ -0,0 +1,26 @@
+tracer_provider:
+ processors:
+ - batch:
+ schedule_delay: 5000
+ export_timeout: 30000
+ max_queue_size: 2048
+ max_export_batch_size: 512
+ exporter:
+ otlp_http:
+ endpoint: http://localhost:4318/v1/traces
+ timeout: 10000
+ headers:
+ - name: header1234
+ value: "1234"
+ - batch:
+ exporter:
+ zipkin:
+ endpoint: http://localhost:9411/zipkin
+
+ - batch:
+ exporter:
+ otlp_grpc:
+ endpoint: http://localhost:4317
+ - simple:
+ exporter:
+ console:
diff --git a/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/Files/TestTracesFileEnvVars.yaml b/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/Files/TestTracesFileEnvVars.yaml
new file mode 100644
index 0000000000..9b9e7433b6
--- /dev/null
+++ b/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/Files/TestTracesFileEnvVars.yaml
@@ -0,0 +1,12 @@
+tracer_provider:
+ processors:
+ - batch:
+ schedule_delay: ${OTEL_BSP_SCHEDULE_DELAY}
+ export_timeout: ${OTEL_BSP_EXPORT_TIMEOUT}
+ max_queue_size: ${OTEL_BSP_MAX_QUEUE_SIZE}
+ max_export_batch_size: ${OTEL_BSP_MAX_EXPORT_BATCH_SIZE}
+ exporter:
+ otlp_http:
+ endpoint: ${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT}
+ timeout: ${OTEL_EXPORTER_OTLP_TRACES_TIMEOUT}
+ headers_list: ${OTEL_EXPORTER_OTLP_TRACES_HEADERS}
\ No newline at end of file
diff --git a/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/Parser/ParserTracesTests.cs b/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/Parser/ParserTracesTests.cs
new file mode 100644
index 0000000000..48eeb664e3
--- /dev/null
+++ b/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/FileBased/Parser/ParserTracesTests.cs
@@ -0,0 +1,98 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using Xunit;
+using YamlParser = OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration.Parser.Parser;
+
+namespace OpenTelemetry.AutoInstrumentation.Tests.Configurations.FileBased.Parser;
+
+[Collection("Non-Parallel Collection")]
+public class ParserTracesTests
+{
+ [Fact]
+ public void Parse_FullConfigYaml_ShouldPopulateModelCorrectly()
+ {
+ var config = YamlParser.ParseYaml("Configurations/FileBased/Files/TestTracesFile.yaml");
+ Assert.NotNull(config);
+
+ Assert.NotNull(config.TracerProvider);
+ Assert.NotNull(config.TracerProvider.Processors);
+ Assert.Equal(4, config.TracerProvider.Processors.Count);
+
+ var traceBatch = config.TracerProvider.Processors[0].Batch;
+ Assert.NotNull(traceBatch);
+
+ Assert.Equal(5000, traceBatch.ScheduleDelay);
+ Assert.Equal(30000, traceBatch.ExportTimeout);
+ Assert.Equal(2048, traceBatch.MaxQueueSize);
+ Assert.Equal(512, traceBatch.MaxExportBatchSize);
+
+ Assert.NotNull(traceBatch.Exporter);
+ var traceExporter = traceBatch.Exporter.OtlpHttp;
+ Assert.NotNull(traceExporter);
+
+ Assert.Equal("http://localhost:4318/v1/traces", traceExporter.Endpoint);
+ Assert.Equal(10000, traceExporter.Timeout);
+
+ Assert.NotNull(traceExporter.Headers);
+ Assert.Single(traceExporter.Headers);
+ Assert.Equal("header1234", traceExporter.Headers[0].Name);
+ Assert.Equal("1234", traceExporter.Headers[0].Value);
+
+ var zipkinBatch = config.TracerProvider.Processors[1].Batch;
+ Assert.NotNull(zipkinBatch);
+ Assert.NotNull(zipkinBatch.Exporter);
+ var zipkinExporter = zipkinBatch.Exporter.Zipkin;
+ Assert.NotNull(zipkinExporter);
+ Assert.Equal("http://localhost:9411/zipkin", zipkinExporter.Endpoint);
+
+ var grpcBatch = config.TracerProvider.Processors[2].Batch;
+ Assert.NotNull(grpcBatch);
+ Assert.NotNull(grpcBatch.Exporter);
+ var grpcExporter = grpcBatch.Exporter.OtlpGrpc;
+ Assert.NotNull(grpcExporter);
+ Assert.Equal("http://localhost:4317", grpcExporter.Endpoint);
+
+ var simpleProcessor = config.TracerProvider.Processors[3].Simple;
+ Assert.NotNull(simpleProcessor);
+ Assert.NotNull(simpleProcessor.Exporter);
+ Assert.NotNull(simpleProcessor.Exporter.Console);
+ }
+
+ [Fact]
+ public void Parse_EnvVarYaml_ShouldPopulateModelCompletely()
+ {
+ Environment.SetEnvironmentVariable("OTEL_SDK_DISABLED", "true");
+ Environment.SetEnvironmentVariable("OTEL_BSP_SCHEDULE_DELAY", "7000");
+ Environment.SetEnvironmentVariable("OTEL_BSP_EXPORT_TIMEOUT", "35000");
+ Environment.SetEnvironmentVariable("OTEL_BSP_MAX_QUEUE_SIZE", "4096");
+ Environment.SetEnvironmentVariable("OTEL_BSP_MAX_EXPORT_BATCH_SIZE", "1024");
+ Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", "http://collector:4318/v1/traces");
+ Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_TRACES_TIMEOUT", "15000");
+ Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_TRACES_HEADERS", "header1=value1,header2=value2");
+
+ var config = YamlParser.ParseYaml("Configurations/FileBased/Files/TestTracesFileEnvVars.yaml");
+ Assert.NotNull(config);
+
+ Assert.NotNull(config.TracerProvider);
+ Assert.NotNull(config.TracerProvider.Processors);
+ var traceBatch = config.TracerProvider.Processors[0].Batch;
+ Assert.NotNull(traceBatch);
+
+ Assert.NotNull(traceBatch.Exporter);
+ Assert.NotNull(traceBatch.Exporter.OtlpHttp);
+ var traceExporter = traceBatch.Exporter.OtlpHttp;
+ Assert.NotNull(traceExporter);
+
+ Assert.Equal(7000, traceBatch.ScheduleDelay);
+ Assert.Equal(35000, traceBatch.ExportTimeout);
+ Assert.Equal(4096, traceBatch.MaxQueueSize);
+ Assert.Equal(1024, traceBatch.MaxExportBatchSize);
+
+ Assert.Equal("http://collector:4318/v1/traces", traceExporter.Endpoint);
+ Assert.Equal(15000, traceBatch.Exporter.OtlpHttp.Timeout);
+ Assert.Null(traceExporter.Headers);
+ Assert.NotNull(traceExporter.HeadersList);
+ Assert.Equal("header1=value1,header2=value2", traceExporter.HeadersList);
+ }
+}
diff --git a/test/OpenTelemetry.AutoInstrumentation.Tests/OpenTelemetry.AutoInstrumentation.Tests.csproj b/test/OpenTelemetry.AutoInstrumentation.Tests/OpenTelemetry.AutoInstrumentation.Tests.csproj
index 73965ceaf8..1bd11da871 100644
--- a/test/OpenTelemetry.AutoInstrumentation.Tests/OpenTelemetry.AutoInstrumentation.Tests.csproj
+++ b/test/OpenTelemetry.AutoInstrumentation.Tests/OpenTelemetry.AutoInstrumentation.Tests.csproj
@@ -12,6 +12,9 @@
+
+ PreserveNewest
+
PreserveNewest
@@ -24,6 +27,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/test/test-applications/integrations/TestApplication.NoCode/Properties/launchSettings.json b/test/test-applications/integrations/TestApplication.NoCode/Properties/launchSettings.json
index 02791064f8..a8acfea733 100644
--- a/test/test-applications/integrations/TestApplication.NoCode/Properties/launchSettings.json
+++ b/test/test-applications/integrations/TestApplication.NoCode/Properties/launchSettings.json
@@ -16,7 +16,8 @@
"DOTNET_STARTUP_HOOKS": "$(SolutionDir)bin\\tracer-home\\net\\OpenTelemetry.AutoInstrumentation.StartupHook.dll",
"OTEL_DOTNET_AUTO_HOME": "$(SolutionDir)bin\\tracer-home",
"OTEL_TRACES_EXPORTER": "otlp,console",
- "OTEL_LOG_LEVEL": "debug"
+ "OTEL_LOG_LEVEL": "debug",
+ "OTEL_EXPERIMENTAL_FILE_BASED_CONFIGURATION_ENABLED": "true"
}
}
}
diff --git a/test/test-applications/integrations/TestApplication.NoCode/config.yaml b/test/test-applications/integrations/TestApplication.NoCode/config.yaml
index 9e37a9b8aa..0a5c40d0a9 100644
--- a/test/test-applications/integrations/TestApplication.NoCode/config.yaml
+++ b/test/test-applications/integrations/TestApplication.NoCode/config.yaml
@@ -1,5 +1,12 @@
file_format: "1.0-rc.1"
+tracer_provider:
+ processors:
+ - batch:
+ exporter:
+ otlp_http:
+ endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT}
+
no_code/development:
targets:
- target: