opentelemetry-sdk-experimental 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 810bad2b227d4e0345bab51445002ccae0dde9cc7a8651d05fc5c44c1bd7df6c
4
- data.tar.gz: 53dd2c762679bda44159ec4936ae8beb6052a536a618d52e793eb25f187b68fd
3
+ metadata.gz: 51a09141af347e88764533ef7ae7a072d1fe45935c61a04ffec0f92d535d90a7
4
+ data.tar.gz: 641bb04a0687ac7c67de416569270b394246f37bc9245435e53b954b93f0a4a4
5
5
  SHA512:
6
- metadata.gz: b48e7906d4250ff6cc7f01d32152e1c85ac0627993cba7171debb16514ef8b6a6af79d186098629cb66dbbf9c5b901f05c007144e2f7dcdc06b7b4b6f71a0c39
7
- data.tar.gz: 3a861705fa43bfd6150c6441c4e6487dd95857acf85f2d6a21dafd14b32e66ff18eb312d3aa1e13cde5f5b971359de304852f05d34e073e28b0a40824bae97b4
6
+ metadata.gz: b531cbb38ca9d102377250b501b4ed4309336bc49432c0f8fb8070795d9849406fcb93324563fed99e0e9e4fc0dce30f55d7abe65ac639f2ae7a0e0b128c37fb
7
+ data.tar.gz: f833b0e558897fe05ec52dbe79ecf0a73d45b4783ed46f992fc73f7b556a8fe56bb806964115a35b8bfc80fcfa4de7b6b95fc31ef142241f2a9c11c6766275ac
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Release History: opentelemetry-sdk-experimental
2
2
 
3
+ ### v0.2.0 / 2023-05-30
4
+
5
+ * FIXED: Consistent probability sampler init
6
+ * BREAKING CHANGE: Consistently pass tracestate
7
+ * BREAKING CHANGE: Set r in Parent CPS
8
+
9
+ ### v0.1.1 / 2023-03-06
10
+
11
+ * FIXED: Reduce allocations in update_tracestate
12
+ * FIXED: Refactor consistent prob sampler for reuse
13
+
3
14
  ### v0.1.0 / 2022-11-09
4
15
 
5
16
  * Initial release.
data/README.md ADDED
@@ -0,0 +1,8 @@
1
+ # Experimental SDK
2
+
3
+ The experimental SDK houses bleeding-edge(-ish) functionality that may have unstable APIs. Some examples of what's in
4
+ here:
5
+
6
+ * `traceresponse` propagator (in [w3c `trace-context` editor's draft](https://w3c.github.io/trace-context/))
7
+ * Consistent Probability Sampler (marked as `experimental` in [opentelemetry-specification)](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/tracestate-probability-sampling.md))
8
+
@@ -8,7 +8,7 @@ module OpenTelemetry
8
8
  module SDK
9
9
  module Experimental
10
10
  # Current OpenTelemetry experimental sdk version
11
- VERSION = '0.1.0'
11
+ VERSION = '0.2.0'
12
12
  end
13
13
  end
14
14
  end
@@ -25,7 +25,7 @@ module OpenTelemetry
25
25
  end
26
26
 
27
27
  @p_floor = (Math.frexp(probability)[1] - 1).abs
28
- @p_ceil = @p_floor + 1
28
+ @p_ceil = @p_floor - 1
29
29
  floor = Math.ldexp(1.0, -@p_floor)
30
30
  ceil = Math.ldexp(1.0, -@p_ceil)
31
31
  @p_ceil_probability = (probability - floor) / (ceil - floor)
@@ -42,39 +42,22 @@ module OpenTelemetry
42
42
  def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:)
43
43
  parent_span_context = OpenTelemetry::Trace.current_span(parent_context).context
44
44
  p = probabilistic_p
45
- if parent_span_context.valid?
46
- tracestate = parent_span_context.tracestate
47
- parse_ot_vendor_tag(tracestate) do |_, in_r, rest|
48
- r = if in_r.nil? || in_r > 62
49
- OpenTelemetry.logger.debug("ConsistentProbabilitySampler: potentially inconsistent trace detected - r: #{in_r.inspect}")
50
- generate_r(trace_id)
51
- else
52
- in_r
53
- end
54
- if p <= r
55
- Result.new(decision: Decision::RECORD_AND_SAMPLE, tracestate: update_tracestate(tracestate, p, r, rest))
56
- else
57
- Result.new(decision: Decision::DROP, tracestate: update_tracestate(tracestate, nil, r, rest))
58
- end
45
+ tracestate = parent_span_context.tracestate
46
+ parse_ot_vendor_tag(tracestate) do |_, r, rest|
47
+ if r.nil? || r > 62
48
+ OpenTelemetry.logger.debug("ConsistentProbabilitySampler: potentially inconsistent trace detected - r: #{r.inspect}") if parent_span_context.valid?
49
+ r = generate_r(trace_id)
59
50
  end
