rails_metrics 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. data/CHANGELOG.rdoc +3 -0
  2. data/Gemfile +9 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +58 -0
  5. data/Rakefile +58 -0
  6. data/TODO.rdoc +1 -0
  7. data/app/controllers/rails_metrics_controller.rb +78 -0
  8. data/app/helpers/rails_metrics_helper.rb +161 -0
  9. data/app/views/layouts/rails_metrics.html.erb +21 -0
  10. data/app/views/rails_metrics/_request.html.erb +21 -0
  11. data/app/views/rails_metrics/_row.html.erb +23 -0
  12. data/app/views/rails_metrics/all.html.erb +25 -0
  13. data/app/views/rails_metrics/chart.html.erb +49 -0
  14. data/app/views/rails_metrics/index.html.erb +21 -0
  15. data/app/views/rails_metrics/show.html.erb +41 -0
  16. data/config/routes.rb +7 -0
  17. data/lib/generators/rails_metrics_generator.rb +40 -0
  18. data/lib/rails_metrics.rb +112 -0
  19. data/lib/rails_metrics/async_consumer.rb +54 -0
  20. data/lib/rails_metrics/engine.rb +29 -0
  21. data/lib/rails_metrics/middleware.rb +27 -0
  22. data/lib/rails_metrics/orm/active_record.rb +66 -0
  23. data/lib/rails_metrics/payload_parser.rb +131 -0
  24. data/lib/rails_metrics/store.rb +132 -0
  25. data/lib/rails_metrics/version.rb +3 -0
  26. data/public/images/rails_metrics/arrow_down.png +0 -0
  27. data/public/images/rails_metrics/arrow_up.png +0 -0
  28. data/public/images/rails_metrics/cancel.png +0 -0
  29. data/public/images/rails_metrics/chart_pie.png +0 -0
  30. data/public/images/rails_metrics/page_white_delete.png +0 -0
  31. data/public/images/rails_metrics/page_white_go.png +0 -0
  32. data/public/images/rails_metrics/tick.png +0 -0
  33. data/public/javascripts/rails_metrics/g.pie-min.js +6 -0
  34. data/public/javascripts/rails_metrics/g.raphael-min.js +5 -0
  35. data/public/javascripts/rails_metrics/raphael-min.js +5 -0
  36. data/public/stylesheets/rails_metrics.css +135 -0
  37. data/test/dummy/app/controllers/application_controller.rb +4 -0
  38. data/test/dummy/app/controllers/users_controller.rb +43 -0
  39. data/test/dummy/app/helpers/application_helper.rb +2 -0
  40. data/test/dummy/app/models/metric.rb +3 -0
  41. data/test/dummy/app/models/notification.rb +7 -0
  42. data/test/dummy/app/models/user.rb +2 -0
  43. data/test/dummy/config/application.rb +52 -0
  44. data/test/dummy/config/boot.rb +9 -0
  45. data/test/dummy/config/environment.rb +5 -0
  46. data/test/dummy/config/environments/development.rb +19 -0
  47. data/test/dummy/config/environments/production.rb +33 -0
  48. data/test/dummy/config/environments/test.rb +29 -0
  49. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  50. data/test/dummy/config/initializers/cookie_verification_secret.rb +7 -0
  51. data/test/dummy/config/initializers/session_store.rb +15 -0
  52. data/test/dummy/config/routes.rb +60 -0
  53. data/test/dummy/db/migrate/20100106152343_create_metrics.rb +17 -0
  54. data/test/dummy/db/migrate/20100108120821_create_users.rb +13 -0
  55. data/test/integration/instrumentation_test.rb +100 -0
  56. data/test/integration/navigation_test.rb +103 -0
  57. data/test/orm/active_record_test.rb +51 -0
  58. data/test/payload_parser_test.rb +36 -0
  59. data/test/rails_metrics_test.rb +43 -0
  60. data/test/store_test.rb +81 -0
  61. data/test/support/helpers.rb +16 -0
  62. data/test/support/instrumentation.rb +18 -0
  63. data/test/support/mock_store.rb +34 -0
  64. data/test/support/webrat/integrations/rails.rb +31 -0
  65. data/test/test_helper.rb +32 -0
  66. metadata +118 -0
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+
3
+ class ActiveRecordTest < ActiveSupport::TestCase
4
+ setup do
5
+ Metric.delete_all
6
+ end
7
+
8
+ test "does not store own queries as notifications" do
9
+ Metric.all
10
+ wait
11
+ assert Metric.all.empty?
12
+ end
13
+
14
+ test "does not store queries other than SELECT, INSERT, UPDATE and DELETE" do
15
+ User.connection.send(:select, "SHOW tables;")
16
+ wait
17
+ assert Metric.all.empty?
18
+ end
19
+
20
+ test "serializes payload" do
21
+ metric = Metric.new
22
+ metric.configure(["metric", Time.now, Time.now, "id", {:foo => :bar}])
23
+ metric.save!
24
+ assert_equal Hash[:foo => :bar], metric.payload
25
+ end
26
+
27
+ test "is invalid when name is blank" do
28
+ metric = Metric.new
29
+ assert metric.invalid?
30
+ assert "can't be blank", metric.errors["name"].join
31
+ end
32
+
33
+ test "is invalid when started_at is blank" do
34
+ metric = Metric.new
35
+ assert metric.invalid?
36
+ assert "can't be blank", metric.errors["started_at"].join
37
+ end
38
+
39
+ test "is invalid when duration is blank" do
40
+ metric = Metric.new
41
+ assert metric.invalid?
42
+ assert "can't be blank", metric.errors["duration"].join
43
+ end
44
+
45
+ test "responds to all required named scopes" do
46
+ [ :by_name, :by_request_id, :latest,
47
+ :earliest, :slowest, :fastest, :requests ].each do |method|
48
+ assert_respond_to Metric, method
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ class PayloadParserTest < ActiveSupport::TestCase
4
+ setup do
5
+ @_previous_parsers = RailsMetrics::PayloadParser.parsers.dup
6
+ end
7
+
8
+ teardown do
9
+ RailsMetrics::PayloadParser.parsers.replace @_previous_parsers
10
+ end
11
+
12
+ delegate :add, :ignore, :filter, :to => RailsMetrics::PayloadParser
13
+
14
+ test "a non registered parser returns payload as is" do
15
+ assert_equal Hash[:some => :info], filter("rails_metrics.something", :some => :info)
16
+ end
17
+
18
+ test "a parser with hash converts into method calls" do
19
+ add "rails_metrics.something", :except => [:foo, :bar]
20
+ assert_equal Hash[:some => :info], filter("rails_metrics.something", :some => :info,
21
+ :foo => :baz, :bar => :baz)
22
+ end
23
+
24
+ test "a parser with a block calls the block with payload" do
25
+ add "rails_metrics.something" do |payload|
26
+ assert_equal Hash[:some => :info], payload
27
+ { :foo => :bar }
28
+ end
29
+ assert_equal Hash[:foo => :bar], filter("rails_metrics.something", :some => :info)
30
+ end
31
+
32
+ test "a parser can be ignored" do
33
+ ignore "rails_metrics.something"
34
+ assert_nil filter("rails_metrics.something", :some => :info)
35
+ end
36
+ end
@@ -0,0 +1,43 @@
1
+ require 'test_helper'
2
+
3
+ class RailsMetricsTest < ActiveSupport::TestCase
4
+ setup do
5
+ RailsMetrics.set_store { MockStore }
6
+ MockStore.instances.clear
7
+ end
8
+
9
+ test "send instrumentation event to the specified store" do
10
+ instrument "rails_metrics.something"
11
+ wait
12
+
13
+ assert_equal 2, MockStore.instances.size
14
+ assert_equal "rails_metrics.something", MockStore.instances.first.name
15
+ end
16
+
17
+ test "does not send an event to the store if it matches an ignored pattern" do
18
+ RailsMetrics.ignore_patterns << /rails_metrics/
19
+
20
+ begin
21
+ instrument "rails_metrics.something"
22
+ wait
23
+ assert MockStore.instances.none? { |m| m.name == "rails_metrics.something" }
24
+ ensure
25
+ RailsMetrics.ignore_patterns.pop
26
+ end
27
+ end
28
+
29
+ test "does not send an event to the store if it was generated inside it" do
30
+ instrument "rails_metrics.kicker"
31
+ wait
32
+
33
+ assert_equal 2, MockStore.instances.size
34
+ assert MockStore.instances.first.kicked?
35
+ assert_equal "rails_metrics.kicker", MockStore.instances.first.name
36
+ end
37
+
38
+ test "does not send an event if not listening" do
39
+ ActiveSupport::Notifications.instrument "rails_metrics.kicker"
40
+ wait
41
+ assert_equal 0, MockStore.instances.size
42
+ end
43
+ end
@@ -0,0 +1,81 @@
1
+ require 'test_helper'
2
+
3
+ class StoreTest < ActiveSupport::TestCase
4
+ setup do
5
+ RailsMetrics.set_store { MockStore }
6
+ MockStore.instances.clear
7
+ end
8
+
9
+ def sample_args
10
+ time = Time.now
11
+ ["rails_metrics.example", time, time + 1, 1, { :some => :info }]
12
+ end
13
+
14
+ def store!(args=sample_args)
15
+ metric = Metric.new
16
+ metric.configure(args)
17
+ metric
18
+ end
19
+
20
+ test "sets the name" do
21
+ assert_equal "rails_metrics.example", store!.name
22
+ end
23
+
24
+ test "sets the duration" do
25
+ assert_equal 1000000, store!.duration
26
+ assert_equal 1000000, store!.duration_in_us
27
+ assert_equal 1000, store!.duration_in_ms
28
+ end
29
+
30
+ test "sets started at" do
31
+ assert_kind_of Time, store!.started_at
32
+ end
33
+
34
+ test "sets the payload" do
35
+ assert_equal Hash[:some => :info], store!.payload
36
+ end
37
+
38
+ test "nested instrumentations are saved nested" do
39
+ instrument "rails_metrics.parent" do
40
+ instrument "rails_metrics.child" do
41
+ end
42
+ end
43
+
44
+ instrument "rails_metrics.another"
45
+
46
+ assert_equal 5, MockStore.instances.size
47
+ child, parent, request, another, another_request = MockStore.instances
48
+
49
+ assert_equal request.id, request.request_id
50
+ assert_equal request.id, parent.request_id
51
+ assert_equal request.id, parent.parent_id
52
+ assert_equal request.id, child.request_id
53
+ assert_equal parent.id, child.parent_id
54
+
55
+ assert parent.parent_of?(child)
56
+ assert child.child_of?(parent)
57
+
58
+ assert !parent.parent_of?(another)
59
+ assert !another.parent_of?(parent)
60
+ assert !parent.child_of?(another)
61
+ assert !another.child_of?(parent)
62
+ end
63
+
64
+ test "tree can be created from nested instrumentations" do
65
+ instrument "rails_metrics.parent" do
66
+ instrument "rails_metrics.child" do
67
+ end
68
+ end
69
+
70
+ child, parent, request = MockStore.instances
71
+ root = RailsMetrics.store.mount_tree(MockStore.instances)
72
+
73
+ assert_equal "rails_metrics.child", child.name
74
+ assert_equal "rails_metrics.parent", parent.name
75
+ assert_equal "rack.request", request.name
76
+
77
+ assert root.rack_request?
78
+ assert [parent], root.children
79
+ assert [child], parent.children
80
+ end
81
+ end
@@ -0,0 +1,16 @@
1
+ class ActiveSupport::TestCase
2
+ # Execute the block setting the given values and restoring old values after
3
+ # the block is executed.
4
+ def swap(object, new_values)
5
+ old_values = {}
6
+ new_values.each do |key, value|
7
+ old_values[key] = object.send key
8
+ object.send :"#{key}=", value
9
+ end
10
+ yield
11
+ ensure
12
+ old_values.each do |key, value|
13
+ object.send :"#{key}=", value
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ class ActiveSupport::TestCase
2
+ def wait
3
+ RailsMetrics.wait
4
+ end
5
+
6
+ # Fake a request instrumentation.
7
+ def instrument(*args, &block)
8
+ if RailsMetrics.listening?
9
+ ActiveSupport::Notifications.instrument(*args, &block)
10
+ else
11
+ RailsMetrics.listen_request do
12
+ ActiveSupport::Notifications.instrument "rack.request" do
13
+ ActiveSupport::Notifications.instrument(*args, &block)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ class ActiveSupport::TestCase
2
+ class MockStore
3
+ include RailsMetrics::Store
4
+
5
+ attr_accessor :id, :name, :parent_id, :request_id, :started_at, :duration, :payload
6
+
7
+ def self.instances
8
+ @instances ||= []
9
+ end
10
+
11
+ def initialize
12
+ self.class.instances << self
13
+ end
14
+
15
+ def kicked?
16
+ @kicked || false
17
+ end
18
+
19
+ def new_record?
20
+ true
21
+ end
22
+
23
+ protected
24
+
25
+ def save_metric!
26
+ self.id ||= (rand * 1000).to_i
27
+
28
+ if self.name == "rails_metrics.kicker"
29
+ @kicked = true
30
+ ActiveSupport::Notifications.instrument("rails_metrics.inside_store")
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,31 @@
1
+ require 'webrat/core/elements/field'
2
+
3
+ module Webrat
4
+ Field.class_eval do
5
+ def parse_rails_request_params(params)
6
+ Rack::Utils.parse_nested_query(params)
7
+ end
8
+ end
9
+ end
10
+
11
+ module ActionController #:nodoc:
12
+ IntegrationTest.class_eval do
13
+ include Webrat::Methods
14
+ include Webrat::Matchers
15
+
16
+ # The Rails version of within supports passing in a model and Webrat
17
+ # will apply a scope based on Rails' dom_id for that model.
18
+ #
19
+ # Example:
20
+ # within User.last do
21
+ # click_link "Delete"
22
+ # end
23
+ def within(selector_or_object, &block)
24
+ if selector_or_object.is_a?(String)
25
+ super
26
+ else
27
+ super('#' + RecordIdentifier.dom_id(selector_or_object), &block)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ # Configure Rails Envinronment
2
+ ENV["RAILS_ENV"] = "test"
3
+
4
+ # To test RailsMetrics, you need to:
5
+ #
6
+ # 1) Install latest bundler with "gem install bundler"
7
+ # 2) bundle install
8
+ # 3) rake prepare
9
+ # 4) rake test
10
+ #
11
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
12
+ require "rails/test_help"
13
+
14
+ ActionMailer::Base.delivery_method = :test
15
+ ActionMailer::Base.perform_deliveries = true
16
+ ActionMailer::Base.default_url_options[:host] = "test.com"
17
+
18
+ Webrat.configure do |config|
19
+ config.mode = :rails
20
+ config.open_error_files = false
21
+ end
22
+
23
+ # Add support to load paths so we can overwrite broken webrat setup
24
+ $:.unshift File.expand_path('../support', __FILE__)
25
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
26
+
27
+ class ActiveSupport::TestCase
28
+ setup do
29
+ wait
30
+ RailsMetrics.set_store { Metric }
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails_metrics
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - "Jos\xC3\xA9 Valim"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-15 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Metrics measurement for your app on top of ActiveSupport::Notifications
17
+ email: contact@engineyard.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - CHANGELOG.rdoc
26
+ - Gemfile
27
+ - MIT-LICENSE
28
+ - README.rdoc
29
+ - Rakefile
30
+ - TODO.rdoc
31
+ - app/controllers/rails_metrics_controller.rb
32
+ - app/helpers/rails_metrics_helper.rb
33
+ - app/views/layouts/rails_metrics.html.erb
34
+ - app/views/rails_metrics/_request.html.erb
35
+ - app/views/rails_metrics/_row.html.erb
36
+ - app/views/rails_metrics/all.html.erb
37
+ - app/views/rails_metrics/chart.html.erb
38
+ - app/views/rails_metrics/index.html.erb
39
+ - app/views/rails_metrics/show.html.erb
40
+ - config/routes.rb
41
+ - lib/generators/rails_metrics_generator.rb
42
+ - lib/rails_metrics.rb
43
+ - lib/rails_metrics/async_consumer.rb
44
+ - lib/rails_metrics/engine.rb
45
+ - lib/rails_metrics/middleware.rb
46
+ - lib/rails_metrics/orm/active_record.rb
47
+ - lib/rails_metrics/payload_parser.rb
48
+ - lib/rails_metrics/store.rb
49
+ - lib/rails_metrics/version.rb
50
+ - public/images/rails_metrics/arrow_down.png
51
+ - public/images/rails_metrics/arrow_up.png
52
+ - public/images/rails_metrics/cancel.png
53
+ - public/images/rails_metrics/chart_pie.png
54
+ - public/images/rails_metrics/page_white_delete.png
55
+ - public/images/rails_metrics/page_white_go.png
56
+ - public/images/rails_metrics/tick.png
57
+ - public/javascripts/rails_metrics/g.pie-min.js
58
+ - public/javascripts/rails_metrics/g.raphael-min.js
59
+ - public/javascripts/rails_metrics/raphael-min.js
60
+ - public/stylesheets/rails_metrics.css
61
+ has_rdoc: true
62
+ homepage: http://github.com/engineyard
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options:
67
+ - --charset=UTF-8
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
81
+ version:
82
+ requirements: []
83
+
84
+ rubyforge_project:
85
+ rubygems_version: 1.3.5
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Metrics measurement for your app on top of ActiveSupport::Notifications
89
+ test_files:
90
+ - test/dummy/app/controllers/application_controller.rb
91
+ - test/dummy/app/controllers/users_controller.rb
92
+ - test/dummy/app/helpers/application_helper.rb
93
+ - test/dummy/app/models/metric.rb
94
+ - test/dummy/app/models/notification.rb
95
+ - test/dummy/app/models/user.rb
96
+ - test/dummy/config/application.rb
97
+ - test/dummy/config/boot.rb
98
+ - test/dummy/config/environment.rb
99
+ - test/dummy/config/environments/development.rb
100
+ - test/dummy/config/environments/production.rb
101
+ - test/dummy/config/environments/test.rb
102
+ - test/dummy/config/initializers/backtrace_silencers.rb
103
+ - test/dummy/config/initializers/cookie_verification_secret.rb
104
+ - test/dummy/config/initializers/session_store.rb
105
+ - test/dummy/config/routes.rb
106
+ - test/dummy/db/migrate/20100106152343_create_metrics.rb
107
+ - test/dummy/db/migrate/20100108120821_create_users.rb
108
+ - test/integration/instrumentation_test.rb
109
+ - test/integration/navigation_test.rb
110
+ - test/orm/active_record_test.rb
111
+ - test/payload_parser_test.rb
112
+ - test/rails_metrics_test.rb
113
+ - test/store_test.rb
114
+ - test/support/helpers.rb
115
+ - test/support/instrumentation.rb
116
+ - test/support/mock_store.rb
117
+ - test/support/webrat/integrations/rails.rb
118
+ - test/test_helper.rb