Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Commit

Permalink
Merge pull request #104 from librato/feature/instrument_action_all
Browse files Browse the repository at this point in the history
Instrument all controller actions
  • Loading branch information
Chance Feick authored Jun 23, 2016
2 parents fa48867 + 1a0e242 commit 6d6a5c2
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### master
* Add support to instrument all controller actions, e.g., `instrument_action :all`.

### Version 1.3.0
* Add support for configurable metric suites

Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,22 @@ class CommentController < ApplicationController
end
```

Optionally, you can instrument all controller actions:

```ruby
class ArticlesController < ApplicationController
instrument_action :all
def create
# ...
end
def show
# ...
end
end
```

Once you instrument an action, `librato-rails` will start reporting a set of metrics specific to that action including:

* rails.action.request.total (# of requests)
Expand Down
7 changes: 6 additions & 1 deletion lib/librato/rails/helpers/controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ def instrument_action(*actions)
end
end

def inherited(other)
super
Subscribers.inherit_watches(self.to_s, other.to_s)
end

end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/librato/rails/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Railtie < ::Rails::Railtie
# don't have any custom http vars anymore, check if hostname is UUID
on_heroku = Socket.gethostname =~ /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/i

config.before_configuration do
config.before_configuration do
# make configuration proxy for config inside Rails
config.librato_rails = Configuration.new

Expand Down
15 changes: 14 additions & 1 deletion lib/librato/rails/subscribers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,20 @@ def self.collector

def self.watch_controller_action(controller, action)
@watches ||= []
@watches << "#{controller}##{action}".freeze

watch =
if action == :all
"#{controller}".freeze
else
"#{controller}##{action}".freeze
end

@watches << watch
end

def self.inherit_watches(base, descendant)
@watches ||= []
@watches << descendant.freeze if @watches.include?(base)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/librato/rails/subscribers/action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module Subscribers
format = "all" if format == "*/*"
exception = event.payload[:exception]

if @watches && @watches.index("#{controller}##{action}")
if @watches && (@watches.index(controller) || @watches.index("#{controller}##{action}"))
source = "#{controller}.#{action}.#{format}"
collector.group 'rails.action.request' do |r|

Expand Down
4 changes: 2 additions & 2 deletions test/dummy/app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
class ApplicationController < ActionController::Base
protect_from_forgery

instrument_action :all
#after_filter :flush_metrics_rails

# manually flush per request
def flush_metrics_rails
Librato::Rails.flush
Expand Down
11 changes: 11 additions & 0 deletions test/dummy/app/controllers/base_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class BaseController < ApplicationController
instrument_action :all

def action_1
render nothing: true
end

def action_2
render nothing: true
end
end
9 changes: 9 additions & 0 deletions test/dummy/app/controllers/derived_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class DerivedController < IntermediateController
def action_1
render nothing: true
end

def action_2
render nothing: true
end
end
2 changes: 1 addition & 1 deletion test/dummy/app/controllers/instrument_action_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def inst
end
end

def not_instrumented
def not
render nothing: true
end

Expand Down
5 changes: 5 additions & 0 deletions test/dummy/app/controllers/intermediate_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class IntermediateController < BaseController
def action_1
render nothing: true
end
end
6 changes: 6 additions & 0 deletions test/dummy/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
get 'instrument/inst' => 'instrument_action#inst', :as => :instrument_action
get 'instrument/not' => 'instrument_action#not', :as => :not_instrumented

get 'base/action_1' => 'base#action_1', :as => :base_action_1
get 'base/action_2' => 'base#action_2', :as => :base_action_2
get 'intermediate/action_1' => 'intermediate#action_1', :as => :intermediate_action_1
get 'derived/action_1' => 'derived#action_1', :as => :derived_action_1
get 'derived/action_2' => 'derived#action_2', :as => :derived_action_2

# The priority is based upon order of creation:
# first created -> highest priority.

Expand Down
30 changes: 30 additions & 0 deletions test/integration/instrument_action_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,34 @@ class InstrumentActionTest < ActiveSupport::IntegrationCase
assert_equal 1, counters.fetch("#{base}.total", source: source)
end

test 'instrument all controller actions' do
visit base_action_1_path
visit base_action_2_path

metric = 'rails.action.request.time'

assert_equal 1, aggregate.fetch(metric, source: 'BaseController.action_1.html')[:count]
assert_equal 1, aggregate.fetch(metric, source: 'BaseController.action_2.html')[:count]
end

test 'instrument all controller actions for inherited controllers' do
visit intermediate_action_1_path
visit derived_action_1_path
visit derived_action_2_path

metric = 'rails.action.request.time'

assert_equal 1, aggregate.fetch(metric, source: 'IntermediateController.action_1.html')[:count]
assert_equal 1, aggregate.fetch(metric, source: 'DerivedController.action_1.html')[:count]
assert_equal 1, aggregate.fetch(metric, source: 'DerivedController.action_2.html')[:count]
end

test 'instrument all controller actions for all controllers' do
visit not_instrumented_path

metric = 'rails.action.request.time'

assert_equal 1, aggregate.fetch(metric, source: 'InstrumentActionController.not.html')[:count]
end

end

0 comments on commit 6d6a5c2

Please sign in to comment.