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.



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/opentelemetry/sdk/trace/span.rb', line 231

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: {'eager' => true})

Lazy example:

span.add_event { OpenTelemetry::Trace::Event.new(name: 'event', attributes: {'eager' => 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, Object>) (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
# 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, Object>

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, Object>)

    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



183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/opentelemetry/sdk/trace/span.rb', line 183

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

#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:



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/opentelemetry/sdk/trace/span.rb', line 208

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