opentelemetry-sdk 0.5.0 → 0.9.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 +4 -4
- data/.yardopts +2 -2
- data/CHANGELOG.md +54 -0
- data/README.md +1 -1
- data/lib/opentelemetry/sdk.rb +2 -1
- data/lib/opentelemetry/sdk/baggage.rb +16 -0
- data/lib/opentelemetry/sdk/{correlation_context → baggage}/builder.rb +5 -5
- data/lib/opentelemetry/sdk/{correlation_context → baggage}/manager.rb +37 -27
- data/lib/opentelemetry/sdk/configurator.rb +41 -20
- data/lib/opentelemetry/sdk/resources/constants.rb +0 -4
- data/lib/opentelemetry/sdk/resources/resource.rb +33 -22
- data/lib/opentelemetry/sdk/trace.rb +1 -0
- 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 +9 -4
- data/lib/opentelemetry/sdk/trace/export/batch_span_processor.rb +84 -36
- data/lib/opentelemetry/sdk/trace/export/console_span_exporter.rb +5 -8
- data/lib/opentelemetry/sdk/trace/export/in_memory_span_exporter.rb +8 -2
- data/lib/opentelemetry/sdk/trace/export/multi_span_exporter.rb +17 -16
- data/lib/opentelemetry/sdk/trace/export/noop_span_exporter.rb +6 -2
- data/lib/opentelemetry/sdk/trace/export/simple_span_processor.rb +22 -4
- data/lib/opentelemetry/sdk/trace/multi_span_processor.rb +30 -6
- data/lib/opentelemetry/sdk/trace/noop_span_processor.rb +17 -3
- data/lib/opentelemetry/sdk/trace/samplers.rb +51 -43
- data/lib/opentelemetry/sdk/trace/samplers/decision.rb +3 -3
- data/lib/opentelemetry/sdk/trace/samplers/parent_based.rb +54 -0
- data/lib/opentelemetry/sdk/trace/samplers/result.rb +3 -3
- data/lib/opentelemetry/sdk/trace/samplers/trace_id_ratio_based.rb +45 -0
- data/lib/opentelemetry/sdk/trace/span.rb +30 -36
- data/lib/opentelemetry/sdk/trace/span_data.rb +16 -3
- data/lib/opentelemetry/sdk/trace/tracer.rb +13 -11
- data/lib/opentelemetry/sdk/trace/tracer_provider.rb +4 -2
- data/lib/opentelemetry/sdk/version.rb +1 -1
- metadata +30 -11
- data/lib/opentelemetry/sdk/correlation_context.rb +0 -16
- data/lib/opentelemetry/sdk/trace/samplers/parent_or_else.rb +0 -43
- data/lib/opentelemetry/sdk/trace/samplers/probability_sampler.rb +0 -64
@@ -26,8 +26,10 @@ module OpenTelemetry
|
|
26
26
|
# not throw or block the execution thread.
|
27
27
|
#
|
28
28
|
# @param [Span] span the {Span} that just started.
|
29
|
-
|
30
|
-
|
29
|
+
# @param [Context] parent_context the parent {Context} of the newly
|
30
|
+
# started span.
|
31
|
+
def on_start(span, parent_context)
|
32
|
+
@span_processors.each { |processor| processor.on_start(span, parent_context) }
|
31
33
|
end
|
32
34
|
|
33
35
|
# Called when a {Span} is ended, if the {Span#recording?}
|
@@ -48,13 +50,35 @@ module OpenTelemetry
|
|
48
50
|
# necessary, such as when using some FaaS providers that may suspend
|
49
51
|
# the process after an invocation, but before the `Processor` exports
|
50
52
|
# the completed spans.
|
51
|
-
|
52
|
-
|
53
|
+
#
|
54
|
+
# @param [optional Numeric] timeout An optional timeout in seconds.
|
55
|
+
# @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
|
56
|
+
# a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
|
57
|
+
def force_flush(timeout: nil)
|
58
|
+
start_time = Time.now
|
59
|
+
results = @span_processors.map do |processor|
|
60
|
+
remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
|
61
|
+
return Export::TIMEOUT if remaining_timeout&.zero?
|
62
|
+
|
63
|
+
processor.force_flush(timeout: remaining_timeout)
|
64
|
+
end
|
65
|
+
results.uniq.max
|
53
66
|
end
|
54
67
|
|
55
68
|
# Called when {TracerProvider#shutdown} is called.
|
56
|
-
|
57
|
-
|
69
|
+
#
|
70
|
+
# @param [optional Numeric] timeout An optional timeout in seconds.
|
71
|
+
# @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
|
72
|
+
# a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
|
73
|
+
def shutdown(timeout: nil)
|
74
|
+
start_time = Time.now
|
75
|
+
results = @span_processors.map do |processor|
|
76
|
+
remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
|
77
|
+
return Export::TIMEOUT if remaining_timeout&.zero?
|
78
|
+
|
79
|
+
processor.shutdown(timeout: remaining_timeout)
|
80
|
+
end
|
81
|
+
results.uniq.max
|
58
82
|
end
|
59
83
|
end
|
60
84
|
end
|
@@ -22,7 +22,9 @@ module OpenTelemetry
|
|
22
22
|
# not throw or block the execution thread.
|
23
23
|
#
|
24
24
|
# @param [Span] span the {Span} that just started.
|
25
|
-
|
25
|
+
# @param [Context] parent_context the parent {Context} of the newly
|
26
|
+
# started span.
|
27
|
+
def on_start(span, parent_context); end
|
26
28
|
|
27
29
|
# Called when a {Span} is ended, if the {Span#recording?}
|
28
30
|
# returns true.
|
@@ -40,10 +42,22 @@ module OpenTelemetry
|
|
40
42
|
# necessary, such as when using some FaaS providers that may suspend
|
41
43
|
# the process after an invocation, but before the `Processor` exports
|
42
44
|
# the completed spans.
|
43
|
-
|
45
|
+
#
|
46
|
+
# @param [optional Numeric] timeout An optional timeout in seconds.
|
47
|
+
# @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
|
48
|
+
# a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
|
49
|
+
def force_flush(timeout: nil)
|
50
|
+
Export::SUCCESS
|
51
|
+
end
|
44
52
|
|
45
53
|
# Called when {TracerProvider#shutdown} is called.
|
46
|
-
|
54
|
+
#
|
55
|
+
# @param [optional Numeric] timeout An optional timeout in seconds.
|
56
|
+
# @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
|
57
|
+
# a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
|
58
|
+
def shutdown(timeout: nil)
|
59
|
+
Export::SUCCESS
|
60
|
+
end
|
47
61
|
end
|
48
62
|
end
|
49
63
|
end
|
@@ -7,15 +7,15 @@
|
|
7
7
|
require 'opentelemetry/sdk/trace/samplers/decision'
|
8
8
|
require 'opentelemetry/sdk/trace/samplers/result'
|
9
9
|
require 'opentelemetry/sdk/trace/samplers/constant_sampler'
|
10
|
-
require 'opentelemetry/sdk/trace/samplers/
|
11
|
-
require 'opentelemetry/sdk/trace/samplers/
|
10
|
+
require 'opentelemetry/sdk/trace/samplers/parent_based'
|
11
|
+
require 'opentelemetry/sdk/trace/samplers/trace_id_ratio_based'
|
12
12
|
|
13
13
|
module OpenTelemetry
|
14
14
|
module SDK
|
15
15
|
module Trace
|
16
16
|
# The Samplers module contains the sampling logic for OpenTelemetry. The
|
17
|
-
# reference implementation provides a {
|
18
|
-
# {ALWAYS_OFF}, and {
|
17
|
+
# reference implementation provides a {TraceIdRatioBased}, {ALWAYS_ON},
|
18
|
+
# {ALWAYS_OFF}, and {ParentBased}.
|
19
19
|
#
|
20
20
|
# Custom samplers can be provided by SDK users. The required interface is:
|
21
21
|
#
|
@@ -25,9 +25,10 @@ module OpenTelemetry
|
|
25
25
|
# Where:
|
26
26
|
#
|
27
27
|
# @param [String] trace_id The trace_id of the {Span} to be created.
|
28
|
-
# @param [OpenTelemetry::
|
29
|
-
# {OpenTelemetry::
|
30
|
-
#
|
28
|
+
# @param [OpenTelemetry::Context] parent_context The
|
29
|
+
# {OpenTelemetry::Context} with a parent {Span}. The {Span}'s
|
30
|
+
# {OpenTelemetry::Trace::SpanContext} may be invalid to indicate a
|
31
|
+
# root span.
|
31
32
|
# @param [Enumerable<Link>] links A collection of links to be associated
|
32
33
|
# with the {Span} to be created. Can be nil.
|
33
34
|
# @param [String] name Name of the {Span} to be created.
|
@@ -37,52 +38,59 @@ module OpenTelemetry
|
|
37
38
|
# to the {Span} to be created. Can be nil.
|
38
39
|
# @return [Result] The sampling result.
|
39
40
|
module Samplers
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
SAMPLING_HINTS = [Decision::
|
44
|
-
APPLY_PROBABILITY_TO_SYMBOLS = %i[root_spans root_spans_and_remote_parent all_spans].freeze
|
41
|
+
RECORD_AND_SAMPLE = Result.new(decision: Decision::RECORD_AND_SAMPLE)
|
42
|
+
DROP = Result.new(decision: Decision::DROP)
|
43
|
+
RECORD_ONLY = Result.new(decision: Decision::RECORD_ONLY)
|
44
|
+
SAMPLING_HINTS = [Decision::DROP, Decision::RECORD_ONLY, Decision::RECORD_AND_SAMPLE].freeze
|
45
45
|
|
46
|
-
private_constant(:
|
46
|
+
private_constant(:RECORD_AND_SAMPLE, :DROP, :RECORD_ONLY, :SAMPLING_HINTS)
|
47
47
|
|
48
|
-
# Returns a {Result} with {Decision::
|
49
|
-
ALWAYS_ON = ConstantSampler.new(result:
|
48
|
+
# Returns a {Result} with {Decision::RECORD_AND_SAMPLE}.
|
49
|
+
ALWAYS_ON = ConstantSampler.new(result: RECORD_AND_SAMPLE, description: 'AlwaysOnSampler')
|
50
50
|
|
51
|
-
# Returns a {Result} with {Decision::
|
52
|
-
ALWAYS_OFF = ConstantSampler.new(result:
|
51
|
+
# Returns a {Result} with {Decision::DROP}.
|
52
|
+
ALWAYS_OFF = ConstantSampler.new(result: DROP, description: 'AlwaysOffSampler')
|
53
53
|
|
54
|
-
# Returns a new sampler. It
|
55
|
-
# decision or delegates to delegate_sampler for root spans.
|
54
|
+
# Returns a new sampler. It delegates to samplers according to the following rules:
|
56
55
|
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
|
60
|
-
|
56
|
+
# | Parent | parent.remote? | parent.trace_flags.sampled? | Invoke sampler |
|
57
|
+
# |--|--|--|--|
|
58
|
+
# | absent | n/a | n/a | root |
|
59
|
+
# | present | true | true | remote_parent_sampled |
|
60
|
+
# | present | true | false | remote_parent_not_sampled |
|
61
|
+
# | present | false | true | local_parent_sampled |
|
62
|
+
# | present | false | false | local_parent_not_sampled |
|
63
|
+
#
|
64
|
+
# @param [Sampler] root The sampler to which the sampling
|
65
|
+
# decision is delegated for spans with no parent (root spans).
|
66
|
+
# @param [optional Sampler] remote_parent_sampled The sampler to which the sampling
|
67
|
+
# decision is delegated for remote parent sampled spans. Defaults to ALWAYS_ON.
|
68
|
+
# @param [optional Sampler] remote_parent_not_sampled The sampler to which the sampling
|
69
|
+
# decision is delegated for remote parent not sampled spans. Defaults to ALWAYS_OFF.
|
70
|
+
# @param [optional Sampler] local_parent_sampled The sampler to which the sampling
|
71
|
+
# decision is delegated for local parent sampled spans. Defaults to ALWAYS_ON.
|
72
|
+
# @param [optional Sampler] local_parent_not_sampled The sampler to which the sampling
|
73
|
+
# decision is delegated for local parent not sampld spans. Defaults to ALWAYS_OFF.
|
74
|
+
def self.parent_based(
|
75
|
+
root:,
|
76
|
+
remote_parent_sampled: ALWAYS_ON,
|
77
|
+
remote_parent_not_sampled: ALWAYS_OFF,
|
78
|
+
local_parent_sampled: ALWAYS_ON,
|
79
|
+
local_parent_not_sampled: ALWAYS_OFF
|
80
|
+
)
|
81
|
+
ParentBased.new(root, remote_parent_sampled, remote_parent_not_sampled, local_parent_sampled, local_parent_not_sampled)
|
61
82
|
end
|
62
83
|
|
63
|
-
# Returns a new sampler. The
|
64
|
-
#
|
84
|
+
# Returns a new sampler. The ratio describes the proportion of the trace ID
|
85
|
+
# space that is sampled.
|
65
86
|
#
|
66
|
-
# @param [Numeric]
|
87
|
+
# @param [Numeric] ratio The desired sampling ratio.
|
67
88
|
# Must be within [0.0, 1.0].
|
68
|
-
# @
|
69
|
-
|
70
|
-
|
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)
|
89
|
+
# @raise [ArgumentError] if ratio is out of range
|
90
|
+
def self.trace_id_ratio_based(ratio)
|
91
|
+
raise ArgumentError, 'ratio must be in range [0.0, 1.0]' unless (0.0..1.0).include?(ratio)
|
81
92
|
|
82
|
-
|
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)
|
93
|
+
TraceIdRatioBased.new(ratio)
|
86
94
|
end
|
87
95
|
end
|
88
96
|
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
|
-
|
15
|
+
DROP = :__drop__
|
16
16
|
|
17
17
|
# Decision to record events and not sample.
|
18
|
-
|
18
|
+
RECORD_ONLY = :__record_only__
|
19
19
|
|
20
20
|
# Decision to record events and sample.
|
21
|
-
|
21
|
+
RECORD_AND_SAMPLE = :__record_and_sample__
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -0,0 +1,54 @@
|
|
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
|
+
parent_span_context = OpenTelemetry::Trace.current_span(parent_context).context
|
41
|
+
delegate = if !parent_span_context.valid?
|
42
|
+
@root
|
43
|
+
elsif parent_span_context.remote?
|
44
|
+
parent_span_context.trace_flags.sampled? ? @remote_parent_sampled : @remote_parent_not_sampled
|
45
|
+
else
|
46
|
+
parent_span_context.trace_flags.sampled? ? @local_parent_sampled : @local_parent_not_sampled
|
47
|
+
end
|
48
|
+
delegate.should_sample?(trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -14,7 +14,7 @@ module OpenTelemetry
|
|
14
14
|
# root span.
|
15
15
|
class Result
|
16
16
|
EMPTY_HASH = {}.freeze
|
17
|
-
DECISIONS = [Decision::
|
17
|
+
DECISIONS = [Decision::RECORD_ONLY, Decision::DROP, Decision::RECORD_AND_SAMPLE].freeze
|
18
18
|
private_constant(:EMPTY_HASH, :DECISIONS)
|
19
19
|
|
20
20
|
# Returns a frozen hash of attributes to be attached span.
|
@@ -39,14 +39,14 @@ module OpenTelemetry
|
|
39
39
|
#
|
40
40
|
# @return [Boolean] sampling decision
|
41
41
|
def sampled?
|
42
|
-
@decision == Decision::
|
42
|
+
@decision == Decision::RECORD_AND_SAMPLE
|
43
43
|
end
|
44
44
|
|
45
45
|
# Returns true if this span should record events, attributes, status, etc.
|
46
46
|
#
|
47
47
|
# @return [Boolean] recording decision
|
48
48
|
def recording?
|
49
|
-
@decision != Decision::
|
49
|
+
@decision != Decision::DROP
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
@@ -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_SAMPLE
|
31
|
+
else
|
32
|
+
DROP
|
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
|
@@ -16,12 +16,16 @@ module OpenTelemetry
|
|
16
16
|
#
|
17
17
|
# rubocop:disable Metrics/ClassLength
|
18
18
|
class Span < OpenTelemetry::Trace::Span
|
19
|
+
DEFAULT_STATUS = OpenTelemetry::Trace::Status.new(OpenTelemetry::Trace::Status::UNSET)
|
20
|
+
|
21
|
+
private_constant(:DEFAULT_STATUS)
|
22
|
+
|
19
23
|
# The following readers are intended for the use of SpanProcessors and
|
20
24
|
# should not be considered part of the public interface for instrumentation.
|
21
|
-
attr_reader :name, :status, :kind, :parent_span_id, :start_timestamp, :end_timestamp, :links, :
|
25
|
+
attr_reader :name, :status, :kind, :parent_span_id, :start_timestamp, :end_timestamp, :links, :resource, :instrumentation_library
|
22
26
|
|
23
27
|
# Return a frozen copy of the current attributes. This is intended for
|
24
|
-
# use of
|
28
|
+
# use of SpanProcessors and should not be considered part of the public
|
25
29
|
# interface for instrumentation.
|
26
30
|
#
|
27
31
|
# @return [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] may be nil.
|
@@ -48,7 +52,7 @@ module OpenTelemetry
|
|
48
52
|
# like events with the #add_event operation and attributes using
|
49
53
|
# #set_attribute.
|
50
54
|
def recording?
|
51
|
-
|
55
|
+
!@ended
|
52
56
|
end
|
53
57
|
|
54
58
|
# Set attribute
|
@@ -59,7 +63,7 @@ module OpenTelemetry
|
|
59
63
|
# meanings.
|
60
64
|
#
|
61
65
|
# @param [String] key
|
62
|
-
# @param [String, Boolean, Numeric] value
|
66
|
+
# @param [String, Boolean, Numeric, Array<String, Numeric, Boolean>] value
|
63
67
|
#
|
64
68
|
# @return [self] returns itself
|
65
69
|
def set_attribute(key, value)
|
@@ -76,37 +80,29 @@ module OpenTelemetry
|
|
76
80
|
end
|
77
81
|
self
|
78
82
|
end
|
83
|
+
alias []= set_attribute
|
79
84
|
|
80
|
-
# Add an Event to a {Span}.
|
81
|
-
# Lazy evaluation is useful when the event attributes are expensive to
|
82
|
-
# build and where the cost can be avoided for an unsampled {Span}.
|
83
|
-
#
|
84
|
-
# Eager example:
|
85
|
-
#
|
86
|
-
# span.add_event(name: 'event', attributes: {'eager' => true})
|
85
|
+
# Add an Event to a {Span}.
|
87
86
|
#
|
88
|
-
#
|
87
|
+
# Example:
|
89
88
|
#
|
90
|
-
# span.add_event
|
89
|
+
# span.add_event('event', attributes: {'eager' => true})
|
91
90
|
#
|
92
91
|
# Note that the OpenTelemetry project
|
93
92
|
# {https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md
|
94
93
|
# documents} certain "standard event names and keys" which have
|
95
94
|
# prescribed semantic meanings.
|
96
95
|
#
|
97
|
-
# @param [
|
98
|
-
# required if a block is not given.
|
96
|
+
# @param [String] name Name of the event.
|
99
97
|
# @param [optional Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
|
100
98
|
# One or more key:value pairs, where the keys must be strings and the
|
101
|
-
# values may be string, boolean or numeric type.
|
102
|
-
# only be used when passing in a name.
|
99
|
+
# values may be string, boolean or numeric type.
|
103
100
|
# @param [optional Time] timestamp Optional timestamp for the event.
|
104
|
-
# This argument should only be used when passing in a name.
|
105
101
|
#
|
106
102
|
# @return [self] returns itself
|
107
|
-
def add_event(name
|
103
|
+
def add_event(name, attributes: nil, timestamp: nil)
|
108
104
|
super
|
109
|
-
event =
|
105
|
+
event = Event.new(name: name, attributes: attributes, timestamp: timestamp || Time.now)
|
110
106
|
|
111
107
|
@mutex.synchronize do
|
112
108
|
if @ended
|
@@ -120,18 +116,18 @@ module OpenTelemetry
|
|
120
116
|
self
|
121
117
|
end
|
122
118
|
|
123
|
-
# Record an
|
119
|
+
# Record an exception during the execution of this span. Multiple exceptions
|
124
120
|
# can be recorded on a span.
|
125
121
|
#
|
126
|
-
# @param [Exception]
|
122
|
+
# @param [Exception] exception The exception to be recorded
|
127
123
|
#
|
128
124
|
# @return [void]
|
129
|
-
def
|
130
|
-
add_event(
|
125
|
+
def record_exception(exception)
|
126
|
+
add_event('exception',
|
131
127
|
attributes: {
|
132
|
-
'
|
133
|
-
'
|
134
|
-
'
|
128
|
+
'exception.type' => exception.class.to_s,
|
129
|
+
'exception.message' => exception.message,
|
130
|
+
'exception.stacktrace' => exception.full_message(highlight: false, order: :top)
|
135
131
|
})
|
136
132
|
end
|
137
133
|
|
@@ -227,7 +223,6 @@ module OpenTelemetry
|
|
227
223
|
@kind,
|
228
224
|
@status,
|
229
225
|
@parent_span_id,
|
230
|
-
@child_count,
|
231
226
|
@total_recorded_attributes,
|
232
227
|
@total_recorded_events,
|
233
228
|
@total_recorded_links,
|
@@ -236,7 +231,7 @@ module OpenTelemetry
|
|
236
231
|
@attributes,
|
237
232
|
@links,
|
238
233
|
@events,
|
239
|
-
@
|
234
|
+
@resource,
|
240
235
|
@instrumentation_library,
|
241
236
|
context.span_id,
|
242
237
|
context.trace_id,
|
@@ -246,7 +241,7 @@ module OpenTelemetry
|
|
246
241
|
end
|
247
242
|
|
248
243
|
# @api private
|
249
|
-
def initialize(context, name, kind, parent_span_id, trace_config, span_processor, attributes, links, start_timestamp,
|
244
|
+
def initialize(context, parent_context, name, kind, parent_span_id, trace_config, span_processor, attributes, links, start_timestamp, resource, instrumentation_library) # rubocop:disable Metrics/AbcSize
|
250
245
|
super(span_context: context)
|
251
246
|
@mutex = Mutex.new
|
252
247
|
@name = name
|
@@ -254,11 +249,10 @@ module OpenTelemetry
|
|
254
249
|
@parent_span_id = parent_span_id.freeze || OpenTelemetry::Trace::INVALID_SPAN_ID
|
255
250
|
@trace_config = trace_config
|
256
251
|
@span_processor = span_processor
|
257
|
-
@
|
252
|
+
@resource = resource
|
258
253
|
@instrumentation_library = instrumentation_library
|
259
254
|
@ended = false
|
260
|
-
@status =
|
261
|
-
@child_count = 0
|
255
|
+
@status = DEFAULT_STATUS
|
262
256
|
@total_recorded_events = 0
|
263
257
|
@total_recorded_links = links&.size || 0
|
264
258
|
@total_recorded_attributes = attributes&.size || 0
|
@@ -268,7 +262,7 @@ module OpenTelemetry
|
|
268
262
|
trim_span_attributes(@attributes)
|
269
263
|
@events = nil
|
270
264
|
@links = trim_links(links, trace_config.max_links_count, trace_config.max_attributes_per_link)
|
271
|
-
@span_processor.on_start(self)
|
265
|
+
@span_processor.on_start(self, parent_context)
|
272
266
|
end
|
273
267
|
|
274
268
|
# TODO: Java implementation overrides finalize to log if a span isn't finished.
|
@@ -300,7 +294,7 @@ module OpenTelemetry
|
|
300
294
|
attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
|
301
295
|
excess = attrs.size - max_attributes_per_link
|
302
296
|
excess.times { attrs.shift } if excess.positive?
|
303
|
-
OpenTelemetry::Trace::Link.new(link.
|
297
|
+
OpenTelemetry::Trace::Link.new(link.span_context, attrs)
|
304
298
|
end.freeze
|
305
299
|
end
|
306
300
|
|
@@ -325,7 +319,7 @@ module OpenTelemetry
|
|
325
319
|
attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
|
326
320
|
excess = attrs.size - max_attributes_per_event
|
327
321
|
excess.times { attrs.shift } if excess.positive?
|
328
|
-
event =
|
322
|
+
event = Event.new(name: event.name, attributes: attrs, timestamp: event.timestamp)
|
329
323
|
end
|
330
324
|
events << event
|
331
325
|
end
|