scout_rails 0.0.4 → 0.0.5.debug1.pre

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/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