class StackifyRubyAPM::Middleware

@api private

Constants

ATTACHMENT
CONTENT_DISPOSITION
CONTENT_TYPE_REGEX

Attributes

configuration[RW]
rack_body[RW]
rack_headers[RW]
rack_status[RW]

Public Class Methods

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

Public Instance Methods

attachment?() click to toggle source
# File lib/stackify_apm/middleware.rb, line 125
def attachment?
  @rack_headers[CONTENT_DISPOSITION] && @rack_headers[CONTENT_DISPOSITION].include?(ATTACHMENT)
end
build_prefix_context(transaction, context) click to toggle source

Add prefix instrument data to transaction context if enabled

# File lib/stackify_apm/middleware.rb, line 142
def build_prefix_context(transaction, context)
  return nil unless @configuration.prefix_enabled.is_a?(TrueClass)

  source = nil
  body = @rack_body
  body.each { |fragment| source ? (source << fragment.to_s) : (source = fragment.to_s) }

  transaction.context.prefix.request_body = context && context.request && context.request.body || ""
  transaction.context.prefix.request_headers = context && context.request && context.request.headers || Hash.new
  transaction.context.prefix.response_body = source || ""
  transaction.context.prefix.response_headers = @rack_headers || Hash.new
end
build_transaction(env, context=nil) click to toggle source

Start of transaction building with params: name, type, context

# File lib/stackify_apm/middleware.rb, line 100
def build_transaction(env, context=nil)
  context = context || StackifyRubyAPM.build_context(env)
  StackifyRubyAPM.transaction 'Rack', 'WEBAPP', context: context
end
call(env) click to toggle source

This is where the requests are received, built into a transaction, and then submitted

rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/PerceivedComplexity

# File lib/stackify_apm/middleware.rb, line 40
def call(env)
  begin
    context = StackifyRubyAPM.build_context(env)
    transaction = build_transaction(env, context) if running?
    resp = @app.call env

    @rack_status = resp[0].to_i
    @rack_headers = resp[1]
    @rack_body = resp[2]
    @configuration = config

    build_prefix_context(transaction, context)

    if okay_to_modify?
      @configuration.already_instrumented_flag = true
      if @configuration.rum_enabled.is_a?(TrueClass)
        # close old response body proxy to close all db connections
        @rack_body.close if @rack_body.respond_to?(:close)
        response = Rack::Response.new @rack_body, @rack_status, @rack_headers
        response.set_cookie(@configuration.rum_cookie_name, value: transaction.id, path: @configuration.rum_cookie_path)
        resp = response.finish
      end
      if @configuration.rum_auto_injection.is_a?(TrueClass)
        response_manupulate = StackifyRubyAPM::ResponseManipulator.new(env, resp, @configuration)
        response_string = response_manupulate.adjust_pagehtml_response
        if response_string
          response = Rack::Response.new(response_string, resp[0].to_i, resp[1])
          resp = response.finish
        else
          resp
        end
      else
        resp
      end
    else
      resp
    end

    submit_transaction(transaction, *resp) if transaction
  rescue InternalError
    raise # Don't report StackifyRubyAPM errors
  rescue StandardError
    transaction.submit('500', status: 500) if transaction
    raise
  ensure
    transaction.release if transaction
  end

  resp
end
config() click to toggle source
# File lib/stackify_apm/middleware.rb, line 109
def config
  StackifyRubyAPM.agent.config
end
modifiable_content_type?() click to toggle source
# File lib/stackify_apm/middleware.rb, line 121
def modifiable_content_type?
  @rack_headers['Content-Type'] =~ self.class::CONTENT_TYPE_REGEX
end
okay_to_modify?() click to toggle source
# File lib/stackify_apm/middleware.rb, line 113
def okay_to_modify?
  return false if xhr?
  return false unless modifiable_content_type?
  return false if @rack_status == 404 || @rack_status == 501
  return false if attachment?
  true
end
running?() click to toggle source
# File lib/stackify_apm/middleware.rb, line 105
def running?
  StackifyRubyAPM.running?
end
streaming?(env) click to toggle source
# File lib/stackify_apm/middleware.rb, line 129
def streaming?(env)
  # Not used
  # Possible use of ActiveSupport.on_load(:action_controller_base)
  return false unless defined?(ActionController::Live)

  env['action_controller.instance'].class.included_modules.include?(ActionController::Live)
end
submit_transaction(transaction, status, headers, _body) click to toggle source

rubocop:enable Metrics/PerceivedComplexity rubocop:enable Metrics/CyclomaticComplexity

# File lib/stackify_apm/middleware.rb, line 93
def submit_transaction(transaction, status, headers, _body)
  result = status.to_i
  transaction.submit(result, status: status, headers: headers)
end
xhr?() click to toggle source
# File lib/stackify_apm/middleware.rb, line 137
def xhr?
  @rack_headers['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'
end