opentelemetry-sdk 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +9 -0
- data/CHANGELOG.md +1 -0
- data/LICENSE +201 -0
- data/README.md +73 -0
- data/lib/opentelemetry-sdk.rb +7 -0
- data/lib/opentelemetry/sdk.rb +69 -0
- data/lib/opentelemetry/sdk/configurator.rb +171 -0
- data/lib/opentelemetry/sdk/correlation_context.rb +16 -0
- data/lib/opentelemetry/sdk/correlation_context/builder.rb +40 -0
- data/lib/opentelemetry/sdk/correlation_context/manager.rb +87 -0
- data/lib/opentelemetry/sdk/instrumentation_library.rb +13 -0
- data/lib/opentelemetry/sdk/internal.rb +52 -0
- data/lib/opentelemetry/sdk/resources.rb +16 -0
- data/lib/opentelemetry/sdk/resources/constants.rb +124 -0
- data/lib/opentelemetry/sdk/resources/resource.rb +84 -0
- data/lib/opentelemetry/sdk/trace.rb +24 -0
- data/lib/opentelemetry/sdk/trace/config.rb +18 -0
- data/lib/opentelemetry/sdk/trace/config/trace_config.rb +77 -0
- data/lib/opentelemetry/sdk/trace/export.rb +30 -0
- data/lib/opentelemetry/sdk/trace/export/batch_span_processor.rb +144 -0
- data/lib/opentelemetry/sdk/trace/export/console_span_exporter.rb +40 -0
- data/lib/opentelemetry/sdk/trace/export/in_memory_span_exporter.rb +86 -0
- data/lib/opentelemetry/sdk/trace/export/multi_span_exporter.rb +58 -0
- data/lib/opentelemetry/sdk/trace/export/noop_span_exporter.rb +42 -0
- data/lib/opentelemetry/sdk/trace/export/simple_span_processor.rb +72 -0
- data/lib/opentelemetry/sdk/trace/multi_span_processor.rb +62 -0
- data/lib/opentelemetry/sdk/trace/noop_span_processor.rb +50 -0
- data/lib/opentelemetry/sdk/trace/samplers.rb +90 -0
- data/lib/opentelemetry/sdk/trace/samplers/constant_sampler.rb +33 -0
- data/lib/opentelemetry/sdk/trace/samplers/decision.rb +26 -0
- data/lib/opentelemetry/sdk/trace/samplers/parent_or_else.rb +43 -0
- data/lib/opentelemetry/sdk/trace/samplers/probability_sampler.rb +64 -0
- data/lib/opentelemetry/sdk/trace/samplers/result.rb +55 -0
- data/lib/opentelemetry/sdk/trace/span.rb +336 -0
- data/lib/opentelemetry/sdk/trace/span_data.rb +34 -0
- data/lib/opentelemetry/sdk/trace/tracer.rb +78 -0
- data/lib/opentelemetry/sdk/trace/tracer_provider.rb +84 -0
- data/lib/opentelemetry/sdk/version.rb +12 -0
- metadata +207 -0
@@ -0,0 +1,42 @@
|
|
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 Export
|
11
|
+
# A noop exporter that demonstrates and documents the SpanExporter
|
12
|
+
# duck type. SpanExporter allows different tracing services to export
|
13
|
+
# recorded data for sampled spans in their own format.
|
14
|
+
#
|
15
|
+
# To export data an exporter MUST be registered to the {TracerProvider} using
|
16
|
+
# a {SimpleSpanProcessor} or a {BatchSpanProcessor}.
|
17
|
+
class NoopSpanExporter
|
18
|
+
def initialize
|
19
|
+
@stopped = false
|
20
|
+
end
|
21
|
+
|
22
|
+
# Called to export sampled {Span}s.
|
23
|
+
#
|
24
|
+
# @param [Enumerable<Span>] spans the list of sampled {Span}s to be
|
25
|
+
# exported.
|
26
|
+
# @return [Integer] the result of the export.
|
27
|
+
def export(spans)
|
28
|
+
return SUCCESS unless @stopped
|
29
|
+
|
30
|
+
FAILURE
|
31
|
+
end
|
32
|
+
|
33
|
+
# Called when {TracerProvider#shutdown} is called, if this exporter is
|
34
|
+
# registered to a {TracerProvider} object.
|
35
|
+
def shutdown
|
36
|
+
@stopped = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,72 @@
|
|
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 Export
|
11
|
+
# An implementation of the duck type SpanProcessor that converts the
|
12
|
+
# {Span} to {io.opentelemetry.proto.trace.v1.Span} and passes it to the
|
13
|
+
# configured exporter.
|
14
|
+
#
|
15
|
+
# Only spans that are recorded are converted, {OpenTelemetry::Trace::Span#is_recording?} must
|
16
|
+
# return true.
|
17
|
+
class SimpleSpanProcessor
|
18
|
+
# Returns a new {SimpleSpanProcessor} that converts spans to
|
19
|
+
# proto and forwards them to the given span_exporter.
|
20
|
+
#
|
21
|
+
# @param span_exporter the (duck type) SpanExporter to where the
|
22
|
+
# recorded Spans are pushed.
|
23
|
+
# @return [SimpleSpanProcessor]
|
24
|
+
# @raise ArgumentError if the span_exporter is nil.
|
25
|
+
def initialize(span_exporter)
|
26
|
+
@span_exporter = span_exporter
|
27
|
+
end
|
28
|
+
|
29
|
+
# Called when a {Span} is started, if the {Span#recording?}
|
30
|
+
# returns true.
|
31
|
+
#
|
32
|
+
# This method is called synchronously on the execution thread, should
|
33
|
+
# not throw or block the execution thread.
|
34
|
+
#
|
35
|
+
# @param [Span] span the {Span} that just started.
|
36
|
+
def on_start(span)
|
37
|
+
# Do nothing.
|
38
|
+
end
|
39
|
+
|
40
|
+
# Called when a {Span} is ended, if the {Span#recording?}
|
41
|
+
# returns true.
|
42
|
+
#
|
43
|
+
# This method is called synchronously on the execution thread, should
|
44
|
+
# not throw or block the execution thread.
|
45
|
+
#
|
46
|
+
# @param [Span] span the {Span} that just ended.
|
47
|
+
def on_finish(span)
|
48
|
+
return unless span.context.trace_flags.sampled?
|
49
|
+
|
50
|
+
@span_exporter&.export([span.to_span_data])
|
51
|
+
rescue => e # rubocop:disable Style/RescueStandardError
|
52
|
+
OpenTelemetry.logger.error("unexpected error in span.on_finish - #{e}")
|
53
|
+
end
|
54
|
+
|
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.
|
65
|
+
def shutdown
|
66
|
+
@span_exporter&.shutdown
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,62 @@
|
|
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
|
+
# Implementation of the SpanProcessor duck type that simply forwards all
|
11
|
+
# received events to a list of SpanProcessors.
|
12
|
+
class MultiSpanProcessor
|
13
|
+
# Creates a new {MultiSpanProcessor}.
|
14
|
+
#
|
15
|
+
# @param [Enumerable<SpanProcessor>] span_processors a collection of
|
16
|
+
# SpanProcessors.
|
17
|
+
# @return [MultiSpanProcessor]
|
18
|
+
def initialize(span_processors)
|
19
|
+
@span_processors = span_processors.to_a.freeze
|
20
|
+
end
|
21
|
+
|
22
|
+
# Called when a {Span} is started, if the {Span#recording?}
|
23
|
+
# returns true.
|
24
|
+
#
|
25
|
+
# This method is called synchronously on the execution thread, should
|
26
|
+
# not throw or block the execution thread.
|
27
|
+
#
|
28
|
+
# @param [Span] span the {Span} that just started.
|
29
|
+
def on_start(span)
|
30
|
+
@span_processors.each { |processor| processor.on_start(span) }
|
31
|
+
end
|
32
|
+
|
33
|
+
# Called when a {Span} is ended, if the {Span#recording?}
|
34
|
+
# returns true.
|
35
|
+
#
|
36
|
+
# This method is called synchronously on the execution thread, should
|
37
|
+
# not throw or block the execution thread.
|
38
|
+
#
|
39
|
+
# @param [Span] span the {Span} that just ended.
|
40
|
+
def on_finish(span)
|
41
|
+
@span_processors.each { |processor| processor.on_finish(span) }
|
42
|
+
end
|
43
|
+
|
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.
|
56
|
+
def shutdown
|
57
|
+
@span_processors.each(&:shutdown)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
require 'singleton'
|
8
|
+
|
9
|
+
module OpenTelemetry
|
10
|
+
module SDK
|
11
|
+
module Trace
|
12
|
+
# NoopSpanProcessor is a singleton implementation of the duck type
|
13
|
+
# SpanProcessor that provides synchronous no-op hooks for when a
|
14
|
+
# {Span} is started or when a {Span} is ended.
|
15
|
+
class NoopSpanProcessor
|
16
|
+
include Singleton
|
17
|
+
|
18
|
+
# Called when a {Span} is started, if the {Span#recording?}
|
19
|
+
# returns true.
|
20
|
+
#
|
21
|
+
# This method is called synchronously on the execution thread, should
|
22
|
+
# not throw or block the execution thread.
|
23
|
+
#
|
24
|
+
# @param [Span] span the {Span} that just started.
|
25
|
+
def on_start(span); end
|
26
|
+
|
27
|
+
# Called when a {Span} is ended, if the {Span#recording?}
|
28
|
+
# returns true.
|
29
|
+
#
|
30
|
+
# This method is called synchronously on the execution thread, should
|
31
|
+
# not throw or block the execution thread.
|
32
|
+
#
|
33
|
+
# @param [Span] span the {Span} that just ended.
|
34
|
+
def on_finish(span); end
|
35
|
+
|
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.
|
46
|
+
def shutdown; end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
require 'opentelemetry/sdk/trace/samplers/decision'
|
8
|
+
require 'opentelemetry/sdk/trace/samplers/result'
|
9
|
+
require 'opentelemetry/sdk/trace/samplers/constant_sampler'
|
10
|
+
require 'opentelemetry/sdk/trace/samplers/parent_or_else'
|
11
|
+
require 'opentelemetry/sdk/trace/samplers/probability_sampler'
|
12
|
+
|
13
|
+
module OpenTelemetry
|
14
|
+
module SDK
|
15
|
+
module Trace
|
16
|
+
# The Samplers module contains the sampling logic for OpenTelemetry. The
|
17
|
+
# reference implementation provides a {ProbabilitySampler}, {ALWAYS_ON},
|
18
|
+
# {ALWAYS_OFF}, and {ParentOrElse}.
|
19
|
+
#
|
20
|
+
# Custom samplers can be provided by SDK users. The required interface is:
|
21
|
+
#
|
22
|
+
# should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:) -> Result
|
23
|
+
# description -> String
|
24
|
+
#
|
25
|
+
# Where:
|
26
|
+
#
|
27
|
+
# @param [String] trace_id The trace_id of the {Span} to be created.
|
28
|
+
# @param [OpenTelemetry::Trace::SpanContext] parent_context The
|
29
|
+
# {OpenTelemetry::Trace::SpanContext} of a parent span, typically
|
30
|
+
# extracted from the wire. Can be nil for a root span.
|
31
|
+
# @param [Enumerable<Link>] links A collection of links to be associated
|
32
|
+
# with the {Span} to be created. Can be nil.
|
33
|
+
# @param [String] name Name of the {Span} to be created.
|
34
|
+
# @param [Symbol] kind The {OpenTelemetry::Trace::SpanKind} of the {Span}
|
35
|
+
# to be created. Can be nil.
|
36
|
+
# @param [Hash<String, Object>] attributes Attributes to be attached
|
37
|
+
# to the {Span} to be created. Can be nil.
|
38
|
+
# @return [Result] The sampling result.
|
39
|
+
module Samplers
|
40
|
+
RECORD_AND_SAMPLED = Result.new(decision: Decision::RECORD_AND_SAMPLED)
|
41
|
+
NOT_RECORD = Result.new(decision: Decision::NOT_RECORD)
|
42
|
+
RECORD = Result.new(decision: Decision::RECORD)
|
43
|
+
SAMPLING_HINTS = [Decision::NOT_RECORD, Decision::RECORD, Decision::RECORD_AND_SAMPLED].freeze
|
44
|
+
APPLY_PROBABILITY_TO_SYMBOLS = %i[root_spans root_spans_and_remote_parent all_spans].freeze
|
45
|
+
|
46
|
+
private_constant(:RECORD_AND_SAMPLED, :NOT_RECORD, :RECORD, :SAMPLING_HINTS, :APPLY_PROBABILITY_TO_SYMBOLS)
|
47
|
+
|
48
|
+
# Returns a {Result} with {Decision::RECORD_AND_SAMPLED}.
|
49
|
+
ALWAYS_ON = ConstantSampler.new(result: RECORD_AND_SAMPLED, description: 'AlwaysOnSampler')
|
50
|
+
|
51
|
+
# Returns a {Result} with {Decision::NOT_RECORD}.
|
52
|
+
ALWAYS_OFF = ConstantSampler.new(result: NOT_RECORD, description: 'AlwaysOffSampler')
|
53
|
+
|
54
|
+
# Returns a new sampler. It either respects the parent span's sampling
|
55
|
+
# decision or delegates to delegate_sampler for root spans.
|
56
|
+
#
|
57
|
+
# @param [Sampler] delegate_sampler The sampler to which the sampling
|
58
|
+
# decision is delegated for root spans.
|
59
|
+
def self.parent_or_else(delegate_sampler)
|
60
|
+
ParentOrElse.new(delegate_sampler)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns a new sampler. The probability of sampling a trace is equal
|
64
|
+
# to that of the specified probability.
|
65
|
+
#
|
66
|
+
# @param [Numeric] probability The desired probability of sampling.
|
67
|
+
# Must be within [0.0, 1.0].
|
68
|
+
# @param [optional Boolean] ignore_parent Whether to ignore parent
|
69
|
+
# sampling. Defaults to not ignore parent sampling.
|
70
|
+
# @param [optional Symbol] apply_probability_to Whether to apply
|
71
|
+
# probability sampling to root spans, root spans and remote parents,
|
72
|
+
# or all spans. Allowed values include :root_spans, :root_spans_and_remote_parent,
|
73
|
+
# and :all_spans. Defaults to :root_spans_and_remote_parent.
|
74
|
+
# @raise [ArgumentError] if probability is out of range
|
75
|
+
# @raise [ArgumentError] if apply_probability_to is not one of the allowed symbols
|
76
|
+
def self.probability(probability,
|
77
|
+
ignore_parent: false,
|
78
|
+
apply_probability_to: :root_spans_and_remote_parent)
|
79
|
+
raise ArgumentError, 'probability must be in range [0.0, 1.0]' unless (0.0..1.0).include?(probability)
|
80
|
+
raise ArgumentError, 'apply_probability_to' unless APPLY_PROBABILITY_TO_SYMBOLS.include?(apply_probability_to)
|
81
|
+
|
82
|
+
ProbabilitySampler.new(probability,
|
83
|
+
ignore_parent: ignore_parent,
|
84
|
+
apply_to_remote_parent: apply_probability_to != :root_spans,
|
85
|
+
apply_to_all_spans: apply_probability_to == :all_spans)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
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
|
@@ -0,0 +1,26 @@
|
|
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
|
+
# The Decision module contains a set of constants to be used in the
|
12
|
+
# decision part of a sampling {Result}.
|
13
|
+
module Decision
|
14
|
+
# Decision to not record events and not sample.
|
15
|
+
NOT_RECORD = :__not_record__
|
16
|
+
|
17
|
+
# Decision to record events and not sample.
|
18
|
+
RECORD = :__record__
|
19
|
+
|
20
|
+
# Decision to record events and sample.
|
21
|
+
RECORD_AND_SAMPLED = :__record_and_sampled__
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,43 @@
|
|
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. It either respects the parent span's sampling
|
14
|
+
# decision or delegates to delegate_sampler for root spans.
|
15
|
+
class ParentOrElse
|
16
|
+
def initialize(delegate_sampler)
|
17
|
+
@delegate_sampler = delegate_sampler
|
18
|
+
end
|
19
|
+
|
20
|
+
# @api private
|
21
|
+
#
|
22
|
+
# See {Samplers}.
|
23
|
+
def description
|
24
|
+
"ParentOrElse{#{@delegate_sampler.description}}"
|
25
|
+
end
|
26
|
+
|
27
|
+
# @api private
|
28
|
+
#
|
29
|
+
# See {Samplers}.
|
30
|
+
def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:)
|
31
|
+
if parent_context.nil?
|
32
|
+
@delegate_sampler.should_sample?(trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes)
|
33
|
+
elsif parent_context.trace_flags.sampled?
|
34
|
+
RECORD_AND_SAMPLED
|
35
|
+
else
|
36
|
+
NOT_RECORD
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,64 @@
|
|
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 ProbabilitySampler
|
15
|
+
attr_reader :description
|
16
|
+
|
17
|
+
def initialize(probability, ignore_parent:, apply_to_remote_parent:, apply_to_all_spans:)
|
18
|
+
@probability = probability
|
19
|
+
@id_upper_bound = (probability * (2**64 - 1)).ceil
|
20
|
+
@use_parent_sampled_flag = !ignore_parent
|
21
|
+
@apply_to_remote_parent = apply_to_remote_parent
|
22
|
+
@apply_to_all_spans = apply_to_all_spans
|
23
|
+
@description = format('ProbabilitySampler{%.6f}', probability)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @api private
|
27
|
+
#
|
28
|
+
# See {Samplers}.
|
29
|
+
def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:)
|
30
|
+
# Ignored for sampling decision: links, name, kind, attributes.
|
31
|
+
|
32
|
+
if sample?(trace_id, parent_context)
|
33
|
+
RECORD_AND_SAMPLED
|
34
|
+
else
|
35
|
+
NOT_RECORD
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def sample?(trace_id, parent_context)
|
42
|
+
if parent_context.nil?
|
43
|
+
sample_trace_id?(trace_id)
|
44
|
+
else
|
45
|
+
parent_sampled?(parent_context) || sample_trace_id_for_child?(parent_context, trace_id)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def parent_sampled?(parent_context)
|
50
|
+
@use_parent_sampled_flag && parent_context.trace_flags.sampled?
|
51
|
+
end
|
52
|
+
|
53
|
+
def sample_trace_id_for_child?(parent_context, trace_id)
|
54
|
+
(@apply_to_all_spans || (@apply_to_remote_parent && parent_context.remote?)) && sample_trace_id?(trace_id)
|
55
|
+
end
|
56
|
+
|
57
|
+
def sample_trace_id?(trace_id)
|
58
|
+
@probability == 1.0 || trace_id[8, 8].unpack1('Q>') < @id_upper_bound
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|