diff options
author | Daniel Schierbeck <daniel.schierbeck@gmail.com> | 2018-10-24 16:00:31 +0200 |
---|---|---|
committer | Jeremy Daer <jeremydaer@gmail.com> | 2019-03-19 08:35:09 -0700 |
commit | 04ae0b0b5e594e0bb99c5cd608921745977bcdcd (patch) | |
tree | c01abaa20879bdcc3ae50ddb90afe285f824447c /actionpack | |
parent | 299573adc60fe0f7aa68f9c66df5ffe2efb0df40 (diff) | |
download | rails-04ae0b0b5e594e0bb99c5cd608921745977bcdcd.tar.gz rails-04ae0b0b5e594e0bb99c5cd608921745977bcdcd.tar.bz2 rails-04ae0b0b5e594e0bb99c5cd608921745977bcdcd.zip |
Instrument middleware processing
Adds ActiveSupport::Notifications instrumentation of the processing of
each middleware in the stack.
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/stack.rb | 23 | ||||
-rw-r--r-- | actionpack/test/dispatch/middleware_stack_test.rb | 41 |
2 files changed, 57 insertions, 7 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index 7a2fcd6db7..f0c869fba0 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -34,7 +34,28 @@ module ActionDispatch end def build(app) - klass.new(app, *args, &block) + InstrumentationProxy.new(klass.new(app, *args, &block), inspect) + end + end + + # This class is used to instrument the execution of a single middleware. + # It proxies the `call` method transparently and instruments the method + # call. + class InstrumentationProxy + EVENT_NAME = "process_middleware.action_dispatch" + + def initialize(middleware, class_name) + @middleware = middleware + + @payload = { + middleware: class_name, + } + end + + def call(env) + ActiveSupport::Notifications.instrument(EVENT_NAME, @payload) do + @middleware.call(env) + end end end diff --git a/actionpack/test/dispatch/middleware_stack_test.rb b/actionpack/test/dispatch/middleware_stack_test.rb index 5f43e5a3c5..90f2eccd19 100644 --- a/actionpack/test/dispatch/middleware_stack_test.rb +++ b/actionpack/test/dispatch/middleware_stack_test.rb @@ -3,13 +3,24 @@ require "abstract_unit" class MiddlewareStackTest < ActiveSupport::TestCase - class FooMiddleware; end - class BarMiddleware; end - class BazMiddleware; end - class HiyaMiddleware; end - class BlockMiddleware + class Base + def initialize(app) + @app = app + end + + def call(env) + @app.call(env) + end + end + + class FooMiddleware < Base; end + class BarMiddleware < Base; end + class BazMiddleware < Base; end + class HiyaMiddleware < Base; end + class BlockMiddleware < Base attr_reader :block - def initialize(&block) + def initialize(app, &block) + super(app) @block = block end end @@ -109,6 +120,24 @@ class MiddlewareStackTest < ActiveSupport::TestCase assert_equal @stack.last, @stack.last end + test "instruments the execution of middlewares" do + app = @stack.build(proc { |env| [200, {}, []] }) + env = {} + + events = [] + + subscriber = proc do |*args| + events << ActiveSupport::Notifications::Event.new(*args) + end + + ActiveSupport::Notifications.subscribed(subscriber, "process_middleware.action_dispatch") do + app.call(env) + end + + assert_equal 2, events.count + assert_equal ["MiddlewareStackTest::BarMiddleware", "MiddlewareStackTest::FooMiddleware"], events.map { |e| e.payload[:middleware] } + end + test "includes a middleware" do assert_equal true, @stack.include?(ActionDispatch::MiddlewareStack::Middleware.new(BarMiddleware, nil, nil)) end |