opentelemetry-sdk 0.5.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -2
  3. data/CHANGELOG.md +54 -0
  4. data/README.md +1 -1
  5. data/lib/opentelemetry/sdk.rb +2 -1
  6. data/lib/opentelemetry/sdk/baggage.rb +16 -0
  7. data/lib/opentelemetry/sdk/{correlation_context → baggage}/builder.rb +5 -5
  8. data/lib/opentelemetry/sdk/{correlation_context → baggage}/manager.rb +37 -27
  9. data/lib/opentelemetry/sdk/configurator.rb +41 -20
  10. data/lib/opentelemetry/sdk/resources/constants.rb +0 -4
  11. data/lib/opentelemetry/sdk/resources/resource.rb +33 -22
  12. data/lib/opentelemetry/sdk/trace.rb +1 -0
  13. data/lib/opentelemetry/sdk/trace/config/trace_config.rb +3 -3
  14. data/lib/opentelemetry/sdk/trace/event.rb +48 -0
  15. data/lib/opentelemetry/sdk/trace/export.rb +9 -4
  16. data/lib/opentelemetry/sdk/trace/export/batch_span_processor.rb +84 -36
  17. data/lib/opentelemetry/sdk/trace/export/console_span_exporter.rb +5 -8
  18. data/lib/opentelemetry/sdk/trace/export/in_memory_span_exporter.rb +8 -2
  19. data/lib/opentelemetry/sdk/trace/export/multi_span_exporter.rb +17 -16
  20. data/lib/opentelemetry/sdk/trace/export/noop_span_exporter.rb +6 -2
  21. data/lib/opentelemetry/sdk/trace/export/simple_span_processor.rb +22 -4
  22. data/lib/opentelemetry/sdk/trace/multi_span_processor.rb +30 -6
  23. data/lib/opentelemetry/sdk/trace/noop_span_processor.rb +17 -3
  24. data/lib/opentelemetry/sdk/trace/samplers.rb +51 -43
  25. data/lib/opentelemetry/sdk/trace/samplers/decision.rb +3 -3
  26. data/lib/opentelemetry/sdk/trace/samplers/parent_based.rb +54 -0
  27. data/lib/opentelemetry/sdk/trace/samplers/result.rb +3 -3
  28. data/lib/opentelemetry/sdk/trace/samplers/trace_id_ratio_based.rb +45 -0
  29. data/lib/opentelemetry/sdk/trace/span.rb +30 -36
  30. data/lib/opentelemetry/sdk/trace/span_data.rb +16 -3
  31. data/lib/opentelemetry/sdk/trace/tracer.rb +13 -11
  32. data/lib/opentelemetry/sdk/trace/tracer_provider.rb +4 -2
  33. data/lib/opentelemetry/sdk/version.rb +1 -1
  34. metadata +30 -11
  35. data/lib/opentelemetry/sdk/correlation_context.rb +0 -16
  36. data/lib/opentelemetry/sdk/trace/samplers/parent_or_else.rb +0 -43
  37. 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
- def on_start(span)
30
- @span_processors.each { |processor| processor.on_start(span) }
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
- def force_flush
52
- @span_processors.each(&:force_flush)
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
- def shutdown
57
- @span_processors.each(&:shutdown)
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
- def on_start(span); end
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
- def force_flush; end
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
- def shutdown; end
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/parent_or_else'
11
- require 'opentelemetry/sdk/trace/samplers/probability_sampler'
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 {ProbabilitySampler}, {ALWAYS_ON},
18
- # {ALWAYS_OFF}, and {ParentOrElse}.
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::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.
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
- 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
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(:RECORD_AND_SAMPLED, :NOT_RECORD, :RECORD, :SAMPLING_HINTS, :APPLY_PROBABILITY_TO_SYMBOLS)
46
+ private_constant(:RECORD_AND_SAMPLE, :DROP, :RECORD_ONLY, :SAMPLING_HINTS)
47
47
 
48
- # Returns a {Result} with {Decision::RECORD_AND_SAMPLED}.
49
- ALWAYS_ON = ConstantSampler.new(result: RECORD_AND_SAMPLED, description: 'AlwaysOnSampler')
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::NOT_RECORD}.
52
- ALWAYS_OFF = ConstantSampler.new(result: NOT_RECORD, description: 'AlwaysOffSampler')
51
+ # Returns a {Result} with {Decision::DROP}.
52
+ ALWAYS_OFF = ConstantSampler.new(result: DROP, description: 'AlwaysOffSampler')
53
53
 
54
- # Returns a new sampler. It either respects the parent span's sampling
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
- # @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)
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 probability of sampling a trace is equal
64
- # to that of the specified probability.
84
+ # Returns a new sampler. The ratio describes the proportion of the trace ID
85
+ # space that is sampled.
65
86
  #
66
- # @param [Numeric] probability The desired probability of sampling.
87
+ # @param [Numeric] ratio The desired sampling ratio.
67
88
  # 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)
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
- 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)
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
- NOT_RECORD = :__not_record__
15
+ DROP = :__drop__
16
16
 
17
17
  # Decision to record events and not sample.
18
- RECORD = :__record__
18
+ RECORD_ONLY = :__record_only__
19
19
 
20
20
  # Decision to record events and sample.
21
- RECORD_AND_SAMPLED = :__record_and_sampled__
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::RECORD, Decision::NOT_RECORD, Decision::RECORD_AND_SAMPLED].freeze
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::RECORD_AND_SAMPLED
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::NOT_RECORD
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, :library_resource, :instrumentation_library
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 SpanProcesses and should not be considered part of the public
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
- true
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}. This can be accomplished eagerly or lazily.
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
- # Lazy example:
87
+ # Example:
89
88
  #
90
- # span.add_event { OpenTelemetry::Trace::Event.new(name: 'event', attributes: {'eager' => false}) }
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 [optional String] name Optional name of the event. This is
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. This argument should
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: nil, attributes: nil, timestamp: nil)
103
+ def add_event(name, attributes: nil, timestamp: nil)
108
104
  super
109
- event = block_given? ? yield : OpenTelemetry::Trace::Event.new(name: name, attributes: attributes, timestamp: timestamp || Time.now)
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 error during the execution of this span. Multiple errors
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] error The error to be recorded
122
+ # @param [Exception] exception The exception to be recorded
127
123
  #
128
124
  # @return [void]
129
- def record_error(error)
130
- add_event(name: 'error',
125
+ def record_exception(exception)
126
+ add_event('exception',
131
127
  attributes: {
132
- 'error.type' => error.class.to_s,
133
- 'error.message' => error.message,
134
- 'error.stack' => error.backtrace.join("\n")
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
- @library_resource,
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, library_resource, instrumentation_library) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
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
- @library_resource = library_resource
252
+ @resource = resource
258
253
  @instrumentation_library = instrumentation_library
259
254
  @ended = false
260
- @status = nil
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.context, attrs)
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 = OpenTelemetry::Trace::Event.new(name: event.name, attributes: attrs, timestamp: event.timestamp)
322
+ event = Event.new(name: event.name, attributes: attrs, timestamp: event.timestamp)
329
323
  end
330
324
  events << event
331
325
  end