Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
bcedd1c
[File-Based] Add traces exporter configuration
ysolomchenko Sep 23, 2025
00dda04
[FileBased] Add traces Tests
ysolomchenko Sep 23, 2025
d6ec27a
[File-Based] Add Batch options
ysolomchenko Sep 29, 2025
a64259e
Merge branch 'main' into FileBasedConfiguration-Traces
ysolomchenko Sep 30, 2025
d35c375
[File-Based] Add Tracer Provider Docs
ysolomchenko Sep 30, 2025
bee1a0c
fix docs
ysolomchenko Sep 30, 2025
44bc7f1
Merge branch 'main' into FileBasedConfiguration-Traces
ysolomchenko Oct 13, 2025
afd0ece
Add note about multiple processor support
ysolomchenko Oct 13, 2025
6ad3fbc
fix no_code
ysolomchenko Oct 13, 2025
1e188bb
Merge branch 'main' into FileBasedConfiguration-Traces
Kielek Oct 14, 2025
56eb56c
remove redundant usings
Kielek Oct 14, 2025
89c9f2b
refactor tests
ysolomchenko Oct 14, 2025
90590b8
[File Based] accept multiple processors
ysolomchenko Oct 15, 2025
f24901e
update tests
ysolomchenko Oct 16, 2025
de5d74f
update docs
ysolomchenko Oct 16, 2025
ea0f538
Merge branch 'main' into FileBasedConfiguration-Traces
ysolomchenko Oct 16, 2025
28eb9cd
fix
ysolomchenko Oct 17, 2025
ba3800b
Merge branch 'FileBasedConfiguration-Traces' of https://github.com/ys…
ysolomchenko Oct 17, 2025
4820495
fix
ysolomchenko Oct 17, 2025
1416380
Merge branch 'main' into FileBasedConfiguration-Traces
ysolomchenko Oct 20, 2025
21b860a
fix var name
ysolomchenko Oct 20, 2025
5276b25
fix test
ysolomchenko Oct 20, 2025
0faa54f
Separate configuration for batch/simple processors
Kielek Oct 23, 2025
ff00c98
Validate configuration while configuring exporters
Kielek Oct 23, 2025
4b2b887
Merge branch 'main' into FileBasedConfiguration-Traces
Kielek Oct 23, 2025
3f1651d
Merge branch 'main' into FileBasedConfiguration-Traces
Kielek Oct 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions docs/file-based-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
// 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;

namespace OpenTelemetry.AutoInstrumentation.Configurations;

internal static class EnvironmentConfigurationTracerHelper
{
private static readonly IOtelLogger Logger = OtelLogging.GetLogger();

public static TracerProviderBuilder UseEnvironmentVariables(
this TracerProviderBuilder builder,
LazyInstrumentationLoader lazyInstrumentationLoader,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
});
}
}
}
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// Gets or sets the delay interval (in milliseconds) between two consecutive exports.
/// Value must be non-negative.
/// If omitted or null, 5000 is used.
/// </summary>
[YamlMember(Alias = "schedule_delay")]
public int ScheduleDelay { get; set; } = 5000;

/// <summary>
/// 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.
/// </summary>
[YamlMember(Alias = "export_timeout")]
public int ExportTimeout { get; set; } = 30000;

/// <summary>
/// Gets or sets the maximum queue size.
/// Value must be positive.
/// If omitted or null, 2048 is used.
/// </summary>
[YamlMember(Alias = "max_queue_size")]
public int MaxQueueSize { get; set; } = 2048;

/// <summary>
/// Gets or sets the maximum batch size.
/// Value must be positive.
/// If omitted or null, 512 is used.
/// </summary>
[YamlMember(Alias = "max_export_batch_size")]
public int MaxExportBatchSize { get; set; } = 512;

/// <summary>
/// Gets or sets the exporters.
/// </summary>
[YamlMember(Alias = "exporter")]
public BatchTracerExporterConfig? Exporter { get; set; }

public void CopyTo(BatchExportProcessorOptions<Activity> options)
{
options.ScheduledDelayMilliseconds = ScheduleDelay;
options.ExporterTimeoutMilliseconds = ExportTimeout;
options.MaxQueueSize = MaxQueueSize;
options.MaxExportBatchSize = MaxExportBatchSize;
}
}
Loading
Loading