@@ -34,15 +34,29 @@ public SpanId? ParentSpanId
3434
3535 public bool IsSampled => Activity . Current ? . Recorded ?? false ;
3636
37- // https://opentelemetry.io/docs/specs/otel/trace/tracestate-handling/#predefined-opentelemetry-sub-keys
38- public double ? SampleRate => GetOtelTraceStateValue ( "th" ) is { } th ? ParseOtelHexFraction ( th ) : null ;
37+ /// <summary>
38+ /// th is a rejection threshold: T = (1 - sampling_probability) * 2^56, so we invert to get the sample rate.
39+ /// </summary>
40+ public double ? SampleRate => GetOtelTraceStateValue ( "th" ) is { } th && ParseOtelHexFraction ( th ) is { } v ? 1.0 - v : null ;
3941
40- // https://opentelemetry.io/docs/specs/otel/trace/tracestate-handling/#predefined-opentelemetry-sub-keys
41- public double ? SampleRand => GetOtelTraceStateValue ( "rv" ) is { } rv ? ParseOtelHexFraction ( rv ) : null ;
42+ /// <summary>
43+ /// Parses the SampleRand from the rv (random value) OTEL equivalent from the TraceStateString
44+ /// </summary>
45+ public double ? SampleRand =>
46+ // OTel keeps a trace when rv ≥ th; Sentry keeps it when sample_rand < sample_rate.
47+ // Mapping sample_rand = 1 − rv makes the decisions equivalent: 1 − rv < 1 − th ↔ rv > th
48+ GetOtelTraceStateValue ( "rv" ) is { } rv && ParseOtelHexFraction ( rv ) is { } v ? 1.0 - v : null ;
4249
43- // Parses a sub-key value from the OTel vendor entry in the W3C tracestate string.
44- // The tracestate format is comma-separated vendor entries (e.g. "ot=th:8;rv:a0b1c2d3e4f5a0,other=x").
45- // The OTel entry uses semicolon-separated sub-keys with colon-delimited values (e.g. "th:8;rv:...").
50+ /// <summary>
51+ /// <para>
52+ /// Parses a sub-key value from the OTel vendor entry in the W3C tracestate string.
53+ /// The tracestate format is comma-separated vendor entries (e.g. "ot=th:8;rv:a0b1c2d3e4f5a0,other=x").
54+ /// The OTel entry uses semicolon-separated sub-keys with colon-delimited values (e.g. "th:8;rv:...").
55+ /// </para>
56+ /// <para>
57+ /// See https://opentelemetry.io/docs/specs/otel/trace/tracestate-handling/
58+ /// </para>
59+ /// </summary>
4660 private static string ? GetOtelTraceStateValue ( string subKey )
4761 {
4862 var traceState = Activity . Current ? . TraceStateString ;
@@ -68,8 +82,10 @@ public SpanId? ParentSpanId
6882 return null ;
6983 }
7084
71- // Converts an OTel 56-bit hex fraction to a double in [0, 1).
72- // The value is encoded as up to 14 lowercase hex digits with trailing zeros omitted, so "8" means 0.5.
85+ /// <summary>
86+ /// Converts an OTel 56-bit hex fraction to a double in [0, 1).
87+ /// The value is encoded as up to 14 lowercase hex digits with trailing zeros omitted, so "8" means 0.5.
88+ /// </summary>
7389 private static double ? ParseOtelHexFraction ( string hexValue )
7490 {
7591 if ( hexValue . Length == 0 || hexValue . Length > 14 )
0 commit comments