60
- else
61
- r = generate_r(trace_id)
62
51
  if p <= r
63
- Result.new(decision: Decision::RECORD_AND_SAMPLE, tracestate: new_tracestate(p: p, r: r))
52
+ Result.new(decision: Decision::RECORD_AND_SAMPLE, tracestate: update_tracestate(tracestate, p, r, rest))
64
53
  else
65
- Result.new(decision: Decision::DROP, tracestate: new_tracestate(r: r))
54
+ Result.new(decision: Decision::DROP, tracestate: update_tracestate(tracestate, nil, r, rest))
66
55
  end
67
56
  end
68
57
  end
69
58
 
70
59
  private
71
60
 
72
- def generate_r(trace_id)
73
- x = trace_id[8, 8].unpack1('Q>') | 0x3
74
- clz = 64 - x.bit_length
75
- clz
76
- end
77
-
78
61
  def probabilistic_p
79
62
  if Random.rand < @p_ceil_probability
80
63
  @p_ceil
@@ -17,6 +17,40 @@ module OpenTelemetry
17
17
  MAX_LIST_LENGTH = 256 # Defined by https://www.w3.org/TR/trace-context/
18
18
  private_constant(:DECIMAL, :MAX_LIST_LENGTH)
19
19
 
20
+ private
21
+
22
+ # sanitized_tracestate returns an OpenTelemetry Tracestate object with the
23
+ # tracestate sanitized according to the Context invariants defined in the
24
+ # tracestate probability sampling spec.
25
+ #
26
+ # If r is nil after the sanitization, it is generated from the trace_id.
27
+ #
28
+ # This method assumes the parent span context is valid.
29
+ #
30
+ # @param trace_id [OpenTelemetry::Trace::TraceId] the trace id
31
+ # @param span_context [OpenTelemetry::Trace::SpanContext] the parent span context
32
+ # @return [OpenTelemetry::Trace::Tracestate] the sanitized tracestate
33
+ def sanitized_tracestate(trace_id, span_context)
34
+ sampled = span_context.trace_flags.sampled?
35
+ tracestate = span_context.tracestate
36
+ parse_ot_vendor_tag(tracestate) do |p, r, rest|
37
+ if !r.nil? && r > 62
38
+ p = r = nil
39
+ elsif !p.nil? && p > 63
40
+ p = nil
41
+ elsif !p.nil? && !r.nil? && !invariant(p, r, sampled)
42
+ p = nil
43
+ elsif !r.nil?
44
+ return tracestate
45
+ end
46
+ if r.nil?
47
+ OpenTelemetry.logger.debug("ConsistentProbabilitySampler: potentially inconsistent trace detected - r: #{r.inspect}")
48
+ r = generate_r(trace_id)
49
+ end
50
+ update_tracestate(tracestate, p, r, rest)
51
+ end
52
+ end
53
+
20
54
  # parse_ot_vendor_tag parses the 'ot' vendor tag of the tracestate.
21
55
  # It yields the parsed probability fields and the remaining tracestate.
22
56
  # It returns the result of the block.
@@ -44,27 +78,22 @@ module OpenTelemetry
44
78
  end
45
79
 
46
80
  def update_tracestate(tracestate, p, r, rest) # rubocop:disable Naming/UncommunicativeMethodParamName
47
- # This could be more efficient and allocate less, however it *should* only be used for root spans and sanitizing invalid tracestate
48
- # in the most common configuration of parent_consistent_probability_based(root: consistent_probability_based(p)).
49
- ps = "p:#{p}" unless p.nil?
50
- rs = "r:#{r}" unless r.nil?
51
- ot = [ps, rs, rest].compact.join(';')
52
- if ot.empty?
81
+ if p.nil? && r.nil? && rest.nil?
53
82
  tracestate.delete('ot')
54
- else
55
- tracestate.set_value('ot', ot)
56
- end
57
- end
58
-
59
- def new_tracestate(p: nil, r: nil) # rubocop:disable Naming/UncommunicativeMethodParamName
60
- if p.nil? && r.nil?
61
- OpenTelemetry::Trace::Tracestate.DEFAULT
83
+ elsif p.nil? && r.nil?
84
+ tracestate.set_value('ot', rest)
85
+ elsif p.nil? && rest.nil?
86
+ tracestate.set_value('ot', "r:#{r}")
87
+ elsif r.nil? && rest.nil?
88
+ tracestate.set_value('ot', "p:#{p}")
62
89
  elsif p.nil?
63
- OpenTelemetry::Trace::Tracestate.from_hash('ot' => "r:#{r}")
90
+ tracestate.set_value('ot', "r:#{r};#{rest}")
64
91
  elsif r.nil?
65
- OpenTelemetry::Trace::Tracestate.from_hash('ot' => "p:#{p}")
92
+ tracestate.set_value('ot', "p:#{p};#{rest}")
93
+ elsif rest.nil?
94
+ tracestate.set_value('ot', "p:#{p};r:#{r}")
66
95
  else
67
- OpenTelemetry::Trace::Tracestate.from_hash('ot' => "p:#{p};r:#{r}")
96
+ tracestate.set_value('ot', "p:#{p};r:#{r};#{rest}")
68
97
  end
69
98
  end
70
99
 
@@ -75,6 +104,12 @@ module OpenTelemetry
75
104
  def decimal(str)
76
105
  str.to_i if !str.nil? && DECIMAL.match?(str)
77
106
  end
107
+
108
+ def generate_r(trace_id)
109
+ x = trace_id[8, 8].unpack1('Q>') | 0x3
110
+ clz = 64 - x.bit_length
111
+ clz
112
+ end
78
113
  end
79
114
  end
80
115
  end
@@ -43,7 +43,7 @@ module OpenTelemetry
43
43
  if !parent_span_context.valid?
44
44
  @root.should_sample?(trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes)
45
45
  else
46
- tracestate = sanitized_tracestate(parent_span_context)
46
+ tracestate = sanitized_tracestate(trace_id, parent_span_context)
47
47
  if parent_span_context.trace_flags.sampled?
48
48
  Result.new(decision: Decision::RECORD_AND_SAMPLE, tracestate: tracestate)
49
49
  else
@@ -55,31 +55,6 @@ module OpenTelemetry
55
55
  protected
56
56
 
57
57
  attr_reader :root
58
-
59
- private
60
-
61
- # sanitized_tracestate returns an OpenTelemetry Tracestate object with the
62
- # tracestate sanitized according to the Context invariants defined in the
63
- # tracestate probability sampling spec.
64
- #
65
- # @param span_context [OpenTelemetry::Trace::SpanContext] the parent span context
66
- # @return [OpenTelemetry::Trace::Tracestate] the sanitized tracestate
67
- def sanitized_tracestate(span_context)
68
- sampled = span_context.trace_flags.sampled?
69
- tracestate = span_context.tracestate
70
- parse_ot_vendor_tag(tracestate) do |p, r, rest|
71
- if !r.nil? && r > 62
72
- p = r = nil
73
- elsif !p.nil? && p > 63
74
- p = nil
75
- elsif !p.nil? && !r.nil? && !invariant(p, r, sampled)
76
- p = nil
77
- else
78
- return tracestate
79
- end
80
- update_tracestate(tracestate, p, r, rest)
81
- end
82
- end
83
58
  end
84
59
  end
85
60
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-sdk-experimental
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-09 00:00:00.000000000 Z
11
+ date: 2023-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opentelemetry-api
@@ -188,6 +188,7 @@ files:
188
188
  - ".yardopts"
189
189
  - CHANGELOG.md
190
190
  - LICENSE
191
+ - README.md
191
192
  - lib/opentelemetry-sdk-experimental.rb
192
193
  - lib/opentelemetry/sdk/experimental.rb
193
194
  - lib/opentelemetry/sdk/experimental/samplers_patch.rb
@@ -200,10 +201,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby
200
201
  licenses:
201
202
  - Apache-2.0
202
203
  metadata:
203
- changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk-experimental/v0.1.0/file.CHANGELOG.html
204
- source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/api
204
+ changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk-experimental/v0.2.0/file.CHANGELOG.html
205
+ source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/sdk_experimental
205
206
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
206
- documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk-experimental/v0.1.0
207
+ documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk-experimental/v0.2.0
207
208
  post_install_message:
208
209
  rdoc_options: []
209
210
  require_paths: