LCOV - code coverage report
Current view: top level - lib/src/trace/sampling - trace_id_ratio_sampler.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 19 19
Test Date: 2026-08-27 23:42:02 Functions: - 0 0

            Line data    Source code
       1              : // Copyright The OpenTelemetry Authors
       2              : // SPDX-License-Identifier: Apache-2.0
       3              : 
       4              : import 'dart:math' as math;
       5              : 
       6              : import '../../../dartastic_opentelemetry.dart';
       7              : 
       8              : /// A sampler that samples traces based on a probability defined by the ratio of
       9              : /// traces that should be sampled. The ratio must be in the range [0.0, 1.0].
      10              : ///
      11              : /// Uses the lowest 8 bytes of the trace ID to make a sampling decision.
      12              : class TraceIdRatioSampler implements Sampler {
      13              :   /// The sampling ratio, a value between 0.0 and 1.0 that determines
      14              :   /// the probability that a trace will be sampled.
      15              :   final double ratio;
      16              : 
      17            3 :   @override
      18            6 :   String get description => 'TraceIdRatioSampler{$ratio}';
      19              : 
      20              :   /// Creates a TraceIdRatioSampler with the given ratio.
      21              :   /// [ratio] must be in the range [0.0, 1.0].
      22            4 :   TraceIdRatioSampler(this.ratio) {
      23           16 :     if (ratio < 0.0 || ratio > 1.0) {
      24            1 :       throw ArgumentError('ratio must be in range [0.0, 1.0]');
      25              :     }
      26              :   }
      27              : 
      28              :   /// Converts a trace ID to a value between 0.0 and 1.0 for sampling decisions.
      29              :   /// Uses the lowest 8 bytes (16 hex characters) of the trace ID as per the specification.
      30              :   ///
      31              :   /// @param traceId The trace ID as a hex string
      32              :   /// @return A value between 0.0 and 1.0 based on the trace ID
      33            3 :   double _traceIdToValue(String traceId) {
      34              :     // Get the last 16 hex chars (8 bytes) of trace ID
      35           12 :     final lastBytes = traceId.substring(math.max(0, traceId.length - 16));
      36              : 
      37              :     // Parse hex string to integer with BigInt to avoid precision issues
      38            3 :     final value = BigInt.parse(lastBytes, radix: 16);
      39              : 
      40              :     // Maximum possible value for 8 bytes (64 bits) is 2^64 - 1
      41            3 :     final maxValue = BigInt.parse('ffffffffffffffff', radix: 16);
      42              : 
      43              :     // Convert to a double between 0.0 and 1.0
      44            9 :     return value.toDouble() / maxValue.toDouble();
      45              :   }
      46              : 
      47            4 :   @override
      48              :   SamplingResult shouldSample({
      49              :     required Context parentContext,
      50              :     required String traceId,
      51              :     required String name,
      52              :     required SpanKind spanKind,
      53              :     required Attributes? attributes,
      54              :     required List<SpanLink>? links,
      55              :   }) {
      56            5 :     final parentTraceState = parentContext.spanContext?.traceState;
      57              : 
      58              :     // If ratio is 0, never sample
      59            8 :     if (ratio == 0.0) {
      60            1 :       return SamplingResult(
      61              :         decision: SamplingDecision.drop,
      62              :         source: SamplingDecisionSource.tracerConfig,
      63              :         traceState: parentTraceState,
      64              :       );
      65              :     }
      66              : 
      67              :     // If ratio is 1, always sample
      68            8 :     if (ratio == 1.0) {
      69            2 :       return SamplingResult(
      70              :         decision: SamplingDecision.recordAndSample,
      71              :         source: SamplingDecisionSource.tracerConfig,
      72              :         traceState: parentTraceState,
      73              :       );
      74              :     }
      75              : 
      76              :     // Convert trace ID to a value between 0.0 and 1.0
      77            3 :     final value = _traceIdToValue(traceId);
      78              : 
      79              :     // If the value is less than our ratio, we should sample
      80            6 :     final shouldSample = value < ratio;
      81              : 
      82            3 :     return SamplingResult(
      83              :       decision: shouldSample
      84              :           ? SamplingDecision.recordAndSample
      85              :           : SamplingDecision.drop,
      86              :       source: SamplingDecisionSource.tracerConfig,
      87              :       traceState: parentTraceState,
      88              :     );
      89              :   }
      90              : }
        

Generated by: LCOV version 2.0-1