class Rack::Instrumentation::Tracer

Attributes

app[R]
tracer[R]

Public Class Methods

new(app, tracer: OpenTracing.global_tracer) click to toggle source

Create a new Rack Tracer middleware.

@param app The Rack application/middlewares stack. @param tracer [OpenTracing::Tracer] A tracer to be used when start_span, and extract

is called.
# File lib/rack/instrumentation/tracer.rb, line 14
def initialize(app, tracer: OpenTracing.global_tracer)
  @app = app
  @tracer = tracer
end

Public Instance Methods

call(env) click to toggle source
# File lib/rack/instrumentation/tracer.rb, line 19
def call(env)
  tracer.start_active_span(*span_args(env)) do |scope|
    trace_request(env, scope)
  end
end

Private Instance Methods

route_from_env(env) click to toggle source
# File lib/rack/instrumentation/tracer.rb, line 66
def route_from_env(env)
  rails_controller = env['action_controller.instance']

  if rails_controller
    "#{env["REQUEST_METHOD"]} #{rails_controller.class.name}##{rails_controller.action_name}"
  end
end
span_args(env) click to toggle source
# File lib/rack/instrumentation/tracer.rb, line 50
def span_args(env)
  method = env["REQUEST_METHOD"]
  context = tracer.extract(OpenTracing::FORMAT_RACK, env)

  [
    method,
    child_of: context,
    tags: {
      'component' => 'ruby-rack',
      'span.kind' => 'server',
      'http.method' => method,
      'http.url' => env["REQUEST_URI"]
    }
  ]
end
trace_request(env, scope) click to toggle source
# File lib/rack/instrumentation/tracer.rb, line 27
def trace_request(env, scope)
  span = scope.span
  env['rack.span'] = span

  app.call(env).tap do |status_code, _headers, _body|
    span.set_tag('http.status_code', status_code)
    span.set_tag('error', true) if (500..599).include?(status_code)

    route = route_from_env(env)
    span.operation_name = route if route
  end
rescue StandardError => e
  span.set_tag('error', true)
  span.log_kv(
    event: 'error',
    :'error.kind' => e.class.to_s,
    :'error.object' => e,
    message: e.message,
    stack: e.backtrace.join("\n")
  )
  raise
end