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: