class Bigcommerce::Lightstep::Tracer

Global tracer

Public Instance Methods

active_span() click to toggle source

Return the active span

@return [::LightStep::Span|NilClass]

# File lib/bigcommerce/lightstep/tracer.rb, line 88
def active_span
  Thread.current[:lightstep_active_span]
end
clear_active_span!() click to toggle source

Clear the active span

# File lib/bigcommerce/lightstep/tracer.rb, line 95
def clear_active_span!
  Thread.current[:lightstep_active_span] = nil
end
enabled?() click to toggle source

@return [Boolean]

# File lib/bigcommerce/lightstep/tracer.rb, line 109
def enabled?
  Bigcommerce::Lightstep.enabled
end
reporter_initialized?() click to toggle source

@return [Boolean]

# File lib/bigcommerce/lightstep/tracer.rb, line 102
def reporter_initialized?
  tracer.instance_variable_defined?(:@reporter) && !tracer.instance_variable_get(:@reporter).nil?
end
start_span(name, context: nil, start_time: nil, tags: nil) { |inner_span| ... } click to toggle source

Start a new span

@param [String] name The operation name for the Span @param [Hash|::LightStep::SpanContext] context (Optional) @param [Time] start_time (Optional) @param [Hash] tags (Optional)

# File lib/bigcommerce/lightstep/tracer.rb, line 34
def start_span(name, context: nil, start_time: nil, tags: nil)
  if enabled?
    # enable the tracer (for fork support)
    tracer.enable
  elsif tracer&.enabled?
    # We are not enabled and the tracer is currently on
    # https://github.com/lightstep/lightstep-tracer-ruby/blob/master/lib/lightstep/tracer.rb#L129-L130
    # we have to set this through instance_variable_set because of a bug in the core lightstep gem which
    # assumes the presence of a reporter, which happens in the initializer, which may not be called
    # because the reporter attempts to flush spans on initialization (which is bad if lightstep isn't
    # present)
    tracer.instance_variable_set(:@enabled, false)
  end

  # find the currently active span
  last_active_span = active_span

  # determine who is the actual parent span
  current_parent = determine_parent(context: context)

  # create new span
  span = ::LightStep.start_span(name, child_of: current_parent, start_time: start_time, tags: tags)

  mark_root_span(span) if active_span.nil?

  # set it as the active span
  self.active_span = span

  # run the process
  result = nil
  begin
    build_context.intercept(span) do |inner_span|
      result = yield inner_span
    end
  rescue StandardError
    span.set_tag('error', true) unless span.tags.key?('error')
    raise
  ensure
    # finish this span if the reporter is initialized
    span.finish if enabled? && reporter_initialized?

    # now set back the parent as the active span
    self.active_span = last_active_span
  end

  # return result
  result
end

Private Instance Methods

active_span=(span) click to toggle source

@param [::LightStep::Span] span

# File lib/bigcommerce/lightstep/tracer.rb, line 140
def active_span=(span)
  Thread.current[:lightstep_active_span] = span
end
build_context() click to toggle source

@return [::Bigcommerce::Lightstep::Interceptors::Context]

# File lib/bigcommerce/lightstep/tracer.rb, line 118
def build_context
  ::Bigcommerce::Lightstep::Interceptors::Context.new
end
determine_parent(context:) click to toggle source

Determine the active parent

@param [Hash|::LightStep::SpanContext] context @return [::LightStep::SpanContext]

# File lib/bigcommerce/lightstep/tracer.rb, line 128
def determine_parent(context:)
  # first attempt to find parent from args, if not, use carrier (headers) to lookup parent
  # 1 = FORMAT_TEXT_MAP (this constant is removed in future lightstep versions)
  current_parent = extract_parent_from_context(context)
  # if no passed in parent, use the active thread parent
  current_parent = active_span if current_parent.nil?
  current_parent
end
extract_parent_from_context(context) click to toggle source

@param [Hash|::LightStep::SpanContext] context @return [::LightStep::SpanContext] @return [NilClass]

# File lib/bigcommerce/lightstep/tracer.rb, line 164
def extract_parent_from_context(context)
  return context if context.is_a?(::LightStep::SpanContext)

  tracer.extract(1, context || {})
rescue StandardError => _e
  # sometimes LightStep, when `start` is not run first, will error here. This protects this until the upstream
  # library can be fixed. We essentially just want to silently no-op here, as this failing simply means there's
  # no context to extract.
  nil
end
mark_root_span(span) click to toggle source

Because LightStep doesn't allow changing the span return class, or adding any arbitrary attributes, we need to do this here to mark what is the “root” span in a service.

# File lib/bigcommerce/lightstep/tracer.rb, line 155
def mark_root_span(span)
  span.instance_variable_set(:@root_span, true)
end
tracer() click to toggle source

@return [::LightStep::Tracer]

# File lib/bigcommerce/lightstep/tracer.rb, line 147
def tracer
  LightStep.instance
end