module TraceView::Inst::CurlUtility

Curb instrumentation wraps instance and class methods in two classes: Curl::Easy and Curl::Multi. This CurlUtility module is used as a common module to be shared among both modules.

Public Instance Methods

profile_curb_method(kvs, method, args, &block) click to toggle source

profile_curb_method

An agnostic method that will profile any Curl::Easy method (and optional args and block) that you throw at it.

# File lib/traceview/inst/curb.rb, line 55
def profile_curb_method(kvs, method, args, &block)
  # If we're not tracing, just do a fast return.
  return self.send(method, args, &block) if !TraceView.tracing?

  begin
    response_context = nil
    req_context = nil
    handle_cross_host = TraceView::Config[:curb][:cross_host]
    kvs.merge! traceview_collect

    TraceView::API.log_entry(:curb, kvs)
    kvs.clear

    if handle_cross_host && !kvs[:blacklisted]
      req_context = TraceView::Context.toString()
      self.headers['X-Trace'] = req_context
    end

    # The core curb call
    response = self.send(method, *args, &block)

    if handle_cross_host
      kvs[:HTTPStatus] = response_code

      # If we get a redirect, report the location header
      if ((300..308).to_a.include? response_code) && headers.key?("Location")
        kvs[:Location] = headers["Location"]
      end

      _, *response_headers = header_str.split(/[\r\n]+/).map(&:strip)
      response_headers = Hash[response_headers.flat_map{ |s| s.scan(/^(\S+): (.+)/) }]

      response_context = response_headers['X-Trace']
      if response_context && !kvs[:blacklisted]
        TraceView::XTrace.continue_service_context(req_context, response_context)
      end
    end

    response
  rescue => e
    TraceView::API.log_exception(:curb, e)
    raise e
  ensure
    TraceView::API.log_exit(:curb, kvs)
  end
end
traceview_collect(verb = nil) click to toggle source

traceview_collect

Used as a central area to retrieve and return values that we're interesting in reporting to TraceView

# File lib/traceview/inst/curb.rb, line 18
def traceview_collect(verb = nil)
  kvs = {}

  if TraceView::Config[:curb][:cross_host]
    kvs[:IsService] = 1

    # Conditionally log query args
    if TraceView::Config[:curb][:log_args]
      kvs[:RemoteURL] = url
    else
      kvs[:RemoteURL] = url.split('?').first
    end

    kvs[:HTTPMethod] = verb if verb
  end

  # Avoid cross host tracing for blacklisted domains
  kvs[:blacklisted] = TraceView::API.blacklisted?(URI(url).hostname)
  kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:curb][:collect_backtraces]

  kvs
rescue => e
  TraceView.logger.debug "[traceview/debug] Error capturing curb KVs: #{e.message}"
  if TraceView::Config[:verbose]
    TraceView.logger.debug "[traceview/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
    TraceView.logger.debug e.backtrace.join('\n')
  end
ensure
  return kvs
end