Class: OpenTelemetry::SDK::Trace::Span

Inherits:
Trace::Span
  • Object
show all
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 (see NoopSpanProcessor for the interface). 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

Instance Method Summary collapse

Constructor Details

#initialize(context, name, kind, parent_span_id, trace_config, span_processor, attributes, links, start_timestamp, library_resource) ⇒ 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.



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/opentelemetry/sdk/trace/span.rb', line 247

def initialize(context, name, kind, parent_span_id, trace_config, span_processor, attributes, links, start_timestamp, library_resource) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  super(span_context: context)
  @mutex = Mutex.new
  @name = name
  @kind = kind
  @parent_span_id = parent_span_id.freeze || OpenTelemetry::Trace::INVALID_SPAN_ID
  @trace_config = trace_config
  @span_processor = span_processor
  @library_resource = library_resource
  @ended = false
  @status = nil
  @child_count = 0
  @total_recorded_events = 0
  @total_recorded_links = links&.size || 0
  @total_recorded_attributes = attributes&.size || 0
  @start_timestamp = start_timestamp
  @end_timestamp = nil
  @attributes = attributes.nil? ? nil : Hash[attributes] # We need a mutable copy of attributes.
  trim_span_attributes(@attributes)
  @events = nil
  @links = trim_links(links, trace_config.max_links_count, trace_config.max_attributes_per_link)
  @span_processor.on_start(self)
end

Instance Attribute Details

#end_timestampObject (readonly)

The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.



21
22
23
# File 'lib/opentelemetry/sdk/trace/span.rb', line 21

def end_timestamp
  @end_timestamp
end

#kindObject (readonly)

The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.



21
22
23
# File 'lib/opentelemetry/sdk/trace/span.rb', line 21

def kind
  @kind
end

#library_resourceObject (readonly)

The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.



21
22
23
# File 'lib/opentelemetry/sdk/trace/span.rb', line 21

def library_resource
  @library_resource
end

The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.



21
22
23
# File 'lib/opentelemetry/sdk/trace/span.rb', line 21

def links
  @links
end

#nameObject

The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.



21
22
23
# File 'lib/opentelemetry/sdk/trace/span.rb', line 21

def name
  @name
end

#parent_span_idObject (readonly)

The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.



21
22
23
# File 'lib/opentelemetry/sdk/trace/span.rb', line 21

def parent_span_id
  @parent_span_id
end

#start_timestampObject (readonly)

The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.



21
22
23
# File 'lib/opentelemetry/sdk/trace/span.rb', line 21

def start_timestamp
  @start_timestamp
end

#statusObject

The following readers are intended for the use of SpanProcessors and should not be considered part of the public interface for instrumentation.



21
22
23
# File 'lib/opentelemetry/sdk/trace/span.rb', line 21

def status
  @status
end

Instance Method Details

#add_event(name: nil, attributes: nil, timestamp: nil) ⇒ self

Add an Event to a OpenTelemetry::SDK::Trace::Span. This can be accomplished eagerly or lazily. Lazy evaluation is useful when the event attributes are expensive to build and where the cost can be avoided for an unsampled OpenTelemetry::SDK::Trace::Span.

Eager example:

span.add_event(name: 'event', attributes: => true)

Lazy example:

span.add_event { OpenTelemetry::Trace::Event.new(name: 'event', attributes: => false) }

Note that the OpenTelemetry project documents certain "standard event names and keys" which have prescribed semantic meanings.

Parameters:

  • name (optional String) (defaults to: nil)

    Optional name of the event. This is required if a block is not given.

  • attributes (optional Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}) (defaults to: nil)

    One or more key:value pairs, where the keys must be strings and the values may be string, boolean or numeric type. This argument should only be used when passing in a name.

  • timestamp (optional Time) (defaults to: nil)

    Optional timestamp for the event. This argument should only be used when passing in a name.

Returns:

  • (self)

    returns itself



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/opentelemetry/sdk/trace/span.rb', line 107

def add_event(name: nil, attributes: nil, timestamp: nil)
  super
  event = block_given? ? yield : OpenTelemetry::Trace::Event.new(name: name, attributes: attributes, timestamp: timestamp || Time.now)

  @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

#attributesHash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}

Return a frozen copy of the current attributes. This is intended for use of SpanProcesses and should not be considered part of the public interface for instrumentation.

Returns:

  • (Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>})

    may be nil.



28
29
30
31
32
# File 'lib/opentelemetry/sdk/trace/span.rb', line 28

def attributes
  # Don't bother synchronizing. Access by SpanProcessors is expected to
  # be serialized.
  @attributes&.clone.freeze
end

#eventsArray<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.

Returns:

  • (Array<Event>)

    may be nil.



39
40
41
42
43
# File 'lib/opentelemetry/sdk/trace/span.rb', line 39

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.

Parameters:

  • end_timestamp (Time) (defaults to: nil)

    optional end timestamp for the span.

Returns:

  • (self)

    returns itself



199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/opentelemetry/sdk/trace/span.rb', line 199

def finish(end_timestamp: nil)
  @mutex.synchronize do
    if @ended
      OpenTelemetry.logger.warn('Calling finish on an ended Span.')
      return self
    end
    @end_timestamp = end_timestamp || Time.now
    @attributes.freeze
    @events.freeze
    @ended = true
  end
  @span_processor.on_finish(self)
  self
end

#record_error(error) ⇒ void

This method returns an undefined value.

Record an error during the execution of this span. Multiple errors can be recorded on a span.

Parameters:

  • error (Exception)

    The error to be recorded



129
130
131
132
133
134
135
136
# File 'lib/opentelemetry/sdk/trace/span.rb', line 129

def record_error(error)
  add_event(name: 'error',
            attributes: {
              'error.type' => error.class.to_s,
              'error.message' => error.message,
              'error.stack' => error.backtrace.join("\n")
            })
end

#recording?Boolean

Return the flag whether this span is recording events

Returns:

  • (Boolean)

    true if this Span is active and recording information like events with the #add_event operation and attributes using

    set_attribute.



50
51
52
# File 'lib/opentelemetry/sdk/trace/span.rb', line 50

def recording?
  true
end

#set_attribute(key, value) ⇒ self

Set attribute

Note that the OpenTelemetry project documents certain "standard attributes" that have prescribed semantic meanings.

Parameters:

  • key (String)
  • value (String, Boolean, Numeric)

Returns:

  • (self)

    returns itself



65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/opentelemetry/sdk/trace/span.rb', line 65

def set_attribute(key, value)
  super
  @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_dataSpanData

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.

Returns:



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/opentelemetry/sdk/trace/span.rb', line 224

def to_span_data
  SpanData.new(
    @name,
    @kind,
    @status,
    @parent_span_id,
    @child_count,
    @total_recorded_attributes,
    @total_recorded_events,
    @total_recorded_links,
    @start_timestamp,
    @end_timestamp,
    @attributes,
    @links,
    @events,
    @library_resource,
    context.span_id,
    context.trace_id,
    context.trace_flags
  )
end