scout_apm 2.1.1 → 2.1.2

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: 18409ba68d80eefddd0a94c5c8f47f7e8061d921
4
- data.tar.gz: 7ab7791459924188b16c1551bf3682defd268937
3
+ metadata.gz: c4c35583425f2cec75988d311df46da4b1cea195
4
+ data.tar.gz: 3e2b125f355a1a5e89037ecf20e2c2d71e7674e6
5
5
  SHA512:
6
- metadata.gz: a586e1f036a81decca9bdda9d15735174e1676157af56c78cd1c8251b44046872811bfd2fcb4b017c7c973bd6e7daf8e608169c6958f33542a5b32cf16b29d3f
7
- data.tar.gz: fb8e623a8f354686a3c3a37ba7e3b9a16db3e17cbefe58b2f7fad198ce5c70b187e33b0d487fcb3f7f71860e8e9b76d2648f81728d6923fdd71bc8e4efee2b7e
6
+ metadata.gz: f9a78acc7da99ee83c64974b0b32703016acf296855558c09bf7e72b640cef692d9e366f019e687b8d7cf1f337b8085712efa8d2e8a31b7530d314d8a4f483b2
7
+ data.tar.gz: 876fd43670907912db636a647cdc858205b73733a4f06ee739bf4c592f70aceb1ed3e153b4a58437cbe63146f2af28a44d15e08924d6f1ab6f58f8b0cc325db8
data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,10 @@
1
+ # master
2
+
3
+ # 2.1.2
4
+
5
+ * Applies `Rails.application.config.filter_parameters` settings to reported transaction trace uris
6
+ * Fix incompatibility with ResqueWeb and middleware instrumentation
7
+
1
8
  # 2.1.1
2
9
 
3
10
  * Fix an issue with AR instrumentation and complex queries
@@ -112,7 +112,10 @@ module ScoutApm
112
112
  # It initializes the agent and starts the worker thread (if appropiate).
113
113
  def start(options = {})
114
114
  @options.merge!(options)
115
+
115
116
  @config = ScoutApm::Config.with_file(@config.value("config_file"))
117
+ layaway.config = config
118
+
116
119
  init_logger
117
120
  logger.info "Attempting to start Scout Agent [#{ScoutApm::VERSION}] on [#{environment.hostname}]"
118
121
 
@@ -41,8 +41,7 @@ module ScoutApm
41
41
  # Note that this middleware never even gets inserted unless Rails environment is development (See Railtie)
42
42
  class Middleware
43
43
  def initialize(app)
44
- ScoutApm::Agent.instance.logger.info("Activating Scout DevTrace because environment=development and dev_trace=true in scout_apm config")
45
- @app = app
44
+ @app = app
46
45
  end
47
46
 
48
47
  def call(env)
@@ -48,8 +48,7 @@ module ScoutApm
48
48
  # specific controller actions.
49
49
  def perform_action_with_scout_instruments(*args, &block)
50
50
  req = ScoutApm::RequestManager.lookup
51
- path = ScoutApm::Agent.instance.config.value("uri_reporting") == 'path' ? request.path : request.fullpath
52
- req.annotate_request(:uri => path)
51
+ req.annotate_request(:uri => request.path) # for security by-default, we don't use request.fullpath which could reveal filtered params.
53
52
  req.context.add_user(:ip => request.remote_ip)
54
53
  req.set_headers(request.headers)
55
54
  req.start_layer( ScoutApm::Layer.new("Controller", "#{controller_path}/#{action_name}") )
@@ -59,8 +59,7 @@ module ScoutApm
59
59
  module ActionControllerRails3Rails4Instruments
60
60
  def process_action(*args)
61
61
  req = ScoutApm::RequestManager.lookup
62
- path = ScoutApm::Agent.instance.config.value("uri_reporting") == 'path' ? request.path : request.fullpath
63
- req.annotate_request(:uri => path)
62
+ req.annotate_request(:uri => scout_transaction_uri(request))
64
63
 
65
64
  # IP Spoofing Protection can throw an exception, just move on w/o remote ip
66
65
  req.context.add_user(:ip => request.remote_ip) rescue nil
@@ -84,8 +83,19 @@ module ScoutApm
84
83
  ensure
85
84
  req.stop_layer
86
85
  end
86
+ end # process_action
87
+
88
+ # Given an +ActionDispatch::Request+, formats the uri based on config settings.
89
+ def scout_transaction_uri(request)
90
+ case ScoutApm::Agent.instance.config.value("uri_reporting")
91
+ when 'path'
92
+ request.path # strips off the query string for more security
93
+ else # default handles filtered params
94
+ request.filtered_path
95
+ end
87
96
  end
88
- end
97
+
98
+ end # ActionControllerRails3Rails4Instruments
89
99
  end
90
100
  end
91
101
 
@@ -23,7 +23,15 @@ module ScoutApm
23
23
  ActionDispatch::MiddlewareStack.class_eval do
24
24
  def build_with_scout_instruments(app = nil, &block)
25
25
  mw_stack = build_without_scout_instruments(app) { block.call if block }
26
- MiddlewareSummaryWrapper.new(mw_stack)
26
+ if app == mw_stack
27
+ # Return the raw middleware stack if it equaled app. No
28
+ # middlewares were created, so nothing to wrap & test.
29
+ #
30
+ # Avoids instrumentation of something that doesn't exist
31
+ mw_stack
32
+ else
33
+ MiddlewareSummaryWrapper.new(mw_stack)
34
+ end
27
35
  end
28
36
 
29
37
  alias_method :build_without_scout_instruments, :build
@@ -45,6 +53,36 @@ module ScoutApm
45
53
  ensure
46
54
  req.stop_layer
47
55
  end
56
+
57
+ # Some code (found in resque_web initially) attempts to call methods
58
+ # directly on `MyApplication.app`, which is the middleware stack.
59
+ # If it hits our middleware instead of the object at the root of the
60
+ # app that it expected, then a method it expects will not be there, and an
61
+ # error thrown.
62
+ #
63
+ # Specifically, resque_web assumes `ResqueWeb::Engine.app.url_helpers`
64
+ # is a method call on rails router for its own Engine, when in fact,
65
+ # we've added a middleware before it.
66
+ #
67
+ # So method_missing just proxies anything to the nested @app object
68
+ #
69
+ # While method_missing is not very performant, this is only here to
70
+ # handle edge-cases in other code, and should not be regularly called
71
+ def method_missing(sym, *arguments, &block)
72
+ if @app.respond_to?(sym)
73
+ @app.send(sym, *arguments, &block)
74
+ else
75
+ super
76
+ end
77
+ end
78
+
79
+ def respond_to?(sym, include_private = false)
80
+ if @app.respond_to?(sym, include_private)
81
+ true
82
+ else
83
+ super
84
+ end
85
+ end
48
86
  end
49
87
  end
50
88
  end
@@ -18,7 +18,7 @@ module ScoutApm
18
18
  # Must be sortable as an integer
19
19
  TIME_FORMAT = "%Y%m%d%H%M"
20
20
 
21
- attr_reader :config
21
+ attr_accessor :config
22
22
  attr_reader :environment
23
23
 
24
24
  def initialize(config, environment)
@@ -69,14 +69,19 @@ module ScoutApm
69
69
 
70
70
  @mutex.synchronize {
71
71
  reporting_periods.select { |time, rp| force || time.timestamp < current_timestamp.timestamp}.
72
- each { |time, rp|
73
- collect_samplers(rp)
74
- layaway.write_reporting_period(rp)
75
- reporting_periods.delete(time)
76
- }
72
+ each { |time, rp| write_reporting_period(layaway, time, rp) }
77
73
  }
78
74
  end
79
75
 
76
+ def write_reporting_period(layaway, time, rp)
77
+ collect_samplers(rp)
78
+ layaway.write_reporting_period(rp)
79
+ rescue => e
80
+ ScoutApm::Agent.instance.logger.warn("Failed writing data to layaway file: #{e.message} / #{e.backtrace}")
81
+ ensure
82
+ reporting_periods.delete(time)
83
+ end
84
+
80
85
  ######################################
81
86
  # Sampler support
82
87
  def add_sampler(sampler)
@@ -1,4 +1,4 @@
1
1
  module ScoutApm
2
- VERSION = "2.1.1"
2
+ VERSION = "2.1.2"
3
3
  end
4
4
 
data/lib/scout_apm.rb CHANGED
@@ -157,6 +157,8 @@ if defined?(Rails) && defined?(Rails::VERSION) && defined?(Rails::VERSION::MAJOR
157
157
  end
158
158
  class Railtie < Rails::Railtie
159
159
  initializer 'scout_apm.start' do |app|
160
+ # Install the middleware every time in development mode.
161
+ # The middleware is a noop if dev_trace is not enabled in config
160
162
  if Rails.env.development?
161
163
  app.middleware.use ScoutApm::Instant::Middleware
162
164
  end
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ require 'scout_apm/store'
4
+
5
+ class FakeFailingLayaway
6
+ def write_reporting_period(rp)
7
+ raise "Always fails. Sucks."
8
+ end
9
+ end
10
+
11
+ class StoreTest < Minitest::Test
12
+ # TODO: Introduce a clock object to avoid having to use 'force'
13
+ def test_writing_layaway_removes_timestamps
14
+ s = ScoutApm::Store.new
15
+ s.track_one!("Controller", "user/show", 10)
16
+
17
+ assert_equal(1, s.reporting_periods.size)
18
+
19
+ s.write_to_layaway(FakeFailingLayaway.new, true)
20
+
21
+ assert_equal({}, s.reporting_periods)
22
+ end
23
+ end
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: 2.1.1
4
+ version: 2.1.2
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-08-18 00:00:00.000000000 Z
12
+ date: 2016-08-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rusage
@@ -235,6 +235,7 @@ files:
235
235
  - test/unit/slow_job_policy_test.rb
236
236
  - test/unit/slow_request_policy_test.rb
237
237
  - test/unit/sql_sanitizer_test.rb
238
+ - test/unit/store_test.rb
238
239
  - test/unit/utils/active_record_metric_name_test.rb
239
240
  - test/unit/utils/backtrace_parser_test.rb
240
241
  homepage: https://github.com/scoutapp/scout_apm_ruby
@@ -278,6 +279,7 @@ test_files:
278
279
  - test/unit/slow_job_policy_test.rb
279
280
  - test/unit/slow_request_policy_test.rb
280
281
  - test/unit/sql_sanitizer_test.rb
282
+ - test/unit/store_test.rb
281
283
  - test/unit/utils/active_record_metric_name_test.rb
282
284
  - test/unit/utils/backtrace_parser_test.rb
283
285
  has_rdoc: