module NewRelic::Agent::Transaction::DistributedTracing

Constants

ACCEPT_EXCEPTION_METRIC
ACCEPT_PARSE_EXCEPTION_METRIC
ACCEPT_PREFIX
ACCEPT_SUCCESS_METRIC
CREATE_EXCEPTION_METRIC
CREATE_PREFIX
CREATE_SUCCESS_METRIC
IGNORE_ACCEPT_AFTER_CREATE_METRIC
IGNORE_ACCEPT_MAJOR_VERSION_METRIC
IGNORE_ACCEPT_NULL_METRIC
IGNORE_ACCEPT_UNTRUSTED_ACCOUNT_METRIC
IGNORE_MULTIPLE_ACCEPT_METRIC
IGNORE_PREFIX
LBRACE
NEWRELIC_TRACE_KEY
NULL_PAYLOAD
SUPPORTABILITY_DISTRIBUTED_TRACE

Attributes

distributed_trace_payload[RW]
distributed_trace_payload_created[W]

Public Instance Methods

accept_distributed_trace_payload(payload) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracing.rb, line 62
def accept_distributed_trace_payload(payload)
  return unless Agent.config[:'distributed_tracing.enabled']

  return false if check_payload_ignored(payload)
  return false unless check_payload_present(payload)
  return false unless payload = decode_payload(payload)
  return false unless check_required_fields_present(payload)
  return false unless check_valid_version(payload)
  return false unless check_trusted_account(payload)

  assign_payload_and_sampling_params(payload)

  NewRelic::Agent.increment_metric(ACCEPT_SUCCESS_METRIC)
  true
rescue => e
  NewRelic::Agent.increment_metric(ACCEPT_EXCEPTION_METRIC)
  NewRelic::Agent.logger.warn('Failed to accept distributed trace payload', e)
  false
end
accept_distributed_tracing_incoming_request(request) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracing.rb, line 38
def accept_distributed_tracing_incoming_request(request)
  return unless Agent.config[:'distributed_tracing.enabled']
  return unless payload = request[NEWRELIC_TRACE_KEY]

  accept_distributed_trace_payload(payload)
end
create_distributed_trace_payload() click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracing.rb, line 49
def create_distributed_trace_payload
  return unless Agent.config[:'distributed_tracing.enabled']

  @distributed_trace_payload_created = true
  payload = DistributedTracePayload.for_transaction(transaction)
  NewRelic::Agent.increment_metric(CREATE_SUCCESS_METRIC)
  payload
rescue => e
  NewRelic::Agent.increment_metric(CREATE_EXCEPTION_METRIC)
  NewRelic::Agent.logger.warn('Failed to create distributed trace payload', e)
  nil
end
distributed_trace_payload_created?() click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracing.rb, line 45
def distributed_trace_payload_created?
  @distributed_trace_payload_created ||= false
end

Private Instance Methods

assign_payload_and_sampling_params(payload) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracing.rb, line 155
def assign_payload_and_sampling_params(payload)
  @distributed_trace_payload = payload
  return if transaction.distributed_tracer.trace_context_header_data

  transaction.trace_id = payload.trace_id
  transaction.distributed_tracer.parent_transaction_id = payload.transaction_id
  transaction.parent_span_id = payload.id

  unless payload.sampled.nil?
    transaction.sampled = payload.sampled
    transaction.priority = payload.priority if payload.priority
  end
end
check_payload_ignored(payload) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracing.rb, line 84
def check_payload_ignored(payload)
  if distributed_trace_payload
    NewRelic::Agent.increment_metric(IGNORE_MULTIPLE_ACCEPT_METRIC)
    return true
  elsif distributed_trace_payload_created?
    NewRelic::Agent.increment_metric(IGNORE_ACCEPT_AFTER_CREATE_METRIC)
    return true
  end
  false
end
check_payload_present(payload) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracing.rb, line 95
def check_payload_present(payload)
  # We might be passed a Ruby `nil` object _or_ the JSON "null"
  if payload.nil? || payload == NULL_PAYLOAD
    NewRelic::Agent.increment_metric(IGNORE_ACCEPT_NULL_METRIC)
    return nil
  end

  payload
end
check_required_fields_present(payload) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracing.rb, line 121
def check_required_fields_present(payload)
  if !payload.version.nil? &&
      !payload.parent_account_id.nil? &&
      !payload.parent_app_id.nil? &&
      !payload.parent_type.nil? &&
      (!payload.transaction_id.nil? || !payload.id.nil?) &&
      !payload.trace_id.nil? &&
      !payload.timestamp.nil?

    true
  else
    NewRelic::Agent.increment_metric(ACCEPT_PARSE_EXCEPTION_METRIC)
    false
  end
end
check_trusted_account(payload) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracing.rb, line 146
def check_trusted_account(payload)
  compare_key = payload.trusted_account_key || payload.parent_account_id
  unless compare_key == NewRelic::Agent.config[:trusted_account_key]
    NewRelic::Agent.increment_metric(IGNORE_ACCEPT_UNTRUSTED_ACCOUNT_METRIC)
    return false
  end
  true
end
check_valid_version(payload) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracing.rb, line 137
def check_valid_version(payload)
  if DistributedTracePayload.major_version_matches?(payload)
    true
  else
    NewRelic::Agent.increment_metric(IGNORE_ACCEPT_MAJOR_VERSION_METRIC)
    false
  end
end
decode_payload(payload) click to toggle source
# File lib/new_relic/agent/transaction/distributed_tracing.rb, line 105
def decode_payload(payload)
  decoded = if payload.start_with?(LBRACE)
    DistributedTracePayload.from_json(payload)
  else
    DistributedTracePayload.from_http_safe(payload)
  end

  return nil unless check_payload_present(decoded)

  decoded
rescue => e
  NewRelic::Agent.increment_metric(ACCEPT_PARSE_EXCEPTION_METRIC)
  NewRelic::Agent.logger.warn('Error parsing distributed trace payload', e)
  nil
end