# encoding: utf-8 require 'one_apm/support/method_tracer' require 'one_apm/transaction' require 'one_apm/transaction/transaction_state' require 'one_apm/inst/support/queue_time' require 'one_apm/inst/transaction_base' require 'one_apm/rack/middleware_tracing' module OneApm::Rack class MiddlewareWrapper include MiddlewareTracing class MiddlewareClassWrapper def initialize(middleware_class) @middleware_class = middleware_class end def new(*args, &blk) middleware_instance = @middleware_class.new(*args, &blk) MiddlewareWrapper.wrap(middleware_instance) end end class << self def is_sinatra_app?(target) defined?(::Sinatra::Base) && target.kind_of?(::Sinatra::Base) end def wrap_class(target_class) MiddlewareClassWrapper.new(target_class) end def needs_wrapping?(target) !target.respond_to?(:_oa_has_middleware_tracing) && !is_sinatra_app?(target) end def wrap(target, is_app = false) if needs_wrapping?(target) self.new(target, is_app) else target end end end attr_reader :target, :category, :transaction_options def initialize(target, is_app = false) @target = target @is_app = is_app @category = determine_category @target_class_name = determine_class_name @transaction_name = "#{determine_prefix}#{@target_class_name}/call" @transaction_options = { :transaction_name => @transaction_name } end def determine_category @is_app ? :rack : :middleware end def determine_prefix OneApm::TransactionNamer.prefix_for_category(nil, @category) end # In 'normal' usage, the target will be an application instance that # responds to #call. With Rails, however, the target may be a subclass # of Rails::Application that defines a method_missing that proxies #call # to a singleton instance of the the subclass. We need to ensure that we # capture the correct name in both cases. def determine_class_name if @target.is_a?(Class) @target.name else @target.class.name end end end end