module NewRelic::Agent::Transaction::TraceContext

Constants

ACCEPT_EXCEPTION_METRIC
ACCEPT_PREFIX
ACCEPT_SUCCESS_METRIC
CREATE_EXCEPTION_METRIC
CREATE_PREFIX
CREATE_SUCCESS_METRIC
IGNORE_ACCEPT_AFTER_CREATE_METRIC
IGNORE_MULTIPLE_ACCEPT_METRIC
INVALID_TRACESTATE_PAYLOAD_METRIC
NO_NR_ENTRY_TRACESTATE_METRIC
SUPPORTABILITY_PREFIX
TRACESTATE_PREFIX

Attributes

trace_context_header_data[RW]
trace_state_payload[R]

Public Instance Methods

accept_trace_context(header_data) click to toggle source
# File lib/new_relic/agent/transaction/trace_context.rb, line 128
def accept_trace_context(header_data)
  return if ignore_trace_context?

  @trace_context_header_data = header_data
  transaction.trace_id = header_data.trace_id
  transaction.parent_span_id = header_data.parent_id

  return false unless payload = assign_trace_state_payload

  transaction.distributed_tracer.parent_transaction_id = payload.transaction_id

  unless payload.sampled.nil?
    transaction.sampled = payload.sampled
    transaction.priority = payload.priority if payload.priority
  end
  NewRelic::Agent.increment_metric(ACCEPT_SUCCESS_METRIC)
  true
rescue => e
  NewRelic::Agent.increment_metric(ACCEPT_EXCEPTION_METRIC)
  NewRelic::Agent.logger.warn('Failed to accept trace context payload', e)
  false
end
assign_trace_state_payload() click to toggle source
# File lib/new_relic/agent/transaction/trace_context.rb, line 115
def assign_trace_state_payload
  payload = @trace_context_header_data.trace_state_payload
  unless payload
    NewRelic::Agent.increment_metric(NO_NR_ENTRY_TRACESTATE_METRIC)
    return false
  end
  unless payload.valid?
    NewRelic::Agent.increment_metric(INVALID_TRACESTATE_PAYLOAD_METRIC)
    return false
  end
  @trace_state_payload = payload
end
create_trace_state() click to toggle source
# File lib/new_relic/agent/transaction/trace_context.rb, line 80
def create_trace_state
  entry_key = AccountHelpers.trace_state_entry_key.dup
  payload = create_trace_state_payload

  if payload
    entry = NewRelic::Agent::DistributedTracing::TraceContext.create_trace_state_entry( \
      entry_key,
      payload.to_s
    )
  else
    entry = NewRelic::EMPTY_STR
  end

  trace_context_header_data ? trace_context_header_data.trace_state(entry) : entry
end
create_trace_state_payload() click to toggle source
# File lib/new_relic/agent/transaction/trace_context.rb, line 96
def create_trace_state_payload
  unless Agent.config[:'distributed_tracing.enabled']
    NewRelic::Agent.logger.warn('Not configured to create WC3 trace context payload')
    return
  end

  span_guid = Agent.config[:'span_events.enabled'] ? transaction.current_segment.guid : nil
  transaction_guid = Agent.config[:'transaction_events.enabled'] ? transaction.guid : nil

  TraceContextPayload.create( \
    parent_account_id: Agent.config[:account_id],
    parent_app_id: Agent.config[:primary_application_id],
    transaction_id: transaction_guid,
    sampled: transaction.sampled?,
    priority: float!(transaction.priority, NewRelic::PRIORITY_PRECISION),
    id: span_guid
  )
end
ignore_trace_context?() click to toggle source
# File lib/new_relic/agent/transaction/trace_context.rb, line 151
def ignore_trace_context?
  if trace_context_header_data
    NewRelic::Agent.increment_metric(IGNORE_MULTIPLE_ACCEPT_METRIC)
    return true
  elsif trace_context_inserted?
    NewRelic::Agent.increment_metric(IGNORE_ACCEPT_AFTER_CREATE_METRIC)
    return true
  end
  false
end
insert_trace_context_header(header, format = NewRelic::FORMAT_NON_RACK) click to toggle source
# File lib/new_relic/agent/transaction/trace_context.rb, line 58
def insert_trace_context_header(header, format = NewRelic::FORMAT_NON_RACK)
  return unless Agent.config[:'distributed_tracing.enabled']

  NewRelic::Agent::DistributedTracing::TraceContext.insert( \
    format: format,
    carrier: header,
    trace_id: transaction.trace_id.rjust(32, '0').downcase,
    parent_id: transaction.current_segment.guid,
    trace_flags: transaction.sampled? ? 0x1 : 0x0,
    trace_state: create_trace_state
  )

  @trace_context_inserted = true

  NewRelic::Agent.increment_metric(CREATE_SUCCESS_METRIC)
  true
rescue Exception => e
  NewRelic::Agent.increment_metric(CREATE_EXCEPTION_METRIC)
  NewRelic::Agent.logger.warn('Failed to create trace context payload', e)
  false
end
trace_context_inserted?() click to toggle source
# File lib/new_relic/agent/transaction/trace_context.rb, line 162
def trace_context_inserted?
  @trace_context_inserted ||= false
end
trace_parent_header_present?(request) click to toggle source
# File lib/new_relic/agent/transaction/trace_context.rb, line 42
def trace_parent_header_present?(request)
  request[NewRelic::HTTP_TRACEPARENT_KEY]
end

Private Instance Methods

accept_trace_context_incoming_request(request) click to toggle source
# File lib/new_relic/agent/transaction/trace_context.rb, line 46
def accept_trace_context_incoming_request(request)
  header_data = NewRelic::Agent::DistributedTracing::TraceContext.parse(
    format: NewRelic::FORMAT_RACK,
    carrier: request,
    trace_state_entry_key: AccountHelpers.trace_state_entry_key
  )
  return if header_data.nil?

  accept_trace_context(header_data)
end