class EpsagonTracerMiddleware

Sinatra middleware for epsagon instrumentation

Attributes

app[R]

Public Class Methods

new(app) click to toggle source
# File lib/instrumentation/sinatra.rb, line 10
def initialize(app)
  @app = app
end

Public Instance Methods

call(env) click to toggle source
# File lib/instrumentation/sinatra.rb, line 18
def call(env)
  request = Rack::Request.new(env)
  path, path_params = request.path.split(';')
  request_headers = JSON.generate(Hash[*env.select { |k, _v| k.start_with? 'HTTP_' }
    .collect { |k, v| [k.sub(/^HTTP_/, ''), v] }
    .collect { |k, v| [k.split('_').collect(&:capitalize).join('-'), v] }
    .sort
    .flatten])

  attributes = {
    'operation' => env['REQUEST_METHOD'],
    'type' => 'http',
    'http.scheme' => env['rack.url_scheme'],
    'http.request.path' => path,
    'http.request.headers' => request_headers
  }

  unless config[:epsagon][:metadata_only]
    request.body.rewind
    request_body = request.body.read
    request.body.rewind

    attributes.merge!(Util.epsagon_query_attributes(request.query_string))

    attributes.merge!({
                        'http.request.body' => request_body,
                        'http.request.path_params' => path_params,
                        'http.request.headers.User-Agent' => env['HTTP_USER_AGENT']
                      })
  end

  tracer.in_span(
    env['HTTP_HOST'],
    attributes: attributes,
    kind: :server,
    with_parent: parent_context(env)
  ) do |http_span|
    tracer.in_span(
      env['HTTP_HOST'],
      kind: :server,
      attributes: { type: 'sinatra' }
    ) do |framework_span|
      app.call(env).tap { |resp| trace_response(http_span, framework_span, env, resp) }
    end
  end
end
config() click to toggle source
# File lib/instrumentation/sinatra.rb, line 14
def config
  EpsagonSinatraInstrumentation.instance.config
end

Private Instance Methods

parent_context(env) click to toggle source
# File lib/instrumentation/sinatra.rb, line 69
def parent_context(env)
  OpenTelemetry.propagation.http.extract(env)
end
trace_response(http_span, framework_span, env, resp) click to toggle source
# File lib/instrumentation/sinatra.rb, line 77
def trace_response(http_span, framework_span, env, resp)
  status, headers, response_body = resp

  unless config[:epsagon][:metadata_only]
    http_span.set_attribute('http.response.headers', JSON.generate(headers))
    http_span.set_attribute('http.response.body', response_body.join)
  end

  http_span.set_attribute('http.status_code', status)
  http_span.set_attribute('http.route', env['sinatra.route'].split.last) if env['sinatra.route']
  http_span.status = OpenTelemetry::Trace::Status.http_to_status(status)
end
tracer() click to toggle source
# File lib/instrumentation/sinatra.rb, line 73
def tracer
  EpsagonSinatraInstrumentation.instance.tracer
end