fiveruns-dash-rails 0.7.8 → 0.8.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.
data/README.rdoc CHANGED
@@ -8,11 +8,11 @@ You'll need a Dash account before using this library.
8
8
 
9
9
  This library is released as a gem from the official repository at http://github.com/fiveruns/dash-rails
10
10
 
11
- sudo gem install fiveruns-dash-rails --source 'http://gems.github.com'
11
+ sudo gem install fiveruns-dash-rails --source http://gems.github.com
12
12
 
13
13
  == Usage
14
14
 
15
- See the Ruby Language Guide http://dash.fiveruns.com/help/ruby.html for information on how to use this library.
15
+ See the Dash Ruby support pages http://support.fiveruns.com/faqs/dash/ruby for information on how to use this library.
16
16
 
17
17
  == Authors
18
18
 
@@ -20,7 +20,8 @@ The FiveRuns Development Team & Dash community
20
20
 
21
21
  == Dependencies
22
22
 
23
- * The fiveruns-dash-ruby gem (see http://github.com/fiveruns/dash-ruby)
23
+ * The fiveruns-dash-activerecord gem (http://github.com/fiveruns/dash-activerecord)
24
+ * The fiveruns-dash-ruby gem (http://github.com/fiveruns/dash-ruby)
24
25
  * The json gem (as a dependency for fiveruns-dash-ruby)
25
26
 
26
27
  == Verifying your setup
@@ -53,7 +54,7 @@ The best way to contribute is by sending pull requests via GitHub. The official
53
54
 
54
55
  Please join the dash-users Google group, http://groups.google.com/group/dash-users
55
56
 
56
- You can also contact us via Twitter, Campfire, or email; see the main help page, http://dash.fiveruns.com/help, for details.
57
+ You can also contact us via Twitter, Campfire, or email; see the main help page, http://support.fiveruns.com, for details.
57
58
 
58
59
  == License
59
60
 
data/Rakefile CHANGED
@@ -20,19 +20,14 @@ begin
20
20
  s.homepage = "http://github.com/fiveruns/dash-rails"
21
21
  s.description = "Provides an API to send metrics from Rails applications to the FiveRuns Dash service"
22
22
  s.authors = ["FiveRuns Development Team"]
23
- s.files = FileList['README.rdoc', 'Rakefile', 'version.yml', 'init.rb', "{lib,rails,test}/**/*", ]
24
- s.add_dependency 'fiveruns-dash-ruby', '>= 0.7.1'
23
+ s.files = FileList['README.rdoc', 'Rakefile', 'VERSION.yml', 'init.rb', "{lib,rails,test}/**/*", ]
24
+ s.add_dependency 'fiveruns-dash-ruby', '>= 0.8.1'
25
+ s.add_dependency 'fiveruns-dash-activerecord', '>= 0.8.1'
25
26
  end
26
27
  rescue LoadError
27
28
  puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
28
29
  end
29
30
 
30
- NAME = "dash-rails"
31
- AUTHOR = "FiveRuns Development Team"
32
- EMAIL = "dev@fiveruns.com"
33
- HOMEPAGE = "http://dash.fiveruns.com/"
34
- SUMMARY = "FiveRuns Dash library for Ruby on Rails"
35
-
36
31
  task :coverage do
37
32
  rm_f "coverage"
38
33
  rm_f "coverage.data"
@@ -0,0 +1,44 @@
1
+ module Fiveruns::Dash::Rails::Context
2
+
3
+ module Action
4
+
5
+ def self.included(base)
6
+ base.send(:include, InstanceMethods)
7
+ base.alias_method_chain :perform_action, :fiveruns_dash_context
8
+ base.extend(ClassMethods)
9
+ (class << base; self; end).alias_method_chain :process, :fiveruns_dash_tracing
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ def process_with_fiveruns_dash_tracing(*args, &block)
15
+ operation = lambda { process_without_fiveruns_dash_tracing(*args, &block) }
16
+ params = args.first.parameters
17
+ # TODO/FIXME: For now, we simply look for a 'trace' parameter to select requests to trace; in the
18
+ # future, we need a more advanced sampling mechanism (some operation in a recipe a
19
+ # request must pass, or selection criteria returned in a response from the service)
20
+ trace_context = ['action', "#{params['controller'].camelize}Controller##{params['action']}"]
21
+ if ::Fiveruns::Dash.trace_contexts.include?(trace_context)
22
+ ::Fiveruns::Dash.session.trace(trace_context) do
23
+ operation.call
24
+ end
25
+ else
26
+ operation.call
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ module InstanceMethods
33
+
34
+ def perform_action_with_fiveruns_dash_context(*args, &block)
35
+ action_name = (request.parameters['action'] || 'index').to_s
36
+ Fiveruns::Dash::Context.set ['action', %(#{self.class.name}##{action_name})]
37
+ perform_action_without_fiveruns_dash_context(*args, &block)
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,62 @@
1
+ module Fiveruns::Dash::Rails::Context
2
+
3
+ module ActiveRecord
4
+
5
+ def self.included(base)
6
+ class << base
7
+ Fiveruns::Dash::ActiveRecord::CLASS_METHODS.each do |meth|
8
+ head = meth
9
+ tail = ''
10
+ head, tail = meth[0..(meth.length-2)], meth[-1..-1] if %w(? !).include? meth[-1..-1]
11
+ self.class_eval <<-EOM
12
+ def #{head}_with_dash_context#{tail}(*args, &block)
13
+ Fiveruns::Dash::Rails::Context::ActiveRecord.with_model_context(self.name) do
14
+ #{head}_without_dash_context#{tail}(*args, &block)
15
+ end
16
+ end
17
+ EOM
18
+ alias_method_chain(meth.to_sym, :dash_context)
19
+ end
20
+ end
21
+
22
+ Fiveruns::Dash::ActiveRecord::INSTANCE_METHODS.each do |meth|
23
+ head = meth
24
+ tail = ''
25
+ head, tail = meth[0..meth.length-2], meth[-1..-1] if %w(? !).include? meth[-1..-1]
26
+ base.class_eval <<-EOM
27
+ def #{head}_with_dash_context#{tail}(*args, &block)
28
+ Fiveruns::Dash::Rails::Context::ActiveRecord.with_model_context(self.class.name) do
29
+ #{head}_without_dash_context#{tail}(*args, &block)
30
+ end
31
+ end
32
+ EOM
33
+ base.alias_method_chain(meth.to_sym, :dash_context)
34
+ end
35
+ end
36
+
37
+ def self.with_model_context(model_name)
38
+ context = Fiveruns::Dash::Context.context
39
+ # don't change context if model context has already been set.
40
+ if context.size > 0 && context[-2] == 'model' && context[-1] == model_name
41
+ return yield
42
+ end
43
+
44
+ original_context = Fiveruns::Dash::Context.context.dup
45
+ begin
46
+ if context[-2] == 'model'
47
+ # Some models will internally load other models.
48
+ Fiveruns::Dash::Context.context.pop
49
+ Fiveruns::Dash::Context.context << model_name
50
+ else
51
+ Fiveruns::Dash::Context.context << 'model'
52
+ Fiveruns::Dash::Context.context << model_name
53
+ end
54
+ return yield
55
+ ensure
56
+ Fiveruns::Dash::Context.set original_context
57
+ end
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,57 @@
1
+ module Fiveruns::Dash::Rails::Context
2
+
3
+ module Template
4
+
5
+ def self.included(base)
6
+ base.send(:include, InstanceMethods)
7
+ base.alias_method_chain(:render, :fiveruns_dash_context)
8
+ end
9
+
10
+ RAILS_ROOT_RE = /\A#{Regexp.quote RAILS_ROOT}/
11
+
12
+ GEM_REs = Gem.path.map do |path|
13
+ /\A#{Regexp.quote path}\/gems/
14
+ end
15
+
16
+ def self.sanitize_view_path(path)
17
+ path = if path[0..0] == '/'
18
+ if path =~ RAILS_ROOT_RE
19
+ trimmed = path.sub(RAILS_ROOT_RE, 'RAILS_ROOT')
20
+ trimmed
21
+ elsif (re = GEM_REs.find { |re| path =~ re })
22
+ trimmed = path.sub(re, 'GEMS')
23
+ else
24
+ path
25
+ end
26
+ else
27
+ path
28
+ end
29
+ # Remove extensions, if any
30
+ path.sub(/\.[^\/\\]*$/, '')
31
+ end
32
+
33
+ module InstanceMethods
34
+
35
+ def render_with_fiveruns_dash_context(*args, &block)
36
+ original_context = Fiveruns::Dash::Context.context.dup
37
+
38
+ begin
39
+ Fiveruns::Dash::Context.context << 'view'
40
+ if respond_to?(:path)
41
+ Fiveruns::Dash::Context.context << Fiveruns::Dash::Rails::Context::Template.sanitize_view_path(path)
42
+ else
43
+ Fiveruns::Dash::Context.context << '(inline)'
44
+ end
45
+ result = render_without_fiveruns_dash_context(*args, &block)
46
+ ensure
47
+ Fiveruns::Dash::Context.set original_context
48
+ end
49
+
50
+ result
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,17 @@
1
+ module Fiveruns::Dash::Rails::Initializer
2
+
3
+ def self.included(base)
4
+ base.send(:include, InstanceMethods)
5
+ base.alias_method_chain :prepare_dispatcher, :dash
6
+ end
7
+
8
+ module InstanceMethods
9
+
10
+ def prepare_dispatcher_with_dash
11
+ prepare_dispatcher_without_dash
12
+ Fiveruns::Dash::Rails.dash_start_block.call
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -1,4 +1,3 @@
1
- require File.dirname(__FILE__) << "/rails/version"
2
1
  require File.dirname(__FILE__) << "/rails/startup"
3
2
 
4
3
  if START_FIVERUNS_DASH_RAILS
@@ -7,10 +6,29 @@ if START_FIVERUNS_DASH_RAILS
7
6
  module Dash
8
7
 
9
8
  module Rails
9
+
10
+ version_file = File.dirname(__FILE__) << "/../../../VERSION.yml"
11
+ version = YAML.load(version_file)
12
+ VERSION = [
13
+ version[:major],
14
+ version[:minor],
15
+ version[:patch]
16
+ ].map(&:to_s).join('.')
10
17
 
11
18
  class << self
12
19
  attr_accessor :server
13
20
  end
21
+
22
+ def self.clean_hash(obj = {})
23
+ (obj || {}).keys.inject({}) do |all, key|
24
+ val = obj[key]
25
+ if val.is_a?(Hash)
26
+ val = clean(val)
27
+ end
28
+ all[key.to_s] = val
29
+ all
30
+ end
31
+ end
14
32
 
15
33
  def self.queue_size
16
34
  return 0 unless server_type
@@ -50,7 +68,6 @@ if START_FIVERUNS_DASH_RAILS
50
68
  store_dash_start_block do
51
69
  configure(tokens, &block) unless tokens.empty?
52
70
  if Fiveruns::Dash.configuration.ready?
53
- RAILS_DEFAULT_LOGGER.info "Starting Dash"
54
71
  Fiveruns::Dash.session.start
55
72
  else
56
73
  log_error unless env == 'development'
@@ -79,14 +96,14 @@ if START_FIVERUNS_DASH_RAILS
79
96
  def self.log_error
80
97
  # TODO: Add URL for help
81
98
  message =<<-EOM
82
- FiveRuns Dash [Rails] (v#{Version::STRING}) Application token missing
99
+ FiveRuns Dash [Rails] (v#{VERSION}) Application token missing
83
100
  ===
84
- In config/initializers/dash.rb or at the bottom of config/environment.rb, please add:
101
+ In config/initializers/dash.rb please add:
85
102
 
86
- Fiveruns::Dash::Rails.configure :#{env} => 'YOUR-#{env.upcase}-ENV-APP-TOKEN-HERE'
103
+ Fiveruns::Dash::Rails.start :#{env} => '#{env.upcase}-APP-TOKEN'
87
104
 
88
105
  You can also set app tokens for other environments (eg, staging), at the same time.
89
- See http://todo/path/to/help for more information
106
+ See http://support.fiveruns.com/faqs/dash/rails for more information
90
107
  ===
91
108
  EOM
92
109
  RAILS_DEFAULT_LOGGER.warn(message.strip)
@@ -157,65 +174,6 @@ if START_FIVERUNS_DASH_RAILS
157
174
  end
158
175
  end
159
176
 
160
- module ActionContext
161
-
162
- def self.included(base)
163
- base.send(:include, InstanceMethods)
164
- base.alias_method_chain :perform_action, :fiveruns_dash_context
165
- base.extend(ClassMethods)
166
- (class << base; self; end).alias_method_chain :process, :fiveruns_dash_tracing
167
- end
168
-
169
- module ClassMethods
170
-
171
- def process_with_fiveruns_dash_tracing(*args, &block)
172
- operation = lambda { process_without_fiveruns_dash_tracing(*args, &block) }
173
- params = args.first.parameters
174
- # TODO/FIXME: For now, we simply look for a 'trace' parameter to select requests to trace; in the
175
- # future, we need a more advanced sampling mechanism (some operation in a recipe a
176
- # request must pass, or selection criteria returned in a response from the service)
177
- trace_context = ['action', "#{params['controller'].camelize}Controller##{params['action']}"]
178
- if ::Fiveruns::Dash.trace_contexts.include?(trace_context)
179
- ::Fiveruns::Dash.session.trace(trace_context) do
180
- operation.call
181
- end
182
- else
183
- operation.call
184
- end
185
- end
186
-
187
- end
188
-
189
- module InstanceMethods
190
-
191
- def perform_action_with_fiveruns_dash_context(*args, &block)
192
- action_name = (request.parameters['action'] || 'index').to_s
193
- Fiveruns::Dash::Context.set ['action', %(#{self.class.name}##{action_name})]
194
- perform_action_without_fiveruns_dash_context(*args, &block)
195
- end
196
-
197
- end
198
-
199
- end
200
-
201
- module Initializer
202
-
203
- def self.included(base)
204
- base.send(:include, InstanceMethods)
205
- base.alias_method_chain :prepare_dispatcher, :dash
206
- end
207
-
208
- module InstanceMethods
209
-
210
- def prepare_dispatcher_with_dash
211
- prepare_dispatcher_without_dash
212
- Fiveruns::Dash::Rails.dash_start_block.call
213
- end
214
-
215
- end
216
-
217
- end
218
-
219
177
  end
220
178
 
221
179
  end
@@ -0,0 +1,15 @@
1
+ Fiveruns::Dash.register_recipe :actionpack, :url => 'http://dash.fiveruns.com' do |recipe|
2
+
3
+ recipe.time :response_time, :method => 'ActionController::Base#perform_action', :mark => true
4
+ recipe.counter :requests, 'Requests', :incremented_by => 'ActionController::Base#perform_action'
5
+
6
+ targets = []
7
+ targets << 'ActionView::Template#render' if defined?(ActionView::Template)
8
+ targets << 'ActionView::PartialTemplate#render' if defined?(ActionView::PartialTemplate)
9
+ if !targets.empty?
10
+ recipe.time :render_time, :method => targets
11
+ else
12
+ Fiveruns::Dash.logger.warn 'Collection of "render_time" unsupported for this version of Rails'
13
+ end
14
+
15
+ end
@@ -1,36 +1,17 @@
1
- module Fiveruns::Dash::Rails::Hash
1
+ # Rails #######################################################################
2
+ Fiveruns::Dash.register_recipe :rails, :url => 'http://dash.fiveruns.com' do |recipe|
2
3
 
3
- def self.clean(extended_hash = {})
4
- (extended_hash || {}).keys.inject({}) do |all, key|
5
- val = extended_hash[key]
6
- if val.kind_of? Hash
7
- val = clean(val)
4
+ recipe.add_recipe :activerecord, :url => 'http://dash.fiveruns.com',
5
+ :total_time => 'response_time'
6
+ recipe.modify :recipe_name => :activerecord, :recipe_url => 'http://dash.fiveruns.com' do |metric|
7
+ metric.find_context_with do |obj, *args|
8
+ if Fiveruns::Dash::Context.context == []
9
+ []
10
+ else
11
+ [[], Fiveruns::Dash::Context.context]
8
12
  end
9
- all[key.to_s] = val
10
- all
11
13
  end
12
14
  end
13
-
14
- end
15
-
16
- # ActionPack ##################################################################
17
- Fiveruns::Dash.register_recipe :actionpack, :url => 'http://dash.fiveruns.com' do |recipe|
18
- recipe.time :response_time, :method => 'ActionController::Base#perform_action', :mark => true
19
- recipe.counter :requests, 'Requests', :incremented_by => 'ActionController::Base#perform_action'
20
-
21
- targets = []
22
- targets << 'ActionView::Template#render' if defined?(ActionView::Template)
23
- targets << 'ActionView::PartialTemplate#render' if defined?(ActionView::PartialTemplate)
24
- if !targets.empty?
25
- recipe.time :render_time, :method => targets
26
- else
27
- Fiveruns::Dash.logger.warn 'Collection of "render_time" unsupported for this version of Rails'
28
- end
29
- end
30
-
31
- # Rails #######################################################################
32
- Fiveruns::Dash.register_recipe :rails, :url => 'http://dash.fiveruns.com' do |recipe|
33
- recipe.add_recipe :activerecord, :url => 'http://dash.fiveruns.com'
34
15
 
35
16
  recipe.add_recipe :actionpack, :url => 'http://dash.fiveruns.com'
36
17
  recipe.modify :recipe_name => :actionpack, :recipe_url => 'http://dash.fiveruns.com' do |metric|
@@ -49,21 +30,21 @@ Fiveruns::Dash.register_recipe :rails, :url => 'http://dash.fiveruns.com' do |re
49
30
  info = {:name => "#{ex.class.name} in #{controller.class.name}##{controller.params[:action]}"}
50
31
  begin
51
32
  session_data = controller.request.session.instance_variable_get("@data")
52
- info[:session] = Fiveruns::Dash::Rails::Hash.clean(session_data).to_json
33
+ info[:session] = Fiveruns::Dash::Rails.clean_hash(session_data).to_json
53
34
  rescue Exception => e
54
35
  Fiveruns::Dash.logger.warn "Could not dump session data for exception: #{e.message}"
55
36
  nil
56
37
  end
57
38
  begin
58
39
  request_data = { :url => controller.request.url, :params => controller.params.inspect }
59
- info[:request] = Fiveruns::Dash::Rails::Hash.clean(request_data).to_json
40
+ info[:request] = Fiveruns::Dash::Rails.clean_hash(request_data).to_json
60
41
  rescue Exception => e
61
42
  Fiveruns::Dash.logger.error "Could not dump request data for exception: #{e.message}"
62
43
  nil
63
44
  end
64
45
  begin
65
46
  header_data = controller.request.headers
66
- info[:headers] = Fiveruns::Dash::Rails::Hash.clean(header_data).to_json
47
+ info[:headers] = Fiveruns::Dash::Rails.clean_hash(header_data).to_json
67
48
  rescue Exception => e
68
49
  Fiveruns::Dash.logger.error "Could not dump header data for exception: #{e.message}"
69
50
  nil
@@ -72,17 +53,21 @@ Fiveruns::Dash.register_recipe :rails, :url => 'http://dash.fiveruns.com' do |re
72
53
  end
73
54
 
74
55
  # Same classes as the exception_notification plugin
75
- IGNORE = [ActiveRecord::RecordNotFound, ActionController::RoutingError, ActionController::UnknownController, ActionController::UnknownAction]
76
-
77
- recipe.ignore_exceptions do |exc|
78
- IGNORE.include? exc.class
56
+ recipe.ignore_exceptions do |exception|
57
+ [ ActiveRecord::RecordNotFound,
58
+ ActionController::RoutingError,
59
+ ActionController::UnknownController,
60
+ ActionController::UnknownAction
61
+ ].include?(exception.class)
79
62
  end
80
63
 
81
64
  recipe.added do
82
- ActionController::Base.send(:include, Fiveruns::Dash::Rails::ActionContext)
83
- ActionView::Template.send(:include, Fiveruns::Dash::Rails::TemplateContext) if defined?(ActionView::Template)
84
- ActionView::InlineTemplate.send(:include, Fiveruns::Dash::Rails::TemplateContext) if defined?(ActionView::InlineTemplate)
85
- ActionView::PartialTemplate.send(:include, Fiveruns::Dash::Rails::TemplateContext) if defined?(ActionView::PartialTemplate)
65
+
66
+ ActiveRecord::Base.send(:include, Fiveruns::Dash::Rails::Context::ActiveRecord)
67
+ ActionController::Base.send(:include, Fiveruns::Dash::Rails::Context::Action)
68
+ ActionView::Template.send(:include, Fiveruns::Dash::Rails::Context::Template) if defined?(ActionView::Template)
69
+ ActionView::InlineTemplate.send(:include, Fiveruns::Dash::Rails::Context::Template) if defined?(ActionView::InlineTemplate)
70
+ ActionView::PartialTemplate.send(:include, Fiveruns::Dash::Rails::Context::Template) if defined?(ActionView::PartialTemplate)
86
71
 
87
72
  begin
88
73
  if defined?(Mongrel)
@@ -105,19 +90,23 @@ Fiveruns::Dash.register_recipe :rails, :url => 'http://dash.fiveruns.com' do |re
105
90
  end
106
91
  end
107
92
 
108
- # Passenger forks the Rails processes, which has the side effect of
109
- # killing our reporter thread. We need to revive the thread.
110
- class ActionController::Base
111
- def perform_action_with_dash_startup(*args, &block)
93
+ if defined?(Passenger)
94
+ # Passenger forks the Rails processes, which has the side effect of
95
+ # killing our reporter thread. We need to revive the thread.
96
+ class ActionController::Base
97
+ def perform_action_with_dash_startup(*args, &block)
98
+ Fiveruns::Dash.session.reporter.revive!
99
+ perform_action_without_dash_startup(*args, &block)
100
+ end
101
+
102
+ alias_method_chain :perform_action, :dash_startup
103
+ end
104
+ elsif defined?(PhusionPassenger)
105
+ # Passenger 2.1+ has an event to handle this gracefully
106
+ PhusionPassenger.on_event(:starting_worker_process) do
112
107
  Fiveruns::Dash.session.reporter.revive!
113
- perform_action_without_dash_startup(*args, &block)
114
108
  end
115
-
116
- alias_method_chain :perform_action, :dash_startup
117
109
  end
118
110
  end
119
111
 
120
- recipe.absolute :queue_size do
121
- Fiveruns::Dash::Rails.queue_size || 0
122
- end
123
112
  end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) << "/fiveruns/dash/rails/startup"
2
+
3
+ if START_FIVERUNS_DASH_RAILS
4
+ gem 'fiveruns-dash-ruby' # Put its path first
5
+ require 'fiveruns/dash'
6
+ begin
7
+ require 'fiveruns/dash/activerecord'
8
+ rescue LoadError
9
+ abort "Missing the `activerecord' recipe. Please install the fiveruns-dash-activerecord gem"
10
+ end
11
+ require 'fiveruns/dash/rails'
12
+ require 'fiveruns/dash/rails/initializer'
13
+ require 'fiveruns/dash/rails/context/action'
14
+ require 'fiveruns/dash/rails/context/active_record'
15
+ require 'fiveruns/dash/rails/context/template'
16
+ require File.dirname(__FILE__) << "/../rails/init"
17
+ end
@@ -1,9 +1,2 @@
1
- require File.dirname(__FILE__) << "/fiveruns/dash/rails/startup"
2
-
3
- if START_FIVERUNS_DASH_RAILS
4
- gem 'fiveruns-dash-ruby' # Put its path first
5
- require 'fiveruns/dash'
6
- require 'fiveruns/dash/rails'
7
- require 'fiveruns/dash/template_context'
8
- require File.dirname(__FILE__) << "/../rails/init"
9
- end
1
+ # Stub for backwards compatibility
2
+ require File.dirname(__FILE__) << "/fiveruns-dash-rails"
data/rails/init.rb CHANGED
@@ -20,7 +20,7 @@ end
20
20
 
21
21
  if START_FIVERUNS_DASH_RAILS
22
22
 
23
- require 'fiveruns_dash_rails'
23
+ require 'fiveruns-dash-rails'
24
24
  Fiveruns::Dash.logger = RAILS_DEFAULT_LOGGER
25
25
  Fiveruns::Dash::Rails.load_recipes
26
26
  Fiveruns::Dash.configure do |config|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fiveruns-dash-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.8
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - FiveRuns Development Team
@@ -9,17 +9,28 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-02-11 00:00:00 -08:00
12
+ date: 2009-02-20 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: fiveruns-dash-ruby
17
+ type: :runtime
17
18
  version_requirement:
18
19
  version_requirements: !ruby/object:Gem::Requirement
19
20
  requirements:
20
21
  - - ">="
21
22
  - !ruby/object:Gem::Version
22
- version: 0.7.1
23
+ version: 0.8.1
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: fiveruns-dash-activerecord
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.8.1
23
34
  version:
24
35
  description: Provides an API to send metrics from Rails applications to the FiveRuns Dash service
25
36
  email: dev@fiveruns.com
@@ -32,22 +43,24 @@ extra_rdoc_files: []
32
43
  files:
33
44
  - README.rdoc
34
45
  - Rakefile
35
- - version.yml
46
+ - VERSION.yml
36
47
  - init.rb
37
48
  - lib/fiveruns
38
49
  - lib/fiveruns/dash
39
50
  - lib/fiveruns/dash/rails
51
+ - lib/fiveruns/dash/rails/context
52
+ - lib/fiveruns/dash/rails/context/action.rb
53
+ - lib/fiveruns/dash/rails/context/active_record.rb
54
+ - lib/fiveruns/dash/rails/context/template.rb
55
+ - lib/fiveruns/dash/rails/initializer.rb
40
56
  - lib/fiveruns/dash/rails/startup.rb
41
- - lib/fiveruns/dash/rails/version.rb
42
57
  - lib/fiveruns/dash/rails.rb
43
58
  - lib/fiveruns/dash/recipes
44
- - lib/fiveruns/dash/recipes/activerecord.rb
59
+ - lib/fiveruns/dash/recipes/actionpack.rb
45
60
  - lib/fiveruns/dash/recipes/rails.rb
46
- - lib/fiveruns/dash/template_context.rb
61
+ - lib/fiveruns-dash-rails.rb
47
62
  - lib/fiveruns_dash_rails.rb
48
63
  - rails/init.rb
49
- - test/activerecord_test.rb
50
- - test/test_helper.rb
51
64
  has_rdoc: true
52
65
  homepage: http://github.com/fiveruns/dash-rails
53
66
  post_install_message:
@@ -1,97 +0,0 @@
1
- # (The MIT License)
2
- #
3
- # Copyright (c) 2008 Jamis Buck <jamis@37signals.com>,
4
- # with modifications by Bruce Williams <bruce@fiveruns.com>
5
- #
6
- # Permission is hereby granted, free of charge, to any person obtaining
7
- # a copy of this software and associated documentation files (the
8
- # 'Software'), to deal in the Software without restriction, including
9
- # without limitation the rights to use, copy, modify, merge, publish,
10
- # distribute, sublicense, and/or sell copies of the Software, and to
11
- # permit persons to whom the Software is furnished to do so, subject to
12
- # the following conditions:
13
- #
14
- # The above copyright notice and this permission notice shall be
15
- # included in all copies or substantial portions of the Software.
16
- #
17
- # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
- # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
- # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
- # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
- # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
- module Fiveruns
25
-
26
- module Dash
27
-
28
- module Rails
29
-
30
- # A class for describing the current version of a library. The version
31
- # consists of three parts: the +major+ number, the +minor+ number, and the
32
- # +tiny+ (or +patch+) number.
33
- class Version
34
-
35
- include Comparable
36
-
37
- # A convenience method for instantiating a new Version instance with the
38
- # given +major+, +minor+, and +tiny+ components.
39
- def self.[](major, minor, tiny)
40
- new(major, minor, tiny)
41
- end
42
-
43
- # Borrowed from TuneUp
44
- def self.rails
45
- @rails ||= begin
46
- # handle ::Rails::VERSION not being set
47
- Version.new(::Rails::VERSION::MAJOR, ::Rails::VERSION::MINOR, ::Rails::VERSION::TINY) rescue Version.new(0,0,0)
48
- end
49
- end
50
-
51
-
52
- attr_reader :major, :minor, :tiny
53
-
54
- # Create a new Version object with the given components.
55
- def initialize(major, minor, tiny)
56
- @major, @minor, @tiny = major, minor, tiny
57
- end
58
-
59
- # Compare this version to the given +version+ object.
60
- def <=>(version)
61
- to_i <=> version.to_i
62
- end
63
-
64
- # Converts this version object to a string, where each of the three
65
- # version components are joined by the '.' character. E.g., 2.0.0.
66
- def to_s
67
- @to_s ||= [@major, @minor, @tiny].join(".")
68
- end
69
-
70
- # Converts this version to a canonical integer that may be compared
71
- # against other version objects.
72
- def to_i
73
- @to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
74
- end
75
-
76
- def to_a
77
- [@major, @minor, @tiny]
78
- end
79
-
80
- PARSED = YAML.load(File.read(File.dirname(__FILE__) << "/../../../../version.yml"))
81
-
82
- MAJOR = PARSED[:major]
83
- MINOR = PARSED[:minor]
84
- TINY = PARSED[:patch]
85
-
86
- # The current version as a Version instance
87
- CURRENT = new(MAJOR, MINOR, TINY)
88
- # The current version as a String
89
- STRING = CURRENT.to_s
90
-
91
- end
92
-
93
- end
94
-
95
- end
96
-
97
- end
@@ -1,96 +0,0 @@
1
- module Fiveruns::Dash::ActiveRecordContext
2
- CLASS_METHODS = %w(find find_by_sql calculate create create! update_all destroy destroy_all delete delete_all)
3
- INSTANCE_METHODS = %w(update save save! destroy)
4
-
5
- def self.included(base)
6
- class << base
7
- CLASS_METHODS.each do |meth|
8
- head = meth
9
- tail = ''
10
- head, tail = meth[0..(meth.length-2)], meth[-1..-1] if %w(? !).include? meth[-1..-1]
11
- self.class_eval <<-EOM
12
- def #{head}_with_dash_context#{tail}(*args, &block)
13
- Fiveruns::Dash::ActiveRecordContext.with_model_context(self.name) do
14
- #{head}_without_dash_context#{tail}(*args, &block)
15
- end
16
- end
17
- EOM
18
- alias_method_chain(meth.to_sym, :dash_context)
19
- end
20
- end
21
-
22
- INSTANCE_METHODS.each do |meth|
23
- head = meth
24
- tail = ''
25
- head, tail = meth[0..meth.length-2], meth[-1..-1] if %w(? !).include? meth[-1..-1]
26
- base.class_eval <<-EOM
27
- def #{head}_with_dash_context#{tail}(*args, &block)
28
- Fiveruns::Dash::ActiveRecordContext.with_model_context(self.class.name) do
29
- #{head}_without_dash_context#{tail}(*args, &block)
30
- end
31
- end
32
- EOM
33
- base.alias_method_chain(meth.to_sym, :dash_context)
34
- end
35
- end
36
-
37
- def self.with_model_context(model_name)
38
- ctx = Fiveruns::Dash::Context.context
39
- # don't change context if model context has already been set.
40
- return yield if ctx.size > 0 && ctx[-2] == 'model' && ctx[-1] == model_name
41
-
42
- original_context = Fiveruns::Dash::Context.context.dup
43
- begin
44
- if ctx[-2] == 'model'
45
- # Some models will internally load other models.
46
- Fiveruns::Dash::Context.context.pop
47
- Fiveruns::Dash::Context.context << model_name
48
- else
49
- Fiveruns::Dash::Context.context << 'model'
50
- Fiveruns::Dash::Context.context << model_name
51
- end
52
- return yield
53
- ensure
54
- Fiveruns::Dash::Context.set original_context
55
- end
56
- end
57
-
58
- def self.all_methods
59
- CLASS_METHODS.map { |m| "ActiveRecord::Base.#{m}" } + INSTANCE_METHODS.map { |m| "ActiveRecord::Base##{m}"}
60
- end
61
-
62
- end
63
-
64
- # ActiveRecord ################################################################
65
-
66
- Fiveruns::Dash.register_recipe :activerecord, :url => 'http://dash.fiveruns.com' do |recipe|
67
- # We need a way to get the total time for a request/operation so that we can
68
- # calculate the relative percentage used by AR/DB. Default to "response_time" for the Rails
69
- # recipe but daemons can set this constant to provide their own total time metric.
70
- total_time = recipe.options[:ar_total_time] ? recipe.options[:ar_total_time] : "response_time"
71
-
72
- recipe.time :ar_time, 'ActiveRecord Time', :methods => Fiveruns::Dash::ActiveRecordContext.all_methods, :reentrant => true, :only_within => total_time
73
- recipe.time :db_time, 'Database Time', :methods => %w(ActiveRecord::ConnectionAdapters::AbstractAdapter#log), :only_within => total_time
74
-
75
- recipe.percentage :ar_util, 'ActiveRecord Utilization', :sources => ["ar_time", total_time] do |ar_time, all_time|
76
- all_time == 0 ? 0 : (ar_time / all_time) * 100.0
77
- end
78
- recipe.percentage :db_util, 'Database Utilization', :sources => ["db_time", total_time] do |db_time, all_time|
79
- all_time == 0 ? 0 : (db_time / all_time) * 100.0
80
- end
81
-
82
- recipe.modify :recipe_name => :activerecord, :recipe_url => 'http://dash.fiveruns.com' do |metric|
83
- metric.find_context_with do |obj, *args|
84
- if Fiveruns::Dash::Context.context == []
85
- []
86
- else
87
- [[], Fiveruns::Dash::Context.context]
88
- end
89
- end
90
- end
91
-
92
- recipe.added do
93
- ActiveRecord::Base.send(:include, Fiveruns::Dash::ActiveRecordContext)
94
- end
95
- end
96
-
@@ -1,54 +0,0 @@
1
-
2
- module Fiveruns::Dash::Rails::TemplateContext
3
-
4
- def self.included(base)
5
- base.send(:include, InstanceMethods)
6
- base.alias_method_chain(:render, :fiveruns_dash_context)
7
- end
8
-
9
- RAILS_ROOT_RE = /\A#{Regexp.quote RAILS_ROOT}/
10
-
11
- GEM_REs = Gem.path.map do |path|
12
- /\A#{Regexp.quote path}\/gems/
13
- end
14
-
15
- def self.sanitize_view_path(path)
16
- path = if path[0..0] == '/'
17
- if path =~ RAILS_ROOT_RE
18
- trimmed = path.sub(RAILS_ROOT_RE, 'RAILS_ROOT')
19
- trimmed
20
- elsif (re = GEM_REs.find { |re| path =~ re })
21
- trimmed = path.sub(re, 'GEMS')
22
- else
23
- path
24
- end
25
- else
26
- path
27
- end
28
- # Remove extensions, if any
29
- path.sub(/\.[^\/\\]*$/, '')
30
- end
31
-
32
- module InstanceMethods
33
-
34
- def render_with_fiveruns_dash_context(*args, &block)
35
- original_context = Fiveruns::Dash::Context.context.dup
36
-
37
- begin
38
- Fiveruns::Dash::Context.context << 'view'
39
- if respond_to?(:path)
40
- Fiveruns::Dash::Context.context << Fiveruns::Dash::Rails::TemplateContext.sanitize_view_path(path)
41
- else
42
- Fiveruns::Dash::Context.context << '(inline)'
43
- end
44
- result = render_without_fiveruns_dash_context(*args, &block)
45
- ensure
46
- Fiveruns::Dash::Context.set original_context
47
- end
48
-
49
- result
50
- end
51
-
52
- end
53
-
54
- end
@@ -1,113 +0,0 @@
1
- require File.dirname(__FILE__) << "/test_helper"
2
-
3
- class ActiverecordTest < Test::Unit::TestCase
4
-
5
- class TestModel < ActiveRecord::Base
6
- end
7
-
8
- class TestEngine
9
- def doit
10
- sleep 1
11
- 2.times do
12
- t = TestModel.create!(:name => 'foo')
13
- t.destroy
14
- end
15
- end
16
-
17
- def conn
18
- TestModel.connection.execute("select sleep(1)")
19
- end
20
-
21
- def entry(meth)
22
- send(meth)
23
- end
24
- end
25
-
26
-
27
- context "Metric" do
28
-
29
- setup do
30
- ActiveRecord::Base.configurations = { 'test' => { 'database' => 'test', 'adapter' => 'mysql', 'user' => 'root', 'hostname' => 'localhost' }}
31
- ActiveRecord::Base.establish_connection
32
- ActiveRecord::Base.connection.execute("create table if not exists test_models (id integer PRIMARY KEY, name varchar(32) not null)")
33
- ActiveRecord::Base.connection.execute("delete from test_models")
34
- end
35
-
36
- should "collect basic AR metrics" do
37
- ar_scenario do
38
- TestEngine.new.entry(:doit)
39
-
40
- data = Fiveruns::Dash.session.data
41
- # data.each do |hsh|
42
- # puts "#{hsh[:name]}: #{hsh[:values].inspect}"
43
- # end
44
-
45
- assert metric('test_time', data) > 1.0
46
- assert metric('ar_util', data) > metric('db_util', data)
47
- assert metric('db_util', data) < 5
48
- end
49
- end
50
-
51
- should "collect DB metrics" do
52
- ar_scenario do
53
- TestEngine.new.entry(:conn)
54
-
55
- data = Fiveruns::Dash.session.data
56
- # data.each do |hsh|
57
- # puts "#{hsh[:name]}: #{hsh[:values].inspect}"
58
- # end
59
-
60
- assert metric('test_time', data) > 1.0
61
- assert metric('test_time', data) < 1.1
62
- assert metric('db_time', data) > 1.0
63
- assert metric('db_time', data) < 1.1
64
- assert metric('db_util', data) > 90.0
65
- assert metric('db_util', data) < 100.0
66
- end
67
- end
68
- end
69
-
70
- def ar_scenario(&block)
71
- child = fork do
72
- mock_activerecord!
73
- yield
74
- end
75
- Process.wait
76
- assert_equal 0, $?.exitstatus
77
- end
78
-
79
- def metric(metric, data, in_ctx=[])
80
- hsh = data.detect { |hsh| hsh[:name] == metric }
81
- assert hsh, "No metric named #{metric} was found in metrics payload"
82
- vals = hsh[:values]
83
- assert vals, "No values found for #{metric} in metrics payload"
84
- val = vals.detect { |val| val[:context] == in_ctx }
85
- assert val, "No value for #{metric} found for context #{in_ctx.inspect}"
86
- val[:value]
87
- end
88
-
89
- def mock_activerecord!
90
- require 'fiveruns/dash'
91
- require 'fiveruns/dash/recipes/activerecord'
92
-
93
- eval <<-MOCK
94
- module Fiveruns::Dash
95
- class Reporter
96
- private
97
- def run
98
- end
99
- end
100
- end
101
- MOCK
102
-
103
- Fiveruns::Dash.register_recipe :tester, :url => 'http://dash.fiveruns.com' do |recipe|
104
- recipe.time :test_time, 'Test Time', :method => 'ActiverecordTest::TestEngine#entry'
105
- end
106
- Fiveruns::Dash.configure :app => '666', :ar_total_time => 'test_time' do |config|
107
- config.add_recipe :ruby
108
- config.add_recipe :activerecord
109
- config.add_recipe :tester
110
- end
111
- Fiveruns::Dash.session.start(true)
112
- end
113
- end
data/test/test_helper.rb DELETED
@@ -1,30 +0,0 @@
1
- RAILS_ENV='test'
2
- RAILS_ROOT=File.dirname(__FILE__)
3
- require 'test/unit'
4
- require 'logger'
5
- require 'rubygems'
6
-
7
- begin
8
- require 'shoulda'
9
- require 'flexmock/test_unit'
10
- require 'fake_web'
11
- rescue
12
- puts "Please install the Shoulda, FakeWeb and flexmock gems to run the Dash plugin tests."
13
- end
14
-
15
- require 'shoulda'
16
- require 'flexmock/test_unit'
17
-
18
- RAILS_DEFAULT_LOGGER=Logger.new(STDOUT)
19
- require 'active_record'
20
- require 'action_controller'
21
- require 'action_controller/test_process'
22
- require 'action_controller/test_case'
23
- require 'action_view'
24
-
25
- $:.unshift(File.dirname(__FILE__) << '/../lib')
26
- $:.unshift(File.dirname(__FILE__) << '/../../fiveruns_dash/lib')
27
-
28
- class Test::Unit::TestCase
29
-
30
- end
data/version.yml DELETED
@@ -1,4 +0,0 @@
1
- ---
2
- :major: 0
3
- :minor: 7
4
- :patch: 8