class NewRelic::Agent::Transaction::DistributedTracer

Attributes

parent_transaction_id[RW]
transaction[R]

Public Class Methods

new(transaction) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 53
def initialize(transaction)
  @transaction = transaction
end

Public Instance Methods

accept_incoming_request(request, transport_type = nil) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 28
def accept_incoming_request(request, transport_type = nil)
  accept_incoming_transport_type(request, transport_type)
  if trace_parent_header_present?(request)
    accept_trace_context_incoming_request(request)
  else
    accept_distributed_tracing_incoming_request(request)
  end
end
accept_incoming_transport_type(request, transport_type) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 45
def accept_incoming_transport_type(request, transport_type)
  if transport_type.to_s == NewRelic::EMPTY_STR
    @caller_transport_type = DistributedTraceTransportType.for_rack_request(request)
  else
    @caller_transport_type = DistributedTraceTransportType.from(transport_type)
  end
end
accept_transport_type_from_api(value) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 41
def accept_transport_type_from_api(value)
  @caller_transport_type = DistributedTraceTransportType.from(value)
end
append_payload(payload) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 62
def append_payload(payload)
  append_cat_info(payload)
  DistributedTraceAttributes.copy_from_transaction( \
    transaction,
    trace_state_payload || distributed_trace_payload,
    payload
  )
end
assign_intrinsics() click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 94
def assign_intrinsics
  if dt_enabled?
    DistributedTraceAttributes.copy_to_attributes(transaction.payload, transaction.attributes)
  elsif is_cross_app?
    assign_cross_app_intrinsics
  end
end
caller_transport_type() click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 37
def caller_transport_type
  @caller_transport_type ||= 'Unknown'
end
consume_message_headers(headers, tracer_state, transport_type) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 85
def consume_message_headers(headers, tracer_state, transport_type)
  log_request_headers(headers, 'INCOMING')
  consume_message_distributed_tracing_headers(headers, transport_type)
  consume_message_cross_app_tracing_headers(headers, tracer_state)
  consume_message_synthetics_headers(headers)
rescue => e
  NewRelic::Agent.logger.error('Error in consume_message_headers', e)
end
insert_cat_headers(headers) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 110
def insert_cat_headers(headers)
  return unless CrossAppTracing.cross_app_enabled?

  @is_cross_app_caller = true
  insert_message_headers(headers,
    transaction.guid,
    cat_trip_id,
    cat_path_hash,
    transaction.raw_synthetics_header)
end
insert_distributed_trace_header(headers) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 102
def insert_distributed_trace_header(headers)
  return unless dt_enabled?
  return if Agent.config[:'exclude_newrelic_header']

  payload = create_distributed_trace_payload
  headers[NewRelic::NEWRELIC_KEY] = payload.http_safe if payload
end
insert_headers(headers) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 76
def insert_headers(headers)
  return unless NewRelic::Agent.agent.connected?

  insert_trace_context_header(headers)
  insert_distributed_trace_header(headers)
  insert_cross_app_header(headers)
  log_request_headers(headers)
end
log_request_headers(headers, direction = 'OUTGOING') click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 71
def log_request_headers(headers, direction = 'OUTGOING')
  printed_headers = headers.is_a?(NewRelic::Agent::HTTPClients::AbstractRequest) ? headers.headers : headers
  NewRelic::Agent.logger.debug("#{direction} REQUEST HEADERS: #{printed_headers}")
end
parent_guid() click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 20
def parent_guid
  if trace_context_header_data
    trace_context_header_data.parent_id
  elsif distributed_trace_payload
    distributed_trace_payload.id
  end
end
record_metrics() click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 57
def record_metrics
  record_cross_app_metrics
  DistributedTraceMetrics.record_metrics_for_transaction(transaction)
end

Private Instance Methods

accept_cross_app_payload(headers, tracer_state) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 163
def accept_cross_app_payload(headers, tracer_state)
  encoded_id = headers[CrossAppTracing::NR_MESSAGE_BROKER_ID_HEADER]
  decoded_id = encoded_id.nil? ? EMPTY_STRING : deobfuscate(encoded_id)

  return unless CrossAppTracing.trusted_valid_cross_app_id?(decoded_id)

  txn_header = headers[CrossAppTracing::NR_MESSAGE_BROKER_TXN_HEADER]
  txn_info = ::JSON.load(deobfuscate(txn_header))
  payload = CrossAppPayload.new(decoded_id, transaction, txn_info)

  @cross_app_payload = payload
rescue => e
  NewRelic::Agent.logger.debug("Failure deserializing encoded header in #{self.class}, #{e.class}, #{e.message}")
  nil
end
consume_message_cross_app_tracing_headers(headers, tracer_state) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 155
def consume_message_cross_app_tracing_headers(headers, tracer_state)
  return unless CrossAppTracing.cross_app_enabled?
  return unless CrossAppTracing.message_has_crossapp_request_header?(headers)

  accept_cross_app_payload(headers, tracer_state)
  CrossAppTracing.assign_intrinsic_transaction_attributes(tracer_state)
end
consume_message_distributed_tracing_headers(headers, transport_type) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 142
def consume_message_distributed_tracing_headers(headers, transport_type)
  return unless dt_enabled?

  accept_incoming_transport_type(headers, transport_type)

  newrelic_trace_key = NewRelic::CANDIDATE_NEWRELIC_KEYS.detect do |key|
    headers.has_key?(key)
  end
  return unless newrelic_trace_key && (payload = headers[newrelic_trace_key])

  accept_distributed_trace_payload(payload)
end
consume_message_synthetics_headers(headers) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 127
def consume_message_synthetics_headers(headers)
  synthetics_header = headers[CrossAppTracing::NR_MESSAGE_BROKER_SYNTHETICS_HEADER]
  if synthetics_header and
      incoming_payload = ::JSON.load(deobfuscate(synthetics_header)) and
      SyntheticsMonitor.is_valid_payload?(incoming_payload) and
      SyntheticsMonitor.is_supported_version?(incoming_payload) and
      SyntheticsMonitor.is_trusted?(incoming_payload)

    transaction.raw_synthetics_header = synthetics_header
    transaction.synthetics_payload = incoming_payload
  end
rescue => e
  NewRelic::Agent.logger.error('Error in consume_message_synthetics_header', e)
end
deobfuscate(message) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 179
def deobfuscate(message)
  CrossAppTracing.obfuscator.deobfuscate(message)
end
dt_enabled?() click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracer.rb, line 123
def dt_enabled?
  Agent.config[:'distributed_tracing.enabled']
end