|
6 | 6 | using System.Runtime.CompilerServices; |
7 | 7 | using System.Text; |
8 | 8 | using System.Text.RegularExpressions; |
9 | | -using Microsoft.Extensions.Configuration; |
10 | 9 | using Microsoft.Extensions.DependencyInjection; |
| 10 | +using Microsoft.Extensions.Options; |
11 | 11 | using OpenTelemetry.Internal; |
12 | 12 | using OpenTelemetry.Resources; |
13 | 13 |
|
14 | 14 | namespace OpenTelemetry.Trace; |
15 | 15 |
|
16 | 16 | internal sealed class TracerProviderSdk : TracerProvider |
17 | 17 | { |
18 | | - internal const string TracesSamplerConfigKey = "OTEL_TRACES_SAMPLER"; |
19 | | - internal const string TracesSamplerArgConfigKey = "OTEL_TRACES_SAMPLER_ARG"; |
20 | | - |
21 | 18 | internal readonly IServiceProvider ServiceProvider; |
22 | 19 | internal IDisposable? OwnedServiceProvider; |
23 | 20 | internal int ShutdownCount; |
@@ -59,7 +56,9 @@ internal TracerProviderSdk( |
59 | 56 | resourceBuilder.ServiceProvider = serviceProvider; |
60 | 57 | this.Resource = resourceBuilder.Build(); |
61 | 58 |
|
62 | | - this.Sampler = GetSampler(serviceProvider!.GetRequiredService<IConfiguration>(), state.Sampler); |
| 59 | + this.Sampler = GetSampler( |
| 60 | + serviceProvider!.GetRequiredService<IOptions<SamplerOptions>>().Value, |
| 61 | + state.Sampler); |
63 | 62 | OpenTelemetrySdkEventSource.Log.TracerProviderSdkEvent($"Sampler added = \"{this.Sampler.GetType()}\"."); |
64 | 63 |
|
65 | 64 | this.supportLegacyActivity = state.LegacyActivityOperationNames.Count > 0; |
@@ -386,77 +385,78 @@ protected override void Dispose(bool disposing) |
386 | 385 | base.Dispose(disposing); |
387 | 386 | } |
388 | 387 |
|
389 | | - private static Sampler GetSampler(IConfiguration configuration, Sampler? stateSampler) |
| 388 | + private static Sampler GetSampler(SamplerOptions options, Sampler? stateSampler) |
390 | 389 | { |
391 | 390 | var sampler = stateSampler; |
392 | 391 |
|
393 | | - if (configuration.TryGetStringValue(TracesSamplerConfigKey, out var configValue)) |
| 392 | + if (!string.IsNullOrWhiteSpace(options.SamplerType)) |
394 | 393 | { |
395 | 394 | if (sampler != null) |
396 | 395 | { |
397 | 396 | OpenTelemetrySdkEventSource.Log.TracerProviderSdkEvent( |
398 | | - $"Trace sampler configuration value '{configValue}' has been ignored because a value '{sampler.GetType().FullName}' was set programmatically."); |
| 397 | + $"Trace sampler configuration value '{options.SamplerType}' has been ignored because a value '{sampler.GetType().FullName}' was set programmatically."); |
399 | 398 | return sampler; |
400 | 399 | } |
401 | 400 |
|
402 | | - switch (configValue) |
| 401 | + switch (options.SamplerType) |
403 | 402 | { |
404 | | - case var _ when string.Equals(configValue, "always_on", StringComparison.OrdinalIgnoreCase): |
| 403 | + case var _ when string.Equals(options.SamplerType, "always_on", StringComparison.OrdinalIgnoreCase): |
405 | 404 | sampler = AlwaysOnSampler.Instance; |
406 | 405 | break; |
407 | | - case var _ when string.Equals(configValue, "always_off", StringComparison.OrdinalIgnoreCase): |
| 406 | + case var _ when string.Equals(options.SamplerType, "always_off", StringComparison.OrdinalIgnoreCase): |
408 | 407 | sampler = AlwaysOffSampler.Instance; |
409 | 408 | break; |
410 | | - case var _ when string.Equals(configValue, "traceidratio", StringComparison.OrdinalIgnoreCase): |
| 409 | + case var _ when string.Equals(options.SamplerType, "traceidratio", StringComparison.OrdinalIgnoreCase): |
411 | 410 | { |
412 | | - var traceIdRatio = ReadTraceIdRatio(configuration); |
| 411 | + var traceIdRatio = ReadTraceIdRatio(options); |
413 | 412 | sampler = new TraceIdRatioBasedSampler(traceIdRatio); |
414 | 413 | break; |
415 | 414 | } |
416 | 415 |
|
417 | | - case var _ when string.Equals(configValue, "parentbased_always_on", StringComparison.OrdinalIgnoreCase): |
| 416 | + case var _ when string.Equals(options.SamplerType, "parentbased_always_on", StringComparison.OrdinalIgnoreCase): |
418 | 417 | sampler = new ParentBasedSampler(AlwaysOnSampler.Instance); |
419 | 418 | break; |
420 | | - case var _ when string.Equals(configValue, "parentbased_always_off", StringComparison.OrdinalIgnoreCase): |
| 419 | + case var _ when string.Equals(options.SamplerType, "parentbased_always_off", StringComparison.OrdinalIgnoreCase): |
421 | 420 | sampler = new ParentBasedSampler(AlwaysOffSampler.Instance); |
422 | 421 | break; |
423 | | - case var _ when string.Equals(configValue, "parentbased_traceidratio", StringComparison.OrdinalIgnoreCase): |
424 | | - { |
425 | | - var traceIdRatio = ReadTraceIdRatio(configuration); |
426 | | - sampler = new ParentBasedSampler(new TraceIdRatioBasedSampler(traceIdRatio)); |
427 | | - break; |
428 | | - } |
429 | | - |
| 422 | + case var _ when string.Equals(options.SamplerType, "parentbased_traceidratio", StringComparison.OrdinalIgnoreCase): |
| 423 | + sampler = new ParentBasedSampler(new TraceIdRatioBasedSampler(ReadTraceIdRatio(options))); |
| 424 | + break; |
430 | 425 | default: |
431 | | - OpenTelemetrySdkEventSource.Log.TracesSamplerConfigInvalid(configValue); |
| 426 | + OpenTelemetrySdkEventSource.Log.TracesSamplerConfigInvalid(options.SamplerType!); |
432 | 427 | break; |
433 | 428 | } |
434 | 429 |
|
435 | 430 | if (sampler != null) |
436 | 431 | { |
437 | 432 | OpenTelemetrySdkEventSource.Log.TracerProviderSdkEvent($"Trace sampler set to '{sampler.GetType().FullName}' from configuration."); |
438 | 433 | } |
| 434 | + |
| 435 | + return sampler ?? new ParentBasedSampler(new AlwaysOnSampler()); |
439 | 436 | } |
440 | 437 |
|
441 | 438 | return sampler ?? new ParentBasedSampler(AlwaysOnSampler.Instance); |
442 | 439 | } |
443 | 440 |
|
444 | | - private static double ReadTraceIdRatio(IConfiguration configuration) |
| 441 | + private static double ReadTraceIdRatio(SamplerOptions options) |
445 | 442 | { |
446 | | - if (configuration.TryGetStringValue(TracesSamplerArgConfigKey, out var configValue) && |
447 | | - double.TryParse(configValue, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var traceIdRatio) && |
448 | | - !double.IsNaN(traceIdRatio) && |
449 | | - !double.IsInfinity(traceIdRatio) && |
450 | | - traceIdRatio >= 0.0 && |
451 | | - traceIdRatio <= 1.0) |
| 443 | + var samplerArg = options.SamplerArg; |
| 444 | + if (samplerArg.HasValue |
| 445 | + && !double.IsNaN(samplerArg.Value) |
| 446 | + && !double.IsInfinity(samplerArg.Value) |
| 447 | + && samplerArg.Value >= 0.0 |
| 448 | + && samplerArg.Value <= 1.0) |
452 | 449 | { |
453 | | - return traceIdRatio; |
454 | | - } |
455 | | - else |
456 | | - { |
457 | | - OpenTelemetrySdkEventSource.Log.TracesSamplerArgConfigInvalid(configValue ?? string.Empty); |
| 450 | + return samplerArg.Value; |
458 | 451 | } |
459 | 452 |
|
| 453 | + // No valid ratio. Log the original config string for diagnostic fidelity and fall back to 1.0. |
| 454 | + OpenTelemetrySdkEventSource.Log.TracesSamplerArgConfigInvalid( |
| 455 | + options.SamplerArgRaw |
| 456 | + ?? (samplerArg.HasValue |
| 457 | + ? samplerArg.Value.ToString(CultureInfo.InvariantCulture) |
| 458 | + : string.Empty)); |
| 459 | + |
460 | 460 | return 1.0; |
461 | 461 | } |
462 | 462 |
|
|
0 commit comments