opentelemetry-sdk 0.2.0 → 0.6.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +9 -0
  3. data/CHANGELOG.md +23 -0
  4. data/LICENSE +1 -1
  5. data/README.md +73 -0
  6. data/lib/opentelemetry-sdk.rb +7 -0
  7. data/lib/opentelemetry/sdk.rb +51 -0
  8. data/lib/opentelemetry/sdk/baggage.rb +16 -0
  9. data/lib/opentelemetry/sdk/baggage/builder.rb +40 -0
  10. data/lib/opentelemetry/sdk/baggage/manager.rb +97 -0
  11. data/lib/opentelemetry/sdk/configurator.rb +172 -0
  12. data/lib/opentelemetry/sdk/instrumentation_library.rb +13 -0
  13. data/lib/opentelemetry/sdk/internal.rb +21 -1
  14. data/lib/opentelemetry/sdk/resources.rb +1 -0
  15. data/lib/opentelemetry/sdk/resources/constants.rb +124 -0
  16. data/lib/opentelemetry/sdk/resources/resource.rb +39 -19
  17. data/lib/opentelemetry/sdk/trace.rb +2 -1
  18. data/lib/opentelemetry/sdk/trace/config/trace_config.rb +3 -3
  19. data/lib/opentelemetry/sdk/trace/event.rb +48 -0
  20. data/lib/opentelemetry/sdk/trace/export.rb +2 -7
  21. data/lib/opentelemetry/sdk/trace/export/batch_span_processor.rb +41 -35
  22. data/lib/opentelemetry/sdk/trace/export/console_span_exporter.rb +1 -1
  23. data/lib/opentelemetry/sdk/trace/export/in_memory_span_exporter.rb +7 -7
  24. data/lib/opentelemetry/sdk/trace/export/multi_span_exporter.rb +8 -14
  25. data/lib/opentelemetry/sdk/trace/export/noop_span_exporter.rb +4 -4
  26. data/lib/opentelemetry/sdk/trace/export/simple_span_processor.rb +10 -1
  27. data/lib/opentelemetry/sdk/trace/multi_span_processor.rb +12 -1
  28. data/lib/opentelemetry/sdk/trace/noop_span_processor.rb +10 -1
  29. data/lib/opentelemetry/sdk/trace/samplers.rb +48 -57
  30. data/lib/opentelemetry/sdk/trace/samplers/constant_sampler.rb +33 -0
  31. data/lib/opentelemetry/sdk/trace/samplers/decision.rb +3 -3
  32. data/lib/opentelemetry/sdk/trace/samplers/parent_based.rb +53 -0
  33. data/lib/opentelemetry/sdk/trace/samplers/result.rb +4 -3
  34. data/lib/opentelemetry/sdk/trace/samplers/trace_id_ratio_based.rb +45 -0
  35. data/lib/opentelemetry/sdk/trace/span.rb +39 -28
  36. data/lib/opentelemetry/sdk/trace/span_data.rb +18 -2
  37. data/lib/opentelemetry/sdk/trace/tracer.rb +26 -15
  38. data/lib/opentelemetry/sdk/trace/{tracer_factory.rb → tracer_provider.rb} +9 -9
  39. data/lib/opentelemetry/sdk/version.rb +1 -1
  40. metadata +20 -8
  41. data/lib/opentelemetry/sdk/trace/samplers/probability_sampler.rb +0 -74
@@ -23,7 +23,7 @@ module OpenTelemetry
23
23
  end
24
24
 
25
25
  def export(spans)
26
- return ResultCodes::FAILED_NOT_RETRYABLE if @stopped
26
+ return ResultCodes::FAILURE if @stopped
27
27
 
28
28
  Array(spans).each { |s| pp s }
29
29
 
@@ -14,13 +14,13 @@ module OpenTelemetry
14
14
  #
15
15
  # class MyClassTest
16
16
  # def setup
17
- # @tracer_factory = TracerFactory.new
17
+ # @tracer_provider = TracerProvider.new
18
18
  # @exporter = InMemorySpanExporter.new
19
- # @tracer_factory.add_span_processor(SimpleSampledSpansProcessor.new(@exporter))
19
+ # @tracer_provider.add_span_processor(SimpleSampledSpansProcessor.new(@exporter))
20
20
  # end
21
21
  #
