opentelemetry-sdk 0.2.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +9 -0
- data/CHANGELOG.md +23 -0
- data/LICENSE +1 -1
- data/README.md +73 -0
- data/lib/opentelemetry-sdk.rb +7 -0
- data/lib/opentelemetry/sdk.rb +51 -0
- data/lib/opentelemetry/sdk/baggage.rb +16 -0
- data/lib/opentelemetry/sdk/baggage/builder.rb +40 -0
- data/lib/opentelemetry/sdk/baggage/manager.rb +97 -0
- data/lib/opentelemetry/sdk/configurator.rb +172 -0
- data/lib/opentelemetry/sdk/instrumentation_library.rb +13 -0
- data/lib/opentelemetry/sdk/internal.rb +21 -1
- data/lib/opentelemetry/sdk/resources.rb +1 -0
- data/lib/opentelemetry/sdk/resources/constants.rb +124 -0
- data/lib/opentelemetry/sdk/resources/resource.rb +39 -19
- data/lib/opentelemetry/sdk/trace.rb +2 -1
- data/lib/opentelemetry/sdk/trace/config/trace_config.rb +3 -3
- data/lib/opentelemetry/sdk/trace/event.rb +48 -0
- data/lib/opentelemetry/sdk/trace/export.rb +2 -7
- data/lib/opentelemetry/sdk/trace/export/batch_span_processor.rb +41 -35
- data/lib/opentelemetry/sdk/trace/export/console_span_exporter.rb +1 -1
- data/lib/opentelemetry/sdk/trace/export/in_memory_span_exporter.rb +7 -7
- data/lib/opentelemetry/sdk/trace/export/multi_span_exporter.rb +8 -14
- data/lib/opentelemetry/sdk/trace/export/noop_span_exporter.rb +4 -4
- data/lib/opentelemetry/sdk/trace/export/simple_span_processor.rb +10 -1
- data/lib/opentelemetry/sdk/trace/multi_span_processor.rb +12 -1
- data/lib/opentelemetry/sdk/trace/noop_span_processor.rb +10 -1
- data/lib/opentelemetry/sdk/trace/samplers.rb +48 -57
- data/lib/opentelemetry/sdk/trace/samplers/constant_sampler.rb +33 -0
- data/lib/opentelemetry/sdk/trace/samplers/decision.rb +3 -3
- data/lib/opentelemetry/sdk/trace/samplers/parent_based.rb +53 -0
- data/lib/opentelemetry/sdk/trace/samplers/result.rb +4 -3
- data/lib/opentelemetry/sdk/trace/samplers/trace_id_ratio_based.rb +45 -0
- data/lib/opentelemetry/sdk/trace/span.rb +39 -28
- data/lib/opentelemetry/sdk/trace/span_data.rb +18 -2
- data/lib/opentelemetry/sdk/trace/tracer.rb +26 -15
- data/lib/opentelemetry/sdk/trace/{tracer_factory.rb → tracer_provider.rb} +9 -9
- data/lib/opentelemetry/sdk/version.rb +1 -1
- metadata +20 -8
- data/lib/opentelemetry/sdk/trace/samplers/probability_sampler.rb +0 -74
@@ -14,13 +14,13 @@ module OpenTelemetry
|
|
14
14
|
#
|
15
15
|
# class MyClassTest
|
16
16
|
# def setup
|
17
|
-
# @
|
17
|
+
# @tracer_provider = TracerProvider.new
|
18
18
|
# @exporter = InMemorySpanExporter.new
|
19
|
-
# @
|
19
|
+
# @tracer_provider.add_span_processor(SimpleSampledSpansProcessor.new(@exporter))
|
20
20
|
# end
|
21
21
|
#
|
22
22
|
# def test_finished_spans
|
23
|
-
# @
|
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
|
-
#
|
64
|
+
# FAILURE
|
65
65
|
def export(span_datas)
|
66
66
|
@mutex.synchronize do
|
67
|
-
return
|
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 {
|
75
|
-
# registered to a {
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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 {
|
39
|
-
# registered to a {
|
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
|
56
|
-
|
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 {
|
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
|
-
|
30
|
+
FAILURE
|
31
31
|
end
|
32
32
|
|
33
|
-
# Called when {
|
34
|
-
# registered to a {
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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/
|
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 {
|
16
|
-
# {ALWAYS_OFF}, and {
|
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:,
|
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
|
45
|
+
private_constant(:RECORD_AND_SAMPLED, :NOT_RECORD, :RECORD, :SAMPLING_HINTS)
|
48
46
|
|
49
|
-
#
|
47
|
+
# Returns a {Result} with {Decision::RECORD_AND_SAMPLED}.
|
48
|
+
ALWAYS_ON = ConstantSampler.new(result: RECORD_AND_SAMPLED, description: 'AlwaysOnSampler')
|
50
49
|
|
51
|
-
#
|
52
|
-
|
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
|
-
#
|
56
|
-
#
|
57
|
-
|
58
|
-
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
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
|
74
|
-
#
|
83
|
+
# Returns a new sampler. The ratio describes the proportion of the trace ID
|
84
|
+
# space that is sampled.
|
75
85
|
#
|
76
|
-
# @param [Numeric]
|
86
|
+
# @param [Numeric] ratio The desired sampling ratio.
|
77
87
|
# Must be within [0.0, 1.0].
|
78
|
-
# @
|
79
|
-
|
80
|
-
|
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
|
-
|
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 =
|
15
|
+
NOT_RECORD = :__not_record__
|
16
16
|
|
17
17
|
# Decision to record events and not sample.
|
18
|
-
RECORD =
|
18
|
+
RECORD = :__record__
|
19
19
|
|
20
20
|
# Decision to record events and sample.
|
21
|
-
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,
|
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
|
31
|
-
# containing attributes to be
|
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
|