class Instana::Tracer

Public Class Methods

method_missing(method, *args, &block) click to toggle source
Calls superclass method
# File lib/instana/tracer.rb, line 11
def method_missing(method, *args, &block)
  if ::Instana.tracer.respond_to?(method)
    ::Instana.tracer.send(method, *args, &block)
  else
    super
  end
end
new(logger: Instana.logger) click to toggle source
# File lib/instana/tracer.rb, line 20
def initialize(logger: Instana.logger)
  @current_span = Concurrent::ThreadLocalVar.new
  @logger = logger
end

Public Instance Methods

clear!() click to toggle source

Used in the test suite, this resets the tracer to non-tracing state.

# File lib/instana/tracer.rb, line 303
def clear!
  self.current_span = nil
end
context() click to toggle source

Retrieve the current context of the tracer.

@return [SpanContext] or nil if not tracing

# File lib/instana/tracer.rb, line 296
def context
  return unless self.current_span
  self.current_span.context
end
current_span() click to toggle source

@return [Instana::Span, NilClass] the current active span or nil if we are not tracing

# File lib/instana/tracer.rb, line 26
def current_span
  @current_span.value
end
current_span=(v) click to toggle source

@param [Instana::Span, NilClas] v the new current span Set the value of the current span

# File lib/instana/tracer.rb, line 32
def current_span=(v)
  @current_span.value = v
end
log_async_entry(name, kvs) click to toggle source

Starts a new asynchronous span on the current trace.

@param name [String] the name of the span to create @param kvs [Hash] list of key values to be reported in the span

@return [Hash] the context: Trace ID and Span ID in the form of

:trace_id => 12345
:span_id => 12345
# File lib/instana/tracer.rb, line 224
def log_async_entry(name, kvs)
  return unless self.current_span

  new_span = Span.new(name, parent_ctx: self.current_span)
  new_span.set_tags(kvs) unless kvs.empty?
  new_span
end
log_async_error(e, span) click to toggle source

Add an error to an asynchronous span

@param e [Exception] Add exception to the current span @param span [Span] the span for this Async op (previously returned from `log_async_entry`)

# File lib/instana/tracer.rb, line 246
def log_async_error(e, span)
  span.add_error(e)
end
log_async_exit(_name, kvs, span) click to toggle source

Closes out an asynchronous span

@param name [String] the name of the async span to exit (close out) @param kvs [Hash] list of additional key/values to be reported in the span (or use {}) @param span [Span] the span for this Async op (previously returned from `log_async_entry`)

# File lib/instana/tracer.rb, line 256
def log_async_exit(_name, kvs, span)
  span.set_tags(kvs) unless kvs.empty?
  span.close
end
log_async_info(kvs, span) click to toggle source

Add info to an asynchronous span

@param kvs [Hash] list of key values to be reported in the span @param span [Span] the span for this Async op (previously returned from `log_async_entry`)

# File lib/instana/tracer.rb, line 237
def log_async_info(kvs, span)
  span.set_tags(kvs)
end
log_end(name, kvs = {}, end_time = ::Instana::Util.now_in_ms) click to toggle source

Closes out the current span in the current trace and queues the trace for reporting

@note `name` isn't really required but helps keep sanity that we're ending the span that we really want to close out.

@param name [String] the name of the span to end @param kvs [Hash] list of key values to be reported in the span

# File lib/instana/tracer.rb, line 199
def log_end(name, kvs = {}, end_time = ::Instana::Util.now_in_ms)
  return unless self.current_span

  if self.current_span.name != name
    @logger.warn "Span mismatch: Attempt to end #{name} span but #{self.current_span.name} is active."
  end

  self.current_span.set_tags(kvs)
  self.current_span.close(end_time)
  self.current_span = nil
end
log_entry(name, kvs = nil, start_time = ::Instana::Util.now_in_ms, child_of = nil) click to toggle source

Will establish a new span as a child of the current span in an existing trace

@param name [String, Symbol] the name of the span to create @param kvs [Hash] list of key values to be reported in the span

# File lib/instana/tracer.rb, line 135
def log_entry(name, kvs = nil, start_time = ::Instana::Util.now_in_ms, child_of = nil)
  return unless self.current_span || child_of

  new_span = if child_of.is_a?(::Instana::Span) || child_of.is_a?(::Instana::SpanContext)
               Span.new(name, parent_ctx: child_of, start_time: start_time)
             else
               Span.new(name, parent_ctx: self.current_span, start_time: start_time)
             end
  new_span.set_tags(kvs) if kvs
  self.current_span = new_span
end
log_error(e) click to toggle source

Add an error to the current span

@param e [Exception] Add exception to the current span

# File lib/instana/tracer.rb, line 160
def log_error(e)
  return unless self.current_span
  self.current_span.add_error(e)
end
log_exit(name, kvs = {}) click to toggle source

Closes out the current span

@note `name` isn't really required but helps keep sanity that we're closing out the span that we really want to close out.

@param name [String, Symbol] the name of the span to exit (close out) @param kvs [Hash] list of key values to be reported in the span

# File lib/instana/tracer.rb, line 173
def log_exit(name, kvs = {})
  return unless self.current_span

  if self.current_span.name != name
    @logger.warn "Span mismatch: Attempt to end #{name} span but #{self.current_span.name} is active."
  end

  self.current_span.set_tags(kvs)
  self.current_span.close

  if self.current_span.parent
    self.current_span = self.current_span.parent
  else
    self.current_span = nil
  end
end
log_info(kvs) click to toggle source

Add info to the current span

@param kvs [Hash] list of key values to be reported in the span

# File lib/instana/tracer.rb, line 151
def log_info(kvs)
  return unless self.current_span
  self.current_span.set_tags(kvs)
end
log_start_or_continue(name, kvs = {}, incoming_context = nil) click to toggle source

Will start a new trace or continue an on-going one (such as from incoming remote requests with context headers).

@param name [String, Symbol] the name of the span to start @param kvs [Hash] list of key values to be reported in the span @param incoming_context [SpanContext or Hash] specifies the incoming context. At a

minimum, it should specify :trace_id and :span_id from the following:
  :trace_id the trace ID (must be an unsigned hex-string)
  :span_id the ID of the parent span (must be an unsigned hex-string)
  :level specifies data collection level (optional)
# File lib/instana/tracer.rb, line 97
def log_start_or_continue(name, kvs = {}, incoming_context = nil)
  return if !::Instana.agent.ready? || !::Instana.config[:tracing][:enabled]

  # Handle the potential variations on `incoming_context`
  if incoming_context
    if incoming_context.is_a?(Hash)
      if !incoming_context.empty?
        parent_context = SpanContext.new(
          incoming_context[:trace_id],
          incoming_context[:span_id],
          incoming_context[:level],
          {
            external_trace_id: incoming_context[:external_trace_id],
            external_state: incoming_context[:external_state]
          }
        )
      end
    else
      parent_context = incoming_context
    end
  end

  if parent_context
    self.current_span = Span.new(name, parent_ctx: parent_context)
  else
    self.current_span = Span.new(name)
  end

  self.current_span.set_tags(kvs) unless kvs.empty?
  self.current_span
end
start_or_continue_trace(name, kvs = {}, incoming_context = nil) { |span| ... } click to toggle source

Will start a new trace or continue an on-going one (such as from incoming remote requests with context headers).

@param name [String, Symbol] the name of the span to start @param kvs [Hash] list of key values to be reported in the span @param incoming_context [Hash] specifies the incoming context. At a

minimum, it should specify :trace_id and :span_id from the following:
  @:trace_id the trace ID (must be an unsigned hex-string)
  :span_id the ID of the parent span (must be an unsigned hex-string)
  :level specifies data collection level (optional)
# File lib/instana/tracer.rb, line 51
def start_or_continue_trace(name, kvs = {}, incoming_context = nil, &block)
  span = log_start_or_continue(name, kvs, incoming_context)
  yield(span)
rescue Exception => e
  log_error(e)
  raise
ensure
  log_end(name)
end
trace(name, kvs = {}) { |span| ... } click to toggle source

Trace a block of code within the context of the exiting trace

Example usage:

::Instana.tracer.trace(:dbwork, { :db_name => @db.name }) do

@db.select(1)

end

@param name [String, Symbol] the name of the span to start @param kvs [Hash] list of key values to be reported in this new span

# File lib/instana/tracer.rb, line 72
def trace(name, kvs = {}, &block)
  span = log_entry(name, kvs)
  yield(span)
rescue Exception => e
  log_error(e)
  raise
ensure
  log_exit(name)
end
tracing?() click to toggle source

Indicates if we're are currently in the process of collecting a trace. This is false when the host agent isn available.

@return [Boolean] true or false on whether we are currently tracing or not

# File lib/instana/tracer.rb, line 271
def tracing?
  # The non-nil value of this instance variable
  # indicates if we are currently tracing
  # in this thread or not.
  self.current_span ? true : false
end
tracing_span?(name) click to toggle source

Indicates if we're tracing and the current span name matches <name>

@param name [Symbol] the name to check against the current span

@return [Boolean]

# File lib/instana/tracer.rb, line 285
def tracing_span?(name)
  if self.current_span
    return self.current_span.name == name
  end
  false
end