22
22
  # def test_finished_spans
23
- # @tracer_factory.tracer.in_span("span") {}
23
+ # @tracer_provider.tracer.in_span("span") {}
24
24
  #
25
25
  # spans = @exporter.finished_spans
26
26
  # spans.wont_be_nil
@@ -61,18 +61,18 @@ module OpenTelemetry
61
61
  # @param [Enumerable<SpanData>] span_datas the list of sampled {SpanData}s to be
62
62
  # exported.
63
63
  # @return [Integer] the result of the export, SUCCESS or
64
- # FAILED_NOT_RETRYABLE
64
+ # FAILURE
65
65
  def export(span_datas)
66
66
  @mutex.synchronize do
67
- return FAILED_NOT_RETRYABLE if @stopped
67
+ return FAILURE if @stopped
68
68
 
69
69
  @finished_spans.concat(span_datas.to_a)
70
70
  end
71
71
  SUCCESS
72
72
  end
73
73
 
74
- # Called when {TracerFactory#shutdown} is called, if this exporter is
75
- # registered to a {TracerFactory} object.
74
+ # Called when {TracerProvider#shutdown} is called, if this exporter is
75
+ # registered to a {TracerProvider} object.
76
76
  def shutdown
77
77
  @mutex.synchronize do
78
78
  @finished_spans.clear
@@ -26,17 +26,15 @@ module OpenTelemetry
26
26
  # @return [Integer] the result of the export.
27
27
  def export(spans)
28
28
  @span_exporters.inject(SUCCESS) do |result_code, span_exporter|
29
- begin
30
- merge_result_code(result_code, span_exporter.export(spans))
31
- rescue => e # rubocop:disable Style/RescueStandardError
32
- OpenTelemetry.logger.warn("exception raised by export - #{e}")
33
- FAILED_NOT_RETRYABLE
34
- end
29
+ merge_result_code(result_code, span_exporter.export(spans))
30
+ rescue => e # rubocop:disable Style/RescueStandardError
31
+ OpenTelemetry.logger.warn("exception raised by export - #{e}")
32
+ FAILURE
35
33
  end
36
34
  end
37
35
 
38
- # Called when {TracerFactory#shutdown} is called, if this exporter is
39
- # registered to a {TracerFactory} object.
36
+ # Called when {TracerProvider#shutdown} is called, if this exporter is
37
+ # registered to a {TracerProvider} object.
40
38
  def shutdown
41
39
  @span_exporters.each(&:shutdown)
42
40
  end
@@ -48,13 +46,9 @@ module OpenTelemetry
48
46
  if result_code == SUCCESS && new_result_code == SUCCESS
49
47
  # If both errors are success then return success.
50
48
  SUCCESS
51
- elsif result_code == FAILED_NOT_RETRYABLE || new_result_code == FAILED_NOT_RETRYABLE
52
- # If any of the codes is not retryable then return not_retryable.
53
- FAILED_NOT_RETRYABLE
54
49
  else
55
- # At this point at least one of the code is FAILED_RETRYABLE and
56
- # none are FAILED_NOT_RETRYABLE, so return FAILED_RETRYABLE.
57
- FAILED_RETRYABLE
50
+ # At this point at least one of the code is FAILURE, so return FAILURE.
51
+ FAILURE
58
52
  end
59
53
  end
60
54
  end
@@ -12,7 +12,7 @@ module OpenTelemetry
12
12
  # duck type. SpanExporter allows different tracing services to export
13
13
  # recorded data for sampled spans in their own format.
14
14
  #
15
- # To export data an exporter MUST be registered to the {TracerFactory} using
15
+ # To export data an exporter MUST be registered to the {TracerProvider} using
16
16
  # a {SimpleSpanProcessor} or a {BatchSpanProcessor}.
17
17
  class NoopSpanExporter
18
18
  def initialize
@@ -27,11 +27,11 @@ module OpenTelemetry
27
27
  def export(spans)
28
28
  return SUCCESS unless @stopped
29
29
 
30
- FAILED_NOT_RETRYABLE
30
+ FAILURE
31
31
  end
32
32
 
33
- # Called when {TracerFactory#shutdown} is called, if this exporter is
34
- # registered to a {TracerFactory} object.
33
+ # Called when {TracerProvider#shutdown} is called, if this exporter is
34
+ # registered to a {TracerProvider} object.
35
35
  def shutdown
36
36
  @stopped = true
37
37
  end
@@ -52,7 +52,16 @@ module OpenTelemetry
52
52
  OpenTelemetry.logger.error("unexpected error in span.on_finish - #{e}")
53
53
  end
54
54
 
55
- # Called when {TracerFactory#shutdown} is called.
55
+ # Export all ended spans to the configured `Exporter` that have not yet
56
+ # been exported.
57
+ #
58
+ # This method should only be called in cases where it is absolutely
59
+ # necessary, such as when using some FaaS providers that may suspend
60
+ # the process after an invocation, but before the `Processor` exports
61
+ # the completed spans.
62
+ def force_flush; end
63
+
64
+ # Called when {TracerProvider#shutdown} is called.
56
65
  def shutdown
57
66
  @span_exporter&.shutdown
58
67
  end
@@ -41,7 +41,18 @@ module OpenTelemetry
41
41
  @span_processors.each { |processor| processor.on_finish(span) }
42
42
  end
43
43
 
44
- # Called when {TracerFactory#shutdown} is called.
44
+ # Export all ended spans to the configured `Exporter` that have not yet
45
+ # been exported.
46
+ #
47
+ # This method should only be called in cases where it is absolutely
48
+ # necessary, such as when using some FaaS providers that may suspend
49
+ # the process after an invocation, but before the `Processor` exports
50
+ # the completed spans.
51
+ def force_flush
52
+ @span_processors.each(&:force_flush)
53
+ end
54
+
55
+ # Called when {TracerProvider#shutdown} is called.
45
56
  def shutdown
46
57
  @span_processors.each(&:shutdown)
47
58
  end
@@ -33,7 +33,16 @@ module OpenTelemetry
33
33
  # @param [Span] span the {Span} that just ended.
34
34
  def on_finish(span); end
35
35
 
36
- # Called when {TracerFactory#shutdown} is called.
36
+ # Export all ended spans to the configured `Exporter` that have not yet
37
+ # been exported.
38
+ #
39
+ # This method should only be called in cases where it is absolutely
40
+ # necessary, such as when using some FaaS providers that may suspend
41
+ # the process after an invocation, but before the `Processor` exports
42
+ # the completed spans.
43
+ def force_flush; end
44
+
45
+ # Called when {TracerProvider#shutdown} is called.
37
46
  def shutdown; end
38
47
  end
39
48
  end
@@ -6,29 +6,28 @@
6
6
 
7
7
  require 'opentelemetry/sdk/trace/samplers/decision'
8
8
  require 'opentelemetry/sdk/trace/samplers/result'
9
- require 'opentelemetry/sdk/trace/samplers/probability_sampler'
9
+ require 'opentelemetry/sdk/trace/samplers/constant_sampler'
10
+ require 'opentelemetry/sdk/trace/samplers/parent_based'
11
+ require 'opentelemetry/sdk/trace/samplers/trace_id_ratio_based'
10
12
 
11
13
  module OpenTelemetry
12
14
  module SDK
13
15
  module Trace
14
16
  # The Samplers module contains the sampling logic for OpenTelemetry. The
15
- # reference implementation provides a {ProbabilitySampler}, {ALWAYS_ON},
16
- # {ALWAYS_OFF}, and {ALWAYS_PARENT}.
17
+ # reference implementation provides a {TraceIdRatioBased}, {ALWAYS_ON},
18
+ # {ALWAYS_OFF}, and {ParentBased}.
17
19
  #
18
- # Custom samplers can be provided by SDK users. The required interface is
19
- # a callable with the signature:
20
+ # Custom samplers can be provided by SDK users. The required interface is:
20
21
  #
21
- # (trace_id:, span_id:, parent_context:, hint:, links:, name:, kind:, attributes:) -> Result
22
+ # should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:) -> Result
23
+ # description -> String
22
24
  #
23
25
  # Where:
24
26
  #
25
27
  # @param [String] trace_id The trace_id of the {Span} to be created.
26
- # @param [String] span_id The span_id of the {Span} to be created.
27
28
  # @param [OpenTelemetry::Trace::SpanContext] parent_context The
28
29
  # {OpenTelemetry::Trace::SpanContext} of a parent span, typically
