class ElasticAPM::OpenTracing::Tracer

rubocop:disable Metrics/ClassLength A custom tracer to use the OpenTracing API with ElasticAPM

Attributes

scope_manager[R]

Public Class Methods

new() click to toggle source
# File lib/elastic_apm/opentracing.rb, line 178
def initialize
  @scope_manager = ScopeManager.new
end

Public Instance Methods

active_span() click to toggle source
# File lib/elastic_apm/opentracing.rb, line 184
def active_span
  scope_manager.active&.span
end
extract(format, carrier) click to toggle source
# File lib/elastic_apm/opentracing.rb, line 286
def extract(format, carrier)
  case format
  when ::OpenTracing::FORMAT_RACK
    ElasticAPM::TraceContext
      .parse(carrier['HTTP_ELASTIC_APM_TRACEPARENT'])
  else
    warn 'Only extraction from HTTP headers via Rack is available'
    nil
  end
rescue ElasticAPM::TraceContext::InvalidTraceparentHeader
  nil
end
inject(span_context, format, carrier) click to toggle source

rubocop:enable Metrics/AbcSize rubocop:enable Metrics/MethodLength, Metrics/ParameterLists

# File lib/elastic_apm/opentracing.rb, line 277
def inject(span_context, format, carrier)
  case format
  when ::OpenTracing::FORMAT_RACK
    carrier['elastic-apm-traceparent'] = span_context.to_header
  else
    warn 'Only injection via HTTP headers and Rack is available'
  end
end
start_active_span( operation_name, child_of: nil, references: nil, start_time: Time.now, tags: {}, ignore_active_scope: false, finish_on_close: true, ** ) { |scope| ... } click to toggle source

rubocop:disable Metrics/MethodLength, Metrics/ParameterLists

# File lib/elastic_apm/opentracing.rb, line 189
def start_active_span(
  operation_name,
  child_of: nil,
  references: nil,
  start_time: Time.now,
  tags: {},
  ignore_active_scope: false,
  finish_on_close: true,
  **
)
  span = start_span(
    operation_name,
    child_of: child_of,
    references: references,
    start_time: start_time,
    tags: tags,
    ignore_active_scope: ignore_active_scope
  )
  scope = scope_manager.activate(span, finish_on_close: finish_on_close)

  if block_given?
    begin
      yield scope
    ensure
      scope.close
    end
  end

  scope
end
start_span( operation_name, child_of: nil, references: nil, start_time: Time.now, tags: {}, ignore_active_scope: false, ** ) click to toggle source

rubocop:disable Metrics/MethodLength, Metrics/ParameterLists rubocop:disable Metrics/AbcSize

# File lib/elastic_apm/opentracing.rb, line 223
def start_span(
  operation_name,
  child_of: nil,
  references: nil,
  start_time: Time.now,
  tags: {},
  ignore_active_scope: false,
  **
)
  span_context = prepare_span_context(
    child_of: child_of,
    references: references,
    ignore_active_scope: ignore_active_scope
  )

  if span_context
    trace_context =
      span_context &&
      span_context.respond_to?(:trace_context) &&
      span_context.trace_context
  end

  elastic_span =
    if ElasticAPM.current_transaction
      ElasticAPM.start_span(
        operation_name,
        trace_context: trace_context
      )
    else
      ElasticAPM.start_transaction(
        operation_name,
        trace_context: trace_context
      )
    end

  # if no Elastic APM agent is running or transaction not sampled
  unless elastic_span
    return ::OpenTracing::Span::NOOP_INSTANCE
  end

  span_context ||=
    SpanContext.from_trace_context(elastic_span.trace_context)

  tags.each do |key, value|
    elastic_span.context.tags[key] = value
  end

  elastic_span.start Util.micros(start_time)

  Span.new(elastic_span, span_context)
end

Private Instance Methods

context_from_active_scope(ignore_active_scope) click to toggle source
# File lib/elastic_apm/opentracing.rb, line 326
def context_from_active_scope(ignore_active_scope)
  if ignore_active_scope
    ElasticAPM.agent&.config&.logger&.warn(
      'ignore_active_scope might lead to unexpeced results'
    )
    return
  end
  @scope_manager.active&.span&.context
end
context_from_child_of(child_of) click to toggle source
# File lib/elastic_apm/opentracing.rb, line 311
def context_from_child_of(child_of)
  return unless child_of
  child_of.respond_to?(:context) ? child_of.context : child_of
end
context_from_references(references) click to toggle source
# File lib/elastic_apm/opentracing.rb, line 316
def context_from_references(references)
  return if !references || references.none?

  child_of = references.find do |reference|
    reference.type == ::OpenTracing::Reference::CHILD_OF
  end

  (child_of || references.first).context
end
prepare_span_context( child_of:, references:, ignore_active_scope: ) click to toggle source
# File lib/elastic_apm/opentracing.rb, line 301
def prepare_span_context(
  child_of:,
  references:,
  ignore_active_scope:
)
  context_from_child_of(child_of) ||
    context_from_references(references) ||
    context_from_active_scope(ignore_active_scope)
end