Class: OpenTelemetry::SDK::Trace::Span
- Inherits:
-
Trace::Span
- Object
- Trace::Span
- OpenTelemetry::SDK::Trace::Span
- Defined in:
- lib/opentelemetry/sdk/trace/span.rb
Overview
Implementation of Trace::Span that records trace events.
This implementation includes reader methods intended to allow access to internal state by SpanProcessors. Instrumentation should use the API provided by Trace::Span and should consider Span to be write-only.
rubocop:disable Metrics/ClassLength
Instance Attribute Summary collapse
-
#end_timestamp ⇒ Object
readonly
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
-
#instrumentation_scope ⇒ Object
(also: #instrumentation_library)
readonly
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
-
#kind ⇒ Object
readonly
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
-
#links ⇒ Object
readonly
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
-
#name ⇒ Object
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
-
#parent_span_id ⇒ Object
readonly
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
-
#resource ⇒ Object
readonly
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
-
#start_timestamp ⇒ Object
readonly
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
-
#status ⇒ Object
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
Instance Method Summary collapse
-
#add_attributes(attributes) ⇒ self
Add attributes.
-
#add_event(name, attributes: nil, timestamp: nil) ⇒ self
Add an Event to a Span.
-
#add_link(link) ⇒ self
Add a link to a Span.
-
#attributes ⇒ Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}
Return a frozen copy of the current attributes.
-
#events ⇒ Array<Event>
Return a frozen copy of the current events.
-
#finish(end_timestamp: nil) ⇒ self
Finishes the Span.
-
#initialize(context, parent_context, parent_span, name, kind, parent_span_id, span_limits, span_processors, attributes, links, start_timestamp, resource, instrumentation_scope) ⇒ Span
constructor
private
A new instance of Span.
-
#record_exception(exception, attributes: nil) ⇒ void
Record an exception during the execution of this span.
-
#recording? ⇒ Boolean
Return the flag whether this span is recording events.
-
#set_attribute(key, value) ⇒ self
(also: #[]=)
Set attribute.
-
#to_span_data ⇒ SpanData
private
Returns a SpanData containing a snapshot of the Span fields.
Constructor Details
#initialize(context, parent_context, parent_span, name, kind, parent_span_id, span_limits, span_processors, attributes, links, start_timestamp, resource, instrumentation_scope) ⇒ Span
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Span.
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 320 def initialize(context, parent_context, parent_span, name, kind, parent_span_id, span_limits, span_processors, attributes, links, , resource, instrumentation_scope) # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity super(span_context: context) @mutex = Mutex.new @name = name @kind = kind @parent_span_id = parent_span_id.freeze || OpenTelemetry::Trace::INVALID_SPAN_ID @span_limits = span_limits @span_processors = span_processors @resource = resource @instrumentation_scope = instrumentation_scope @ended = false @status = DEFAULT_STATUS @total_recorded_events = 0 @total_recorded_links = links&.size || 0 @total_recorded_attributes = attributes&.size || 0 @attributes = attributes trim_span_attributes(@attributes) @events = nil @links = trim_links(links, span_limits.link_count_limit, span_limits.link_attribute_count_limit) # Times are hard. Whenever an explicit timestamp is provided # (for Events or for the Span start_timestamp or end_timestamp), # we use that as the recorded timestamp. An implicit Event timestamp # and end_timestamp is computed as a monotonic clock offset from # the realtime start_timestamp. The realtime start_timestamp is # computed as a monotonic clock offset from the realtime # start_timestamp of its parent span, if available, or it is # fetched from the realtime system clock. # # We therefore have 3 start timestamps. The first two are used # internally (and by child spans) to compute other timestamps. # The last is the start timestamp actually recorded in the # SpanData. @monotonic_start_timestamp = monotonic_now @realtime_start_timestamp = if parent_span.recording? relative_realtime(parent_span., parent_span., @monotonic_start_timestamp) else realtime_now end @start_timestamp = if time_in_nanoseconds() else @realtime_start_timestamp end @end_timestamp = nil @span_processors.each { |processor| processor.on_start(self, parent_context) } end |
Instance Attribute Details
#end_timestamp ⇒ Object (readonly)
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
26 27 28 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 26 def @end_timestamp end |
#instrumentation_scope ⇒ Object (readonly) Also known as: instrumentation_library
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
26 27 28 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 26 def instrumentation_scope @instrumentation_scope end |
#kind ⇒ Object (readonly)
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
26 27 28 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 26 def kind @kind end |
#links ⇒ Object (readonly)
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
26 27 28 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 26 def links @links end |
#name ⇒ Object
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
26 27 28 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 26 def name @name end |
#parent_span_id ⇒ Object (readonly)
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
26 27 28 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 26 def parent_span_id @parent_span_id end |
#resource ⇒ Object (readonly)
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
26 27 28 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 26 def resource @resource end |
#start_timestamp ⇒ Object (readonly)
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
26 27 28 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 26 def @start_timestamp end |
#status ⇒ Object
The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.
26 27 28 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 26 def status @status end |
Instance Method Details
#add_attributes(attributes) ⇒ self
Add attributes
Note that the OpenTelemetry project documents certain “standard attributes” that have prescribed semantic meanings.
107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 107 def add_attributes(attributes) @mutex.synchronize do if @ended OpenTelemetry.logger.warn('Calling add_attributes on an ended Span.') else @attributes ||= {} @attributes.merge!(attributes) trim_span_attributes(@attributes) @total_recorded_attributes += attributes.size end end self end |
#add_event(name, attributes: nil, timestamp: nil) ⇒ self
Add an Event to a OpenTelemetry::SDK::Trace::Span.
Example:
span.add_event('event', attributes: => true)
Note that the OpenTelemetry project documents certain “standard event names and keys” which have prescribed semantic meanings.
170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 170 def add_event(name, attributes: nil, timestamp: nil) event = Event.new(name, truncate_attribute_values(attributes, @span_limits.event_attribute_length_limit), ()) @mutex.synchronize do if @ended OpenTelemetry.logger.warn('Calling add_event on an ended Span.') else @events ||= [] @events = append_event(@events, event) @total_recorded_events += 1 end end self end |
#add_link(link) ⇒ self
Add a link to a OpenTelemetry::SDK::Trace::Span.
Adding links at span creation using the links
option is preferred to calling add_link later, because head sampling decisions can only consider information present during span creation.
Example:
span.add_link(OpenTelemetry::Trace::Link.new(span_to_link_from.context))
Note that the OpenTelemetry project documents certain “standard attributes” that have prescribed semantic meanings.
139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 139 def add_link(link) @mutex.synchronize do if @ended OpenTelemetry.logger.warn('Calling add_link on an ended Span.') else @links ||= [] @links = trim_links(@links << link, @span_limits.link_count_limit, @span_limits.link_attribute_count_limit) @total_recorded_links += 1 end end self end |
#attributes ⇒ Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}
Return a frozen copy of the current attributes. This is intended for use of SpanProcessors and should not be considered part of the public interface for instrumentation.
39 40 41 42 43 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 39 def attributes # Don't bother synchronizing. Access by SpanProcessors is expected to # be serialized. @attributes&.clone.freeze end |
#events ⇒ Array<Event>
Return a frozen copy of the current events. This is intended for use of SpanProcessors and should not be considered part of the public interface for instrumentation.
50 51 52 53 54 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 50 def events # Don't bother synchronizing. Access by SpanProcessors is expected to # be serialized. @events&.clone.freeze end |
#finish(end_timestamp: nil) ⇒ self
Finishes the Span
Implementations MUST ignore all subsequent calls to #finish (there might be exceptions when Tracer is streaming event and has no mutable state associated with the Span).
Call to #finish MUST not have any effects on child spans. Those may still be running and can be ended later.
This API MUST be non-blocking*.
(*) not actually non-blocking. In particular, it synchronizes on an internal mutex, which will typically be uncontended, and Export::BatchSpanProcessor will also synchronize on a mutex, if that processor is used.
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 267 def finish(end_timestamp: nil) @mutex.synchronize do if @ended OpenTelemetry.logger.warn('Calling finish on an ended Span.') return self end @end_timestamp = () @span_processors.each do |processor| processor.on_finishing(self) if processor.respond_to?(:on_finishing) end @attributes = validated_attributes(@attributes).freeze @events.freeze @links.freeze @ended = true end @span_processors.each { |processor| processor.on_finish(self) } self end |
#record_exception(exception, attributes: nil) ⇒ void
This method returns an undefined value.
Record an exception during the execution of this span. Multiple exceptions can be recorded on a span.
195 196 197 198 199 200 201 202 203 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 195 def record_exception(exception, attributes: nil) event_attributes = { 'exception.type' => exception.class.to_s, 'exception.message' => exception., 'exception.stacktrace' => exception.(highlight: false, order: :top).encode('UTF-8', invalid: :replace, undef: :replace, replace: '�') } event_attributes.merge!(attributes) unless attributes.nil? add_event('exception', attributes: event_attributes) end |
#recording? ⇒ Boolean
Return the flag whether this span is recording events
61 62 63 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 61 def recording? !@ended end |
#set_attribute(key, value) ⇒ self Also known as: []=
Set attribute
Note that the OpenTelemetry project documents certain “standard attributes” that have prescribed semantic meanings.
79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 79 def set_attribute(key, value) @mutex.synchronize do if @ended OpenTelemetry.logger.warn('Calling set_attribute on an ended Span.') else @attributes ||= {} @attributes[key] = value trim_span_attributes(@attributes) @total_recorded_attributes += 1 end end self end |
#to_span_data ⇒ SpanData
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a SpanData containing a snapshot of the Span fields. It is assumed that the Span has been finished, and that no further modifications will be made to the Span.
This method should be called only from a SpanProcessor prior to calling the SpanExporter.
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/opentelemetry/sdk/trace/span.rb', line 296 def to_span_data SpanData.new( @name, @kind, @status, @parent_span_id, @total_recorded_attributes, @total_recorded_events, @total_recorded_links, @start_timestamp, @end_timestamp, @attributes, @links, @events, @resource, @instrumentation_scope, context.span_id, context.trace_id, context.trace_flags, context.tracestate ) end |