29
30
  # extracted from the wire. Can be nil for a root span.
30
- # @param [Symbol] hint A {OpenTelemetry::Trace::SamplingHint} about
31
- # whether the {Span} should be sampled and/or record events.
32
31
  # @param [Enumerable<Link>] links A collection of links to be associated
33
32
  # with the {Span} to be created. Can be nil.
34
33
  # @param [String] name Name of the {Span} to be created.
@@ -42,63 +41,55 @@ module OpenTelemetry
42
41
  NOT_RECORD = Result.new(decision: Decision::NOT_RECORD)
43
42
  RECORD = Result.new(decision: Decision::RECORD)
44
43
  SAMPLING_HINTS = [Decision::NOT_RECORD, Decision::RECORD, Decision::RECORD_AND_SAMPLED].freeze
45
- APPLY_PROBABILITY_TO_SYMBOLS = %i[root_spans root_spans_and_remote_parent all_spans].freeze
46
44
 
47
- private_constant(:RECORD_AND_SAMPLED, :NOT_RECORD, :RECORD, :SAMPLING_HINTS, :APPLY_PROBABILITY_TO_SYMBOLS)
45
+ private_constant(:RECORD_AND_SAMPLED, :NOT_RECORD, :RECORD, :SAMPLING_HINTS)
48
46
 
49
- # rubocop:disable Lint/UnusedBlockArgument
47
+ # Returns a {Result} with {Decision::RECORD_AND_SAMPLED}.
48
+ ALWAYS_ON = ConstantSampler.new(result: RECORD_AND_SAMPLED, description: 'AlwaysOnSampler')
50
49
 
51
- # Ignores all values in hint and returns a {Result} with
52
- # {Decision::RECORD_AND_SAMPLED}.
53
- ALWAYS_ON = ->(trace_id:, span_id:, parent_context:, hint:, links:, name:, kind:, attributes:) { RECORD_AND_SAMPLED }
50
+ # Returns a {Result} with {Decision::NOT_RECORD}.
51
+ ALWAYS_OFF = ConstantSampler.new(result: NOT_RECORD, description: 'AlwaysOffSampler')
54
52
 
55
- # Ignores all values in hint and returns a {Result} with
56
- # {Decision::NOT_RECORD}.
57
- ALWAYS_OFF = ->(trace_id:, span_id:, parent_context:, hint:, links:, name:, kind:, attributes:) { NOT_RECORD }
58
-
59
- # Ignores all values in hint and returns a {Result} with
60
- # {Decision::RECORD_AND_SAMPLED} if the parent context is sampled or
61
- # {Decision::NOT_RECORD} otherwise, or if there is no parent context.
62
- # rubocop:disable Style/Lambda
63
- ALWAYS_PARENT = ->(trace_id:, span_id:, parent_context:, hint:, links:, name:, kind:, attributes:) do
64
- if parent_context&.trace_flags&.sampled?
65
- RECORD_AND_SAMPLED
66
- else
67
- NOT_RECORD
68
- end
53
+ # Returns a new sampler. It delegates to samplers according to the following rules:
54
+ #
55
+ # | Parent | parent.remote? | parent.trace_flags.sampled? | Invoke sampler |
56
+ # |--|--|--|--|
57
+ # | absent | n/a | n/a | root |
58
+ # | present | true | true | remote_parent_sampled |
59
+ # | present | true | false | remote_parent_not_sampled |
60
+ # | present | false | true | local_parent_sampled |
61
+ # | present | false | false | local_parent_not_sampled |
62
+ #
63
+ # @param [Sampler] root The sampler to which the sampling
64
+ # decision is delegated for spans with no parent (root spans).
65
+ # @param [optional Sampler] remote_parent_sampled The sampler to which the sampling
66
+ # decision is delegated for remote parent sampled spans. Defaults to ALWAYS_ON.
67
+ # @param [optional Sampler] remote_parent_not_sampled The sampler to which the sampling
68
+ # decision is delegated for remote parent not sampled spans. Defaults to ALWAYS_OFF.
69
+ # @param [optional Sampler] local_parent_sampled The sampler to which the sampling
70
+ # decision is delegated for local parent sampled spans. Defaults to ALWAYS_ON.
71
+ # @param [optional Sampler] local_parent_not_sampled The sampler to which the sampling
72
+ # decision is delegated for local parent not sampld spans. Defaults to ALWAYS_OFF.
73
+ def self.parent_based(
74
+ root:,
75
+ remote_parent_sampled: ALWAYS_ON,
76
+ remote_parent_not_sampled: ALWAYS_OFF,
77
+ local_parent_sampled: ALWAYS_ON,
78
+ local_parent_not_sampled: ALWAYS_OFF
79
+ )
80
+ ParentBased.new(root, remote_parent_sampled, remote_parent_not_sampled, local_parent_sampled, local_parent_not_sampled)
69
81
  end
70
- # rubocop:enable Style/Lambda
71
- # rubocop:enable Lint/UnusedBlockArgument
72
82
 
73
- # Returns a new sampler. The probability of sampling a trace is equal
74
- # to that of the specified probability.
83
+ # Returns a new sampler. The ratio describes the proportion of the trace ID
84
+ # space that is sampled.
75
85
  #
76
- # @param [Numeric] probability The desired probability of sampling.
86
+ # @param [Numeric] ratio The desired sampling ratio.
77
87
  # Must be within [0.0, 1.0].
78
- # @param [optional Enumerable<Symbol>] ignore_hints Sampling hints to
79
- # ignore. Defaults to ignore {OpenTelemetry::Trace::SamplingHint::RECORD}.
80
- # @param [optional Boolean] ignore_parent Whether to ignore parent
81
- # sampling. Defaults to not ignore parent sampling.
82
- # @param [optional Symbol] apply_probability_to Whether to apply
83
- # probability sampling to root spans, root spans and remote parents,
84
- # or all spans. Allowed values include :root_spans, :root_spans_and_remote_parent,
85
- # and :all_spans. Defaults to :root_spans_and_remote_parent.
86
- # @raise [ArgumentError] if probability is out of range
87
- # @raise [ArgumentError] if ignore_hints contains invalid hints
88
- # @raise [ArgumentError] if apply_probability_to is not one of the allowed symbols
89
- def self.probability(probability,
90
- ignore_hints: [OpenTelemetry::Trace::SamplingHint::RECORD],
91
- ignore_parent: false,
92
- apply_probability_to: :root_spans_and_remote_parent)
93
- raise ArgumentError, 'probability must be in range [0.0, 1.0]' unless (0.0..1.0).include?(probability)
94
- raise ArgumentError, 'ignore_hints' unless (ignore_hints.to_a - SAMPLING_HINTS).empty?
95
- raise ArgumentError, 'apply_probability_to' unless APPLY_PROBABILITY_TO_SYMBOLS.include?(apply_probability_to)
88
+ # @raise [ArgumentError] if ratio is out of range
89
+ def self.trace_id_ratio_based(ratio)
90
+ raise ArgumentError, 'ratio must be in range [0.0, 1.0]' unless (0.0..1.0).include?(ratio)
96
91
 
97
- ProbabilitySampler.new(probability,
98
- ignore_hints: ignore_hints.to_a,
99
- ignore_parent: ignore_parent,
100
- apply_to_remote_parent: apply_probability_to != :root_spans,
101
- apply_to_all_spans: apply_probability_to == :all_spans)
92
+ TraceIdRatioBased.new(ratio)
102
93
  end
103
94
  end
104
95
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ module OpenTelemetry
8
+ module SDK
9
+ module Trace
10
+ module Samplers
11
+ # @api private
12
+ #
13
+ # Implements a sampler returning a constant result.
14
+ class ConstantSampler
15
+ attr_reader :description
16
+
17
+ def initialize(result:, description:)
18
+ @result = result
19
+ @description = description
20
+ end
21
+
22
+ # @api private
23
+ #
24
+ # See {Samplers}.
25
+ def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:)
26
+ # All arguments ignored for sampling decision.
27
+ @result
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -12,13 +12,13 @@ module OpenTelemetry
12
12
  # decision part of a sampling {Result}.
13
13
  module Decision
14
14
  # Decision to not record events and not sample.
15
- NOT_RECORD = OpenTelemetry::Trace::SamplingHint::NOT_RECORD
15
+ NOT_RECORD = :__not_record__
16
16
 
17
17
  # Decision to record events and not sample.
18
- RECORD = OpenTelemetry::Trace::SamplingHint::RECORD
18
+ RECORD = :__record__
19
19
 
20
20
  # Decision to record events and sample.
21
- RECORD_AND_SAMPLED = OpenTelemetry::Trace::SamplingHint::RECORD_AND_SAMPLED
21
+ RECORD_AND_SAMPLED = :__record_and_sampled__
22
22
  end
23
23
  end
24
24
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ module OpenTelemetry
8
+ module SDK
9
+ module Trace
10
+ module Samplers
11
+ # @api private
12
+ #
13
+ # This is a composite sampler. ParentBased helps distinguished between the
14
+ # following cases:
15
+ # * No parent (root span).
16
+ # * Remote parent (SpanContext.remote? with trace_flags.sampled?)
17
+ # * Remote parent (SpanContext.remote? with !trace_flags.sampled?)
18
+ # * Local parent (!SpanContext.remote? with trace_flags.sampled?)
19
+ # * Local parent (!SpanContext.remote? with !trace_flags.sampled?)
20
+ class ParentBased
21
+ def initialize(root, remote_parent_sampled, remote_parent_not_sampled, local_parent_sampled, local_parent_not_sampled)
22
+ @root = root
23
+ @remote_parent_sampled = remote_parent_sampled
24
+ @remote_parent_not_sampled = remote_parent_not_sampled
25
+ @local_parent_sampled = local_parent_sampled
26
+ @local_parent_not_sampled = local_parent_not_sampled
27
+ end
28
+
29
+ # @api private
30
+ #
31
+ # See {Samplers}.
32
+ def description
33
+ "ParentBased{root=#{@root.description}, remote_parent_sampled=#{@remote_parent_sampled.description}, remote_parent_not_sampled=#{@remote_parent_not_sampled.description}, local_parent_sampled=#{@local_parent_sampled.description}, local_parent_not_sampled=#{@local_parent_not_sampled.description}}"
34
+ end
35
+
36
+ # @api private
37
+ #
38
+ # See {Samplers}.
39
+ def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:)
40
+ delegate = if parent_context.nil?
41
+ @root
42
+ elsif parent_context.remote?
43
+ parent_context.trace_flags.sampled? ? @remote_parent_sampled : @remote_parent_not_sampled
44
+ else
45
+ parent_context.trace_flags.sampled? ? @local_parent_sampled : @local_parent_not_sampled
46
+ end
47
+ delegate.should_sample?(trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -19,7 +19,7 @@ module OpenTelemetry
19
19
 
20
20
  # Returns a frozen hash of attributes to be attached span.
21
21
  #
22
- # @return [Hash<String, Object>]
22
+ # @return [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}]
23
23
  attr_reader :attributes
24
24
 
25
25
  # Returns a new sampling result with the specified decision and
@@ -27,8 +27,9 @@ module OpenTelemetry
27
27
  #
28
28
  # @param [Symbol] decision Whether or not a span should be sampled
29
29
  # and/or record events.
30
- # @param [optional Hash<String, Object>] attributes A frozen or freezable hash
31
- # containing attributes to be attached to the span.
30
+ # @param [optional Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}]
31
+ # attributes A frozen or freezable hash containing attributes to be
32
+ # attached to the span.
32
33
  def initialize(decision:, attributes: nil)
33
34
  @decision = decision
34
35
  @attributes = attributes.freeze || EMPTY_HASH
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2019 OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ module OpenTelemetry
8
+ module SDK
9
+ module Trace
10
+ module Samplers
11
+ # @api private
12
+ #
13
+ # Implements sampling based on a probability.
14
+ class TraceIdRatioBased
15
+ attr_reader :description
16
+
17
+ def initialize(probability)
18
+ @probability = probability
19
+ @id_upper_bound = (probability * (2**64 - 1)).ceil
20
+ @description = format('TraceIdRatioBased{%.6f}', probability)
21
+ end
22
+
23
+ # @api private
24
+ #
25
+ # See {Samplers}.
26
+ def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:)
27
+ # Ignored for sampling decision: parent_context:, links, name, kind, attributes.
28
+
29
+ if sample?(trace_id)
30
+ RECORD_AND_SAMPLED
31
+ else
32
+ NOT_RECORD
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def sample?(trace_id)
39
+ @probability == 1.0 || trace_id[8, 8].unpack1('Q>') < @id_upper_bound
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end