scout_apm 1.4.3 → 1.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e35b6c5c23a78e589b4756310047fb0bc7ac4adf
4
- data.tar.gz: 5489c84a0cd1a0f3df4ec85a54b9d6a8f34692b3
3
+ metadata.gz: 3f23c7ac5d4eb5fd3377ec8d9c4aa9f57a5fc356
4
+ data.tar.gz: 72c4e84ceeae582c401e30343c0f0594c79036cc
5
5
  SHA512:
6
- metadata.gz: 1786feaa5c35aa342e8d4e805d923754cb37de844f396cba10e66b56c341ea9facf9e8d8fec90c33ce23c3fda4fc062325c2adc7096ee7cf6a9a2bd3f0e31e33
7
- data.tar.gz: 85c19b4db97a36905e497db1c2e70bad95ab528d656db5f29378b55b53c5fdc256ce83bfa14f297bbdf47be21dacbbfcc999da7a55e6f78042d8707200c55b6d
6
+ metadata.gz: 7ae0882e14379a6a1d87923f20500fa9508cc8e63438788db0d9ee98ae773413a2f3a3d1aef9fee9977447cda1f10593f91de92837b8ee168e7a18c058b023ab
7
+ data.tar.gz: 93197ba1fdf634b6ccf399ba1e73363abc21d0604ae71f75537f5280e50480855c280b4f11690be2c32d8e780a85011d5f8ac3f49fe6e256a138c7b71c9e5ea6
data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,8 @@
1
+ # 1.4.4
2
+
3
+ * Instrument Mongoid
4
+ * Instrument Redis
5
+
1
6
  # 1.4.3
2
7
 
3
8
  * Add a to_s call to have HTTPClient work with URI objects. Thanks to Nicolai for providing the change!
data/Rakefile CHANGED
@@ -8,3 +8,12 @@ task :test do
8
8
  Dir.glob('./test/**/*_test.rb').each { |file| require file }
9
9
  end
10
10
 
11
+
12
+ desc "IRB with this gem required"
13
+ task :console do
14
+ require 'irb'
15
+ require 'irb/completion'
16
+ require 'scout_apm'
17
+ ARGV.clear
18
+ IRB.start
19
+ end
data/lib/scout_apm.rb CHANGED
@@ -62,6 +62,7 @@ require 'scout_apm/instruments/net_http'
62
62
  require 'scout_apm/instruments/http_client'
63
63
  require 'scout_apm/instruments/moped'
64
64
  require 'scout_apm/instruments/mongoid'
65
+ require 'scout_apm/instruments/redis'
65
66
  require 'scout_apm/instruments/delayed_job'
66
67
  require 'scout_apm/instruments/active_record'
67
68
  require 'scout_apm/instruments/action_controller_rails_2'
@@ -253,6 +253,7 @@ module ScoutApm
253
253
  install_instrument(ScoutApm::Instruments::Mongoid)
254
254
  install_instrument(ScoutApm::Instruments::NetHttp)
255
255
  install_instrument(ScoutApm::Instruments::HttpClient)
256
+ install_instrument(ScoutApm::Instruments::Redis)
256
257
 
257
258
  if StackProf.respond_to?(:fake?) && StackProf.fake?
258
259
  logger.info 'StackProf not found - add `gem "stackprof"` to your Gemfile to enable advanced code profiling (only for Ruby 2.1+)'
@@ -266,6 +267,14 @@ module ScoutApm
266
267
  def install_instrument(instrument_klass)
267
268
  # Don't attempt to install the same instrument twice
268
269
  return if @installed_instruments.any? { |already_installed_instrument| instrument_klass === already_installed_instrument }
270
+
271
+ # Allow users to skip individual instruments via the config file
272
+ instrument_short_name = instrument_klass.name.split("::").last
273
+ if config.value("disabled_instruments").include?(instrument_short_name)
274
+ logger.info "Skipping Disabled Instrument: #{instrument_short_name} - To re-enable, change `disabled_instruments` key in scout_apm.yml"
275
+ return
276
+ end
277
+
269
278
  instance = instrument_klass.new
270
279
  @installed_instruments << instance
271
280
  instance.install
@@ -27,6 +27,7 @@ module ScoutApm
27
27
  'stackprof_interval' => 20000, # microseconds, 1000 = 1 millisecond, so 20k == 20 milliseconds
28
28
  'uri_reporting' => 'full_path',
29
29
  'report_format' => 'json',
30
+ 'disabled_instruments' => []
30
31
  }.freeze
31
32
 
32
33
  def initialize(config_path = nil)
@@ -22,11 +22,10 @@ module ScoutApm
22
22
  ::Mongoid::Collection.class_eval do
23
23
  include ScoutApm::Tracer
24
24
  (::Mongoid::Collections::Operations::ALL - [:<<, :[]]).each do |method|
25
- instrument_method method, :type => "MongoDB", :name => '#{@klass}/#{method}'
25
+ instrument_method method, :type => "MongoDB", :name => '#{@klass}/' + method.to_s
26
26
  end
27
27
  end
28
28
  end
29
-
30
29
  end
31
30
  end
32
31
  end
@@ -0,0 +1,39 @@
1
+ module ScoutApm
2
+ module Instruments
3
+ class Redis
4
+ attr_reader :logger
5
+
6
+ def initalize(logger=ScoutApm::Agent.instance.logger)
7
+ @logger = logger
8
+ @installed = false
9
+ end
10
+
11
+ def installed?
12
+ @installed
13
+ end
14
+
15
+ def install
16
+ @installed = true
17
+
18
+ if defined?(::Redis) && defined?(::Redis::Client)
19
+ ScoutApm::Agent.instance.logger.info "Instrumenting Redis"
20
+
21
+ ::Redis::Client.class_eval do
22
+ include ScoutApm::Tracer
23
+
24
+ def call_with_scout_instruments(*args, &block)
25
+ command = args.first.first rescue "Unknown"
26
+
27
+ self.class.instrument("Redis", command) do
28
+ call_without_scout_instruments(*args, &block)
29
+ end
30
+ end
31
+
32
+ alias_method :call_without_scout_instruments, :call
33
+ alias_method :call, :call_with_scout_instruments
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -44,33 +44,62 @@ module ScoutApm
44
44
  # Options:
45
45
  # type - "View" or "ActiveRecord" and similar
46
46
  # name - "users/show", "App#find"
47
- def instrument_method(method, options = {})
48
- ScoutApm::Agent.instance.logger.info "Instrumenting #{method}"
47
+ def instrument_method(method_name, options = {})
48
+ ScoutApm::Agent.instance.logger.info "Instrumenting #{method_name}"
49
49
  type = options[:type] || "Custom"
50
- name = options[:name] || "#{self.name}/#{method.to_s}"
50
+ name = options[:name] || "#{self.name}/#{method_name.to_s}"
51
51
 
52
- return if !instrumentable?(method) or instrumented?(method, type, name)
52
+ instrumented_name, uninstrumented_name = _determine_instrumented_name(method_name, type)
53
+
54
+ ScoutApm::Agent.instance.logger.info "Instrumenting #{instrumented_name}, #{uninstrumented_name}"
55
+
56
+ return if !_instrumentable?(method_name) or _instrumented?(instrumented_name, method_name)
53
57
 
54
58
  class_eval(
55
- instrumented_method_string(method, type, name, {:scope => options[:scope] }),
59
+ _instrumented_method_string(instrumented_name, uninstrumented_name, type, name, {:scope => options[:scope] }),
56
60
  __FILE__, __LINE__
57
61
  )
58
62
 
59
- alias_method _uninstrumented_method_name(method, type, name), method
60
- alias_method method, _instrumented_method_name(method, type, name)
63
+ alias_method uninstrumented_name, method_name
64
+ alias_method method_name, instrumented_name
61
65
  end
62
66
 
63
67
  private
64
68
 
65
- def instrumented_method_string(method, type, name, options={})
69
+ def _determine_instrumented_name(method_name, type)
70
+ inst = _find_unused_method_name { _instrumented_method_name(method_name, type) }
71
+ uninst = _find_unused_method_name { _uninstrumented_method_name(method_name, type) }
72
+
73
+ return inst, uninst
74
+ end
75
+
76
+ def _find_unused_method_name
77
+ raw_name = name = yield
78
+
79
+ i = 0
80
+ while method_defined?(name) && i < 100
81
+ i += 1
82
+ name = "#{raw_name}_#{i}"
83
+ end
84
+ name
85
+ end
86
+
87
+ def _instrumented_method_string(instrumented_name, uninstrumented_name, type, name, options={})
66
88
  klass = (self === Module) ? "self" : "self.class"
67
89
  method_str = <<-EOF
68
- def #{_instrumented_method_name(method, type, name)}(*args, &block)
90
+ def #{instrumented_name}(*args, &block)
91
+ name = begin
92
+ "#{name}"
93
+ rescue => e
94
+ ScoutApm::Agent.instance.logger.error("Error raised while interpreting instrumented name: %s, %s" % ['#{name}', e.message])
95
+ "Unknown"
96
+ end
97
+
69
98
  #{klass}.instrument( "#{type}",
70
- "#{name}",
99
+ name,
71
100
  {:scope => #{options[:scope] || false}}
72
101
  ) do
73
- #{_uninstrumented_method_name(method, type, name)}(*args, &block)
102
+ #{uninstrumented_name}(*args, &block)
74
103
  end
75
104
  end
76
105
  EOF
@@ -79,29 +108,29 @@ module ScoutApm
79
108
  end
80
109
 
81
110
  # The method must exist to be instrumented.
82
- def instrumentable?(method)
83
- exists = method_defined?(method) || private_method_defined?(method)
84
- ScoutApm::Agent.instance.logger.warn "The method [#{self.name}##{method}] does not exist and will not be instrumented" unless exists
111
+ def _instrumentable?(method_name)
112
+ exists = method_defined?(method_name) || private_method_defined?(method_name)
113
+ ScoutApm::Agent.instance.logger.warn "The method [#{self.name}##{method_name}] does not exist and will not be instrumented" unless exists
85
114
  exists
86
115
  end
87
116
 
88
117
  # +True+ if the method is already instrumented.
89
- def instrumented?(method, type, name)
90
- instrumented = method_defined?(_instrumented_method_name(method, type, name))
91
- ScoutApm::Agent.instance.logger.warn("The method [#{self.name}##{method}] has already been instrumented") if instrumented
118
+ def _instrumented?(instrumented_name, method_name)
119
+ instrumented = method_defined?(instrumented_name)
120
+ ScoutApm::Agent.instance.logger.warn("The method [#{self.name}##{method_name}] has already been instrumented") if instrumented
92
121
  instrumented
93
122
  end
94
123
 
95
124
  # given a method and a metric, this method returns the
96
125
  # untraced alias of the method name
97
- def _uninstrumented_method_name(method, type, name)
98
- "#{_sanitize_name(method)}_without_scout_instrument_#{_sanitize_name(name)}"
126
+ def _uninstrumented_method_name(method_name, type)
127
+ "#{_sanitize_name(method_name)}_without_scout_instrument"
99
128
  end
100
129
 
101
130
  # given a method and a metric, this method returns the traced
102
131
  # alias of the method name
103
- def _instrumented_method_name(method, type, name)
104
- "#{_sanitize_name(method)}_with_scout_instrument_#{_sanitize_name(name)}"
132
+ def _instrumented_method_name(method_name, type)
133
+ "#{_sanitize_name(method_name)}_with_scout_instrument"
105
134
  end
106
135
 
107
136
  # Method names like +any?+ or +replace!+ contain a trailing character that would break when
@@ -1,4 +1,4 @@
1
1
  module ScoutApm
2
- VERSION = "1.4.3"
2
+ VERSION = "1.4.4"
3
3
  end
4
4
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout_apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3
4
+ version: 1.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Haynes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-03-02 00:00:00.000000000 Z
12
+ date: 2016-03-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -101,6 +101,7 @@ files:
101
101
  - lib/scout_apm/instruments/process/process_cpu.rb
102
102
  - lib/scout_apm/instruments/process/process_memory.rb
103
103
  - lib/scout_apm/instruments/rails_router.rb
104
+ - lib/scout_apm/instruments/redis.rb
104
105
  - lib/scout_apm/instruments/sinatra.rb
105
106
  - lib/scout_apm/layaway.rb
106
107
  - lib/scout_apm/layaway_file.rb