scout_rails 0.0.4 → 0.0.5.debug1.pre

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,8 @@
1
+ # 0.0.5.pre
2
+
3
+ * Support for custom categories
4
+ * Not raising an exception w/an unbalanced stack
5
+
1
6
  # 0.0.4
2
7
 
3
8
  * Transaction Sampling
@@ -4,6 +4,7 @@ module ScoutRails::Instruments
4
4
  # Instruments the action and tracks errors.
5
5
  def process_action(*args)
6
6
  scout_controller_action = "Controller/#{controller_path}/#{action_name}"
7
+ ScoutRails::Agent.instance.logger.debug "Processing #{scout_controller_action}"
7
8
  self.class.trace(scout_controller_action, :uri => request.fullpath) do
8
9
  begin
9
10
  super
@@ -20,8 +20,10 @@ class ScoutRails::Store
20
20
  # Called when the last stack item completes for the current transaction to clear
21
21
  # for the next run.
22
22
  def reset_transaction!
23
+ Thread::current[:scout_stack_unbalanced] = nil
23
24
  Thread::current[:scout_scope_name] = nil
24
25
  @transaction_hash = Hash.new
26
+ @stack = Array.new
25
27
  end
26
28
 
27
29
  # Called at the start of Tracer#instrument:
@@ -38,7 +40,17 @@ class ScoutRails::Store
38
40
  def stop_recording(sanity_check_item, options={})
39
41
  item = stack.pop
40
42
  stack_empty = stack.empty?
41
- raise "items not equal: #{item.inspect} / #{sanity_check_item.inspect}" if item != sanity_check_item
43
+ # unbalanced stack - if it's unbalanced, the item is popped but nothing happens.
44
+ if Thread::current[:scout_stack_unbalanced]
45
+ return
46
+ end
47
+ # unbalanced stack check - unreproducable cases have seen this occur. when it does, sets a Thread variable
48
+ # so we ignore further recordings. +Store#reset_transaction!+ resets this.
49
+ if item != sanity_check_item
50
+ ScoutRails::Agent.instance.logger.warn "Scope [#{Thread::current[:scout_scope_name]}] Popped off stack: #{item.inspect} Expected: #{sanity_check_item.inspect}. Aborting."
51
+ Thread::current[:scout_stack_unbalanced] = true
52
+ return
53
+ end
42
54
  duration = Time.now - item.start_time
43
55
  if last=stack.last
44
56
  last.children_time += duration
@@ -56,9 +68,11 @@ class ScoutRails::Store
56
68
  transaction_hash[meta] = stat
57
69
 
58
70
  if stack_empty
71
+ ScoutRails::Agent.instance.logger.debug "Stop Recording: #{meta.metric_name}"
72
+
59
73
  aggs=aggregate_calls(transaction_hash.dup,meta)
60
74
  store_sample(options[:uri],transaction_hash.dup.merge(aggs),meta,stat)
61
- # ugly attempt to see if deep dup is the issue
75
+ # deep duplicate
62
76
  duplicate = aggs.dup
63
77
  duplicate.each_pair do |k,v|
64
78
  duplicate[k.dup] = v.dup
@@ -67,9 +81,21 @@ class ScoutRails::Store
67
81
  end
68
82
  end
69
83
 
84
+ # Returns the top-level category names used in the +metrics+ hash.
85
+ def categories(metrics)
86
+ cats = Set.new
87
+ metrics.keys.each do |meta|
88
+ next if meta.scope.nil? # ignore controller
89
+ if match=meta.metric_name.match(/\A([\w|\d]+)\//)
90
+ cats << match[1]
91
+ end
92
+ end # metrics.each
93
+ cats
94
+ end
95
+
70
96
  # Takes a metric_hash of calls and generates aggregates for ActiveRecord and View calls.
71
97
  def aggregate_calls(metrics,parent_meta)
72
- categories = %w(ActiveRecord View)
98
+ categories = categories(metrics)
73
99
  aggregates = {}
74
100
  categories.each do |cat|
75
101
  agg_meta=ScoutRails::MetricMeta.new("#{cat}/all")
@@ -21,12 +21,16 @@ module ScoutRails::Tracer
21
21
  def trace(metric_name, options = {}, &block)
22
22
  ScoutRails::Agent.instance.store.reset_transaction!
23
23
  instrument(metric_name, options) do
24
+ ScoutRails::Agent.instance.logger.debug "Instrumenting #{metric_name}"
24
25
  Thread::current[:scout_scope_name] = metric_name
25
26
  yield
26
27
  Thread::current[:scout_scope_name] = nil
27
28
  end
28
29
  end
29
30
 
31
+ # Options:
32
+ # - :scope => If specified, sets the sub-scope for the metric. We allow additional scope level. This is used
33
+ # when rendering the transaction tree in the UI.
30
34
  def instrument(metric_name, options={}, &block)
31
35
  if options.delete(:scope)
32
36
  Thread::current[:scout_sub_scope] = metric_name
@@ -41,6 +45,7 @@ module ScoutRails::Tracer
41
45
  end
42
46
 
43
47
  def instrument_method(method,options = {})
48
+ ScoutRails::Agent.instance.logger.info "Instrumenting #{method}"
44
49
  metric_name = options[:metric_name] || default_metric_name(method)
45
50
  return if !instrumentable?(method) or instrumented?(method,metric_name)
46
51
  class_eval instrumented_method_string(method, {:metric_name => metric_name, :scope => options[:scope]}), __FILE__, __LINE__
@@ -1,3 +1,3 @@
1
1
  module ScoutRails
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5.debug1.pre"
3
3
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
5
- prerelease:
4
+ version: 0.0.5.debug1.pre
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Derek Haynes
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-06-13 00:00:00.000000000 Z
13
+ date: 2012-06-21 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: Monitors a Ruby on Rails application and reports detailed metrics on
16
16
  performance to Scout, a hosted monitoring service.
@@ -61,9 +61,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
61
61
  required_rubygems_version: !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
- - - ! '>='
64
+ - - ! '>'
65
65
  - !ruby/object:Gem::Version
66
- version: '0'
66
+ version: 1.3.1
67
67
  requirements: []
68
68
  rubyforge_project: scout_rails
69
69
  rubygems_version: 1.8.10