class ElasticAPM::Middleware

@api private

Public Class Methods

new(app) click to toggle source
# File lib/elastic_apm/middleware.rb, line 26
def initialize(app)
  @app = app
end

Public Instance Methods

call(env) click to toggle source
# File lib/elastic_apm/middleware.rb, line 30
def call(env)
  begin
    if running? && !path_ignored?(env)
      transaction = start_transaction(env)
    end

    resp = @app.call env
  rescue InternalError
    raise # Don't report ElasticAPM errors
  rescue ::Exception => e
    context = ElasticAPM.build_context(rack_env: env, for_type: :error)
    ElasticAPM.report(e, context: context, handled: false)
    raise
  ensure
    if transaction
      if resp
        status, headers, _body = resp
        transaction.add_response(status, headers: headers.dup)
        transaction&.outcome = Transaction::Outcome.from_http_status(status)
      else
        transaction&.outcome = Transaction::Outcome::FAILURE
      end
    end

    ElasticAPM.end_transaction http_result(status)
  end

  resp
end

Private Instance Methods

config() click to toggle source
# File lib/elastic_apm/middleware.rb, line 97
def config
  @config ||= ElasticAPM.agent.config
end
http_result(status) click to toggle source
# File lib/elastic_apm/middleware.rb, line 62
def http_result(status)
  status && "HTTP #{status.to_s[0]}xx"
end
path_ignored?(env) click to toggle source
# File lib/elastic_apm/middleware.rb, line 66
def path_ignored?(env)
  return true if config.ignore_url_patterns.any? do |r|
    r.match(env['PATH_INFO'])
  end

  return true if config.transaction_ignore_urls.any? do |r|
    r.match(env['PATH_INFO'])
  end

  false
end
running?() click to toggle source
# File lib/elastic_apm/middleware.rb, line 93
def running?
  ElasticAPM.running?
end
start_transaction(env) click to toggle source
# File lib/elastic_apm/middleware.rb, line 78
def start_transaction(env)
  context = ElasticAPM.build_context(rack_env: env, for_type: :transaction)

  ElasticAPM.start_transaction 'Rack', 'request',
    context: context,
    trace_context: trace_context(env)
end
trace_context(env) click to toggle source
# File lib/elastic_apm/middleware.rb, line 86
def trace_context(env)
  TraceContext.parse(env: env)
rescue TraceContext::InvalidTraceparentHeader => e
  warn e.message
  nil
end