Class: NewRelic::Agent::OpenTelemetry::Trace::Span

Inherits:
OpenTelemetry::Trace::Span
  • Object
show all
Defined in:
lib/new_relic/agent/opentelemetry/trace/span.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#finishableObject

Returns the value of attribute finishable.



10
11
12
# File 'lib/new_relic/agent/opentelemetry/trace/span.rb', line 10

def finishable
  @finishable
end

#statusObject

Returns the value of attribute status.



11
12
13
# File 'lib/new_relic/agent/opentelemetry/trace/span.rb', line 11

def status
  @status
end

Instance Method Details

#add_attributes(attributes) ⇒ Object



45
46
47
# File 'lib/new_relic/agent/opentelemetry/trace/span.rb', line 45

def add_attributes(attributes)
  NewRelic::Agent.add_custom_span_attributes(attributes)
end

#add_instrumentation_scope(name, version) ⇒ Object



88
89
90
91
92
93
# File 'lib/new_relic/agent/opentelemetry/trace/span.rb', line 88

def add_instrumentation_scope(name, version)
  return unless transaction

  transaction.add_agent_attribute('otel.scope.name', name, AttributeFilter::DST_SPAN_EVENTS)
  transaction.add_agent_attribute('otel.scope.version', version, AttributeFilter::DST_SPAN_EVENTS)
end

#finish(end_timestamp: nil) ⇒ Object



13
14
15
16
17
# File 'lib/new_relic/agent/opentelemetry/trace/span.rb', line 13

def finish(end_timestamp: nil)
  update_client_span
  update_server_span
  finishable&.finish
end

#name=(name) ⇒ Object

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.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/new_relic/agent/opentelemetry/trace/span.rb', line 63

def name=(name)
  if recording?
    # overridden_name has slightly higher precedence than
    # set_transaction_name, but still has a small chance of being
    # overruled by other transaction naming operations if a
    # @frozen_name has already been set. See Transaction#best_name.
    if finishable.is_a?(NewRelic::Agent::Transaction)
      finishable.overridden_name = name
    # New Relic doesn't allow customers to rename segments
    # so this method is just to deal with the OTel APIs that may
    # try to rename a span after it's created.
    elsif finishable.is_a?(NewRelic::Agent::Transaction::Segment)
      finishable.instance_variable_set(:@name, name)
    end
  else
    NewRelic::Agent.logger.warn('Calling name= on a finished OpenTelemetry Span')
  end
end

#record_exception(exception, attributes: nil) ⇒ Object

TODO: do we need to add a condition for NewRelic::Agent::Tracer.capture_segment_error(segment) if finishable is a segment?



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

def record_exception(exception, attributes: nil)
  NewRelic::Agent.notice_error(exception, attributes: attributes)
end

#recording?Boolean

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:

  • (Boolean)


55
56
57
58
59
60
# File 'lib/new_relic/agent/opentelemetry/trace/span.rb', line 55

def recording?
  # in OTel, the recording? method checks for the end time on a span
  # The closest method we have to this is finished? which exists on
  # both transactions and segments.
  !finishable&.finished?
end

#set_attribute(key, value) ⇒ Object



41
42
43
# File 'lib/new_relic/agent/opentelemetry/trace/span.rb', line 41

def set_attribute(key, value)
  NewRelic::Agent.add_custom_span_attributes(key => value)
end

#transactionObject



82
83
84
85
86
# File 'lib/new_relic/agent/opentelemetry/trace/span.rb', line 82

def transaction
  return nil unless finishable

  @transaction ||= finishable.is_a?(Transaction) ? finishable : finishable.transaction
end

#update_client_spanObject



30
31
32
33
34
35
36
37
38
39
# File 'lib/new_relic/agent/opentelemetry/trace/span.rb', line 30

def update_client_span
  if finishable.is_a?(NewRelic::Agent::Transaction::ExternalRequestSegment) &&
      finishable.http_status_code.nil?
    # TODO: Delete duplicate attrs from custom attributes
    finishable_attrs = finishable.attributes.custom_attributes
    code = finishable_attrs['http.response.status_code'] || finishable_attrs['http.status_code']

    finishable.instance_variable_set(:@http_status_code, code) if code
  end
end

#update_server_spanObject

TODO: This method can probably be combined with update_client_span and turned into something more generic when we refactor the way attributes are stored on NR items



22
23
24
25
26
27
28
# File 'lib/new_relic/agent/opentelemetry/trace/span.rb', line 22

def update_server_span
  if finishable.is_a?(NewRelic::Agent::Transaction) && finishable.category == :web
    finishable_segment_attrs = finishable.segments.first.attributes.custom_attributes
    code = finishable_segment_attrs['http.response.status_code'] || finishable_segment_attrs['http.status_code']
    finishable.http_response_code = code if code
  end
end