scout_apm 5.3.3 → 5.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +11 -9
- data/CHANGELOG.markdown +17 -0
- data/README.markdown +5 -1
- data/gems/instruments.gemfile +2 -0
- data/lib/scout_apm/app_server_load.rb +1 -1
- data/lib/scout_apm/auto_instrument/rails.rb +21 -0
- data/lib/scout_apm/instruments/action_view.rb +62 -3
- data/lib/scout_apm/instruments/active_record.rb +1 -1
- data/lib/scout_apm/instruments/net_http.rb +1 -1
- data/lib/scout_apm/layer_converters/external_service_converter.rb +1 -1
- data/lib/scout_apm/slow_request_policy.rb +1 -1
- data/lib/scout_apm/version.rb +1 -1
- data/scout_apm.gemspec +1 -1
- data/test/test_helper.rb +32 -0
- data/test/unit/auto_instrument/hash_shorthand_controller-instrumented.rb +41 -0
- data/test/unit/auto_instrument/hash_shorthand_controller.rb +41 -0
- data/test/unit/auto_instrument_test.rb +7 -1
- data/test/unit/environment_test.rb +0 -28
- data/test/unit/instruments/action_view_test.rb +102 -0
- data/test/unit/instruments/active_record_test.rb +30 -0
- data/test/unit/instruments/fixtures/test/_test_partial.html.erb +3 -0
- data/test/unit/instruments/fixtures/test/_test_partial_collection.html.erb +3 -0
- data/test/unit/instruments/fixtures/test_view.html.erb +10 -0
- metadata +83 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a0f837b1786c1e41925b01d4f2c03964c3541bf92666920f0bb8a0ba7cbdb89
|
4
|
+
data.tar.gz: 050c8858b43539abf92b893f8a1664e448d860fef2a3aa28f03af23e95941dd3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05cf25c9161a0d2e1a5b5a0f5bffd9dfb27d05d9adc17e39a860ff55653c307e7815315b978bc75aa8f7e77fee8ba7a4f57e9a67009472ea40a9f80d02857f47
|
7
|
+
data.tar.gz: 54198b64b284943f81384fc992f0446e871f8630f4693ecce8d774728cdc20e02d078dc77213496b7b581af73cd7566c224557f319b6134056c32b5975e78041
|
data/.github/workflows/test.yml
CHANGED
@@ -7,7 +7,7 @@ jobs:
|
|
7
7
|
runs-on: ubuntu-latest
|
8
8
|
|
9
9
|
steps:
|
10
|
-
- uses: actions/checkout@
|
10
|
+
- uses: actions/checkout@v3
|
11
11
|
- uses: ruby/setup-ruby@v1
|
12
12
|
with:
|
13
13
|
bundler-cache: true
|
@@ -37,29 +37,31 @@ jobs:
|
|
37
37
|
- ruby: 2.7
|
38
38
|
- ruby: 2.7
|
39
39
|
prepend: true
|
40
|
-
- ruby: 3.0
|
41
|
-
- ruby: 3.0
|
40
|
+
- ruby: "3.0"
|
41
|
+
- ruby: "3.0"
|
42
42
|
prepend: true
|
43
|
-
- ruby: 3.0
|
43
|
+
- ruby: "3.0"
|
44
44
|
gemfile: gems/instruments.gemfile
|
45
45
|
test_features: "instruments"
|
46
|
-
- ruby: 3.0
|
46
|
+
- ruby: "3.0"
|
47
47
|
gemfile: gems/instruments.gemfile
|
48
48
|
prepend: true
|
49
49
|
test_features: "instruments"
|
50
|
-
- ruby: 3.0
|
50
|
+
- ruby: "3.0"
|
51
51
|
gemfile: gems/sidekiq.gemfile
|
52
52
|
test_features: "sidekiq_install"
|
53
|
-
|
53
|
+
- ruby: 3.1
|
54
|
+
- ruby: 3.2
|
54
55
|
env:
|
55
56
|
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
56
57
|
SCOUT_TEST_FEATURES: ${{ matrix.test_features }}
|
57
58
|
SCOUT_USE_PREPEND: ${{ matrix.prepend }}
|
58
59
|
|
59
|
-
|
60
|
+
# https://github.com/ruby/setup-ruby/issues/496
|
61
|
+
runs-on: ${{ matrix.ruby == '2.2' && 'ubuntu-20.04' || 'ubuntu-latest' }}
|
60
62
|
|
61
63
|
steps:
|
62
|
-
- uses: actions/checkout@
|
64
|
+
- uses: actions/checkout@v3
|
63
65
|
- uses: ruby/setup-ruby@v1
|
64
66
|
with:
|
65
67
|
bundler-cache: true
|
data/CHANGELOG.markdown
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# Unreleased
|
2
2
|
|
3
|
+
# 5.3.7
|
4
|
+
* Fix parser dependency issue
|
5
|
+
|
6
|
+
# 5.3.6
|
7
|
+
* Fix AutoInstruments when instrumenting hash with shorthand (#486)
|
8
|
+
* Fix Connection Handling deprecation in ActiveRecord for Rails 7.1 (#483)
|
9
|
+
* Update ActionView partial instrumentation for Rails 7 (#487)
|
10
|
+
|
11
|
+
# 5.3.5
|
12
|
+
* Fix adding instrumentation of ActiveRecord after configuration has initialized for Rails versions greater than 3. (#465)
|
13
|
+
* Fix typo with double use of PercentilePolicy, instead of PercentPolicy, for scoring. (#468)
|
14
|
+
* Fix span annotations/desc for external service requests with the use of prepend. (#471)
|
15
|
+
* Fix ActiveSupport methods and replace them with non ActiveSupport methods. (#474)
|
16
|
+
|
17
|
+
# 5.3.4
|
18
|
+
Unused.
|
19
|
+
|
3
20
|
# 5.3.3
|
4
21
|
|
5
22
|
* Fix double firing of Puma `on_worker_boot` when preloading. (#463)
|
data/README.markdown
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# ScoutApm Ruby Agent
|
2
2
|
|
3
|
-
[![Build Status](https://
|
3
|
+
[![Build Status](https://github.com/scoutapp/scout_apm_ruby/actions/workflows/test.yml/badge.svg)](https://github.com/scoutapp/scout_apm_ruby/actions)
|
4
4
|
|
5
5
|
A Ruby gem for detailed Rails application performance monitoring 📈. Metrics and transaction traces are
|
6
6
|
reported to [Scout](https://scoutapp.com), a hosted application monitoring
|
@@ -21,6 +21,10 @@ Add the gem to your Gemfile
|
|
21
21
|
|
22
22
|
gem 'scout_apm'
|
23
23
|
|
24
|
+
Add [a version of the `parser` gem that supports your version of Ruby](https://github.com/whitequark/parser?tab=readme-ov-file#backwards-compatibility). For example, if you're on Ruby 3.3.0:
|
25
|
+
|
26
|
+
gem 'parser', '~> 3.3.0.0'
|
27
|
+
|
24
28
|
Update your Gemfile
|
25
29
|
|
26
30
|
bundle install
|
data/gems/instruments.gemfile
CHANGED
@@ -51,7 +51,7 @@ module ScoutApm
|
|
51
51
|
ensure
|
52
52
|
# Sometimes :database_engine and :database_adapter can cause a reference to an AR connection.
|
53
53
|
# Make sure we release all AR connections held by this thread.
|
54
|
-
ActiveRecord::Base.clear_active_connections! if Utils::KlassHelper.defined?("ActiveRecord::Base")
|
54
|
+
ActiveRecord::Base.connection_handler.clear_active_connections! if Utils::KlassHelper.defined?("ActiveRecord::Base")
|
55
55
|
end
|
56
56
|
|
57
57
|
# Calls `.to_s` on the object passed in.
|
@@ -135,6 +135,27 @@ module ScoutApm
|
|
135
135
|
wrap(node.location.expression, *instrument(node.location.expression.source, file_name, line))
|
136
136
|
end
|
137
137
|
|
138
|
+
def on_hash(node)
|
139
|
+
node.children.each do |pair|
|
140
|
+
# Skip `pair` if we're sure it's not using the hash shorthand syntax
|
141
|
+
next if pair.type != :pair
|
142
|
+
key_node, value_node = pair.children
|
143
|
+
next unless key_node.type == :sym && value_node.type == :send
|
144
|
+
key = key_node.children[0]
|
145
|
+
next unless value_node.children.size == 2 && value_node.children[0].nil? && key == value_node.children[1]
|
146
|
+
|
147
|
+
# Extract useful metadata for instrumentation:
|
148
|
+
line = pair.location.line || 'line?'
|
149
|
+
# column = pair.location.column || 'column?' # not used
|
150
|
+
# method_name = key || '*unknown*' # not used
|
151
|
+
file_name = @source_rewriter.source_buffer.name
|
152
|
+
|
153
|
+
instrument_before, instrument_after = instrument(pair.location.expression.source, file_name, line)
|
154
|
+
replace(pair.loc.expression, "#{key}: #{instrument_before}#{key}#{instrument_after}")
|
155
|
+
end
|
156
|
+
super
|
157
|
+
end
|
158
|
+
|
138
159
|
# def on_class(node)
|
139
160
|
# class_name = node.children[1]
|
140
161
|
#
|
@@ -72,9 +72,67 @@ module ScoutApm
|
|
72
72
|
|
73
73
|
logger.info "Instrumenting ActionView::TemplateRenderer"
|
74
74
|
::ActionView::TemplateRenderer.prepend(ActionViewTemplateRendererInstruments)
|
75
|
+
|
76
|
+
if defined?(::ActionView::CollectionRenderer)
|
77
|
+
logger.info "Instrumenting ActionView::CollectionRenderer"
|
78
|
+
::ActionView::CollectionRenderer.prepend(ActionViewCollectionRendererInstruments)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# In Rails 6.1 collection was moved to CollectionRenderer.
|
83
|
+
module ActionViewCollectionRendererInstruments
|
84
|
+
def render_collection(*args, **kwargs)
|
85
|
+
req = ScoutApm::RequestManager.lookup
|
86
|
+
|
87
|
+
maybe_template = args[3]
|
88
|
+
|
89
|
+
template_name ||= maybe_template.virtual_path rescue nil
|
90
|
+
template_name ||= "Unknown Collection"
|
91
|
+
layer_name = template_name + "/Rendering"
|
92
|
+
|
93
|
+
layer = ScoutApm::Layer.new("View", layer_name)
|
94
|
+
layer.subscopable!
|
95
|
+
|
96
|
+
begin
|
97
|
+
req.start_layer(layer)
|
98
|
+
if ScoutApm::Agent.instance.context.environment.supports_kwarg_delegation?
|
99
|
+
super(*args, **kwargs)
|
100
|
+
else
|
101
|
+
super(*args)
|
102
|
+
end
|
103
|
+
ensure
|
104
|
+
req.stop_layer
|
105
|
+
end
|
106
|
+
end
|
75
107
|
end
|
76
108
|
|
77
109
|
module ActionViewPartialRendererInstruments
|
110
|
+
# In Rails 6.1, render_partial was renamed to render_partial_template
|
111
|
+
def render_partial_template(*args, **kwargs)
|
112
|
+
req = ScoutApm::RequestManager.lookup
|
113
|
+
|
114
|
+
# Template was moved to the third argument in Rails 6.1.
|
115
|
+
maybe_template = args[2]
|
116
|
+
|
117
|
+
template_name ||= maybe_template.virtual_path rescue nil
|
118
|
+
template_name ||= "Unknown Partial"
|
119
|
+
|
120
|
+
layer_name = template_name + "/Rendering"
|
121
|
+
layer = ScoutApm::Layer.new("View", layer_name)
|
122
|
+
layer.subscopable!
|
123
|
+
|
124
|
+
begin
|
125
|
+
req.start_layer(layer)
|
126
|
+
if ScoutApm::Agent.instance.context.environment.supports_kwarg_delegation?
|
127
|
+
super(*args, **kwargs)
|
128
|
+
else
|
129
|
+
super(*args)
|
130
|
+
end
|
131
|
+
ensure
|
132
|
+
req.stop_layer
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
78
136
|
# In Rails 6, the signature changed to pass the view & template args directly, as opposed to through the instance var
|
79
137
|
# New signature is: def render_partial(view, template)
|
80
138
|
def render_partial(*args, **kwargs)
|
@@ -83,7 +141,7 @@ module ScoutApm
|
|
83
141
|
maybe_template = args[1]
|
84
142
|
|
85
143
|
template_name = @template.virtual_path rescue nil # Works on Rails 3.2 -> end of Rails 5 series
|
86
|
-
template_name ||= maybe_template.virtual_path rescue nil # Works on Rails 6 -> 6.0.
|
144
|
+
template_name ||= maybe_template.virtual_path rescue nil # Works on Rails 6 -> 6.0.6
|
87
145
|
template_name ||= "Unknown Partial"
|
88
146
|
|
89
147
|
layer_name = template_name + "/Rendering"
|
@@ -102,13 +160,14 @@ module ScoutApm
|
|
102
160
|
end
|
103
161
|
end
|
104
162
|
|
163
|
+
# This method was moved in Rails 6.1 to CollectionRender.
|
105
164
|
def collection_with_template(*args, **kwargs)
|
106
165
|
req = ScoutApm::RequestManager.lookup
|
107
166
|
|
108
167
|
maybe_template = args[1]
|
109
168
|
|
110
169
|
template_name = @template.virtual_path rescue nil # Works on Rails 3.2 -> end of Rails 5 series
|
111
|
-
template_name ||= maybe_template.virtual_path rescue nil # Works on Rails 6 -> 6.0.
|
170
|
+
template_name ||= maybe_template.virtual_path rescue nil # Works on Rails 6 -> 6.0.6
|
112
171
|
template_name ||= "Unknown Collection"
|
113
172
|
layer_name = template_name + "/Rendering"
|
114
173
|
|
@@ -137,7 +196,7 @@ module ScoutApm
|
|
137
196
|
maybe_template = args[1]
|
138
197
|
|
139
198
|
template_name = args[0].virtual_path rescue nil # Works on Rails 3.2 -> end of Rails 5 series
|
140
|
-
template_name ||= maybe_template.virtual_path rescue nil # Works on Rails 6 ->
|
199
|
+
template_name ||= maybe_template.virtual_path rescue nil # Works on Rails 6 -> 7.1.3
|
141
200
|
template_name ||= "Unknown"
|
142
201
|
layer_name = template_name + "/Rendering"
|
143
202
|
|
@@ -60,7 +60,7 @@ module ScoutApm
|
|
60
60
|
|
61
61
|
module NetHttpInstrumentationPrepend
|
62
62
|
def request(request, *args, &block)
|
63
|
-
self.class.instrument("HTTP", "request", :ignore_children => true, :desc => request_scout_description(
|
63
|
+
self.class.instrument("HTTP", "request", :ignore_children => true, :desc => request_scout_description(request)) do
|
64
64
|
super(request, *args, &block)
|
65
65
|
end
|
66
66
|
end
|
@@ -14,7 +14,7 @@ module ScoutApm
|
|
14
14
|
|
15
15
|
def add_default_policies
|
16
16
|
add(SlowPolicy::SpeedPolicy.new(context))
|
17
|
-
add(SlowPolicy::
|
17
|
+
add(SlowPolicy::PercentPolicy.new(context))
|
18
18
|
add(SlowPolicy::AgePolicy.new(context))
|
19
19
|
add(SlowPolicy::PercentilePolicy.new(context))
|
20
20
|
end
|
data/lib/scout_apm/version.rb
CHANGED
data/scout_apm.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.add_runtime_dependency "parser"
|
32
32
|
|
33
33
|
# These are general development dependencies which are used in instrumentation
|
34
|
-
# tests. Specific versions are pulled in using specific gemfiles, e.g.
|
34
|
+
# tests. Specific versions are pulled in using specific gemfiles, e.g.
|
35
35
|
# `gems/rails3.gemfile`.
|
36
36
|
s.add_development_dependency "activerecord"
|
37
37
|
s.add_development_dependency "sqlite3"
|
data/test/test_helper.rb
CHANGED
@@ -65,6 +65,38 @@ class FakeEnvironment
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
def remove_rails_namespace
|
69
|
+
Object.send(:remove_const, "Rails") if defined?(Rails)
|
70
|
+
end
|
71
|
+
|
72
|
+
def fake_rails(version)
|
73
|
+
remove_rails_namespace if (ENV["SCOUT_TEST_FEATURES"] || "").include?("instruments")
|
74
|
+
|
75
|
+
Kernel.const_set("Rails", Module.new)
|
76
|
+
Kernel.const_set("ActionController", Module.new)
|
77
|
+
r = Kernel.const_get("Rails")
|
78
|
+
r.const_set("VERSION", Module.new)
|
79
|
+
v = r.const_get("VERSION")
|
80
|
+
v.const_set("MAJOR", version)
|
81
|
+
|
82
|
+
assert_equal version, Rails::VERSION::MAJOR
|
83
|
+
end
|
84
|
+
|
85
|
+
def clean_fake_rails
|
86
|
+
Kernel.send(:remove_const, "Rails") if defined?(Kernel::Rails)
|
87
|
+
Kernel.send(:remove_const, "ActionController") if defined?(Kernel::ActionController)
|
88
|
+
end
|
89
|
+
|
90
|
+
def fake_sinatra
|
91
|
+
Kernel.const_set("Sinatra", Module.new)
|
92
|
+
s = Kernel.const_get("Sinatra")
|
93
|
+
s.const_set("Base", Module.new)
|
94
|
+
end
|
95
|
+
|
96
|
+
def clean_fake_sinatra
|
97
|
+
Kernel.const_unset("Sinatra") if defined?(Kernel::Sinatra)
|
98
|
+
end
|
99
|
+
|
68
100
|
# Helpers available to all tests
|
69
101
|
class Minitest::Test
|
70
102
|
def setup
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
class HashShorthandController < ApplicationController
|
3
|
+
def hash
|
4
|
+
json = {
|
5
|
+
static: "static",
|
6
|
+
shorthand: ::ScoutApm::AutoInstrument("shorthand:",["ROOT/test/unit/auto_instrument/hash_shorthand_controller.rb:6:in `hash'"]){shorthand},
|
7
|
+
longhand: ::ScoutApm::AutoInstrument("longhand: longhand",["ROOT/test/unit/auto_instrument/hash_shorthand_controller.rb:7:in `hash'"]){longhand},
|
8
|
+
longhand_different_key: ::ScoutApm::AutoInstrument("longhand",["ROOT/test/unit/auto_instrument/hash_shorthand_controller.rb:8:in `hash'"]){longhand},
|
9
|
+
hash_rocket: ::ScoutApm::AutoInstrument(":hash_rocket => hash_rocket",["ROOT/test/unit/auto_instrument/hash_shorthand_controller.rb:9:in `hash'"]){hash_rocket},
|
10
|
+
:hash_rocket_different_key => ::ScoutApm::AutoInstrument("hash_rocket",["ROOT/test/unit/auto_instrument/hash_shorthand_controller.rb:10:in `hash'"]){hash_rocket},
|
11
|
+
non_nil_receiver: ::ScoutApm::AutoInstrument("non_nil_receiver.value",["ROOT/test/unit/auto_instrument/hash_shorthand_controller.rb:11:in `hash'"]){non_nil_receiver.value},
|
12
|
+
nested: {
|
13
|
+
shorthand: ::ScoutApm::AutoInstrument("shorthand:",["ROOT/test/unit/auto_instrument/hash_shorthand_controller.rb:13:in `hash'"]){shorthand},
|
14
|
+
},
|
15
|
+
nested_call: ::ScoutApm::AutoInstrument("nested_call(params[\"timestamp\"])",["ROOT/test/unit/auto_instrument/hash_shorthand_controller.rb:15:in `hash'"]){nested_call(params["timestamp"])}
|
16
|
+
}
|
17
|
+
::ScoutApm::AutoInstrument("render json:",["ROOT/test/unit/auto_instrument/hash_shorthand_controller.rb:17:in `hash'"]){render json:}
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def nested_call(noop)
|
23
|
+
noop
|
24
|
+
end
|
25
|
+
|
26
|
+
def shorthand
|
27
|
+
"shorthand"
|
28
|
+
end
|
29
|
+
|
30
|
+
def longhand
|
31
|
+
"longhand"
|
32
|
+
end
|
33
|
+
|
34
|
+
def hash_rocket
|
35
|
+
"hash_rocket"
|
36
|
+
end
|
37
|
+
|
38
|
+
def non_nil_receiver
|
39
|
+
::ScoutApm::AutoInstrument("OpenStruct.new(value: \"value\")",["ROOT/test/unit/auto_instrument/hash_shorthand_controller.rb:39:in `non_nil_receiver'"]){OpenStruct.new(value: "value")}
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
class HashShorthandController < ApplicationController
|
3
|
+
def hash
|
4
|
+
json = {
|
5
|
+
static: "static",
|
6
|
+
shorthand:,
|
7
|
+
longhand: longhand,
|
8
|
+
longhand_different_key: longhand,
|
9
|
+
:hash_rocket => hash_rocket,
|
10
|
+
:hash_rocket_different_key => hash_rocket,
|
11
|
+
non_nil_receiver: non_nil_receiver.value,
|
12
|
+
nested: {
|
13
|
+
shorthand:,
|
14
|
+
},
|
15
|
+
nested_call: nested_call(params["timestamp"])
|
16
|
+
}
|
17
|
+
render json:
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def nested_call(noop)
|
23
|
+
noop
|
24
|
+
end
|
25
|
+
|
26
|
+
def shorthand
|
27
|
+
"shorthand"
|
28
|
+
end
|
29
|
+
|
30
|
+
def longhand
|
31
|
+
"longhand"
|
32
|
+
end
|
33
|
+
|
34
|
+
def hash_rocket
|
35
|
+
"hash_rocket"
|
36
|
+
end
|
37
|
+
|
38
|
+
def non_nil_receiver
|
39
|
+
OpenStruct.new(value: "value")
|
40
|
+
end
|
41
|
+
end
|
@@ -4,7 +4,7 @@ require 'scout_apm/auto_instrument'
|
|
4
4
|
|
5
5
|
class AutoInstrumentTest < Minitest::Test
|
6
6
|
ROOT = File.expand_path("../../", __dir__)
|
7
|
-
|
7
|
+
|
8
8
|
def source_path(name)
|
9
9
|
File.expand_path("auto_instrument/#{name}.rb", __dir__)
|
10
10
|
end
|
@@ -38,6 +38,12 @@ class AutoInstrumentTest < Minitest::Test
|
|
38
38
|
normalize_backtrace(::ScoutApm::AutoInstrument::Rails.rewrite(source_path("controller")))
|
39
39
|
end
|
40
40
|
|
41
|
+
def test_controller_rewrite_hash_shorthand
|
42
|
+
skip if RUBY_VERSION < "3.1"
|
43
|
+
assert_equal instrumented_source("hash_shorthand_controller"),
|
44
|
+
normalize_backtrace(::ScoutApm::AutoInstrument::Rails.rewrite(source_path("hash_shorthand_controller")))
|
45
|
+
end
|
46
|
+
|
41
47
|
def test_rescue_from_rewrite
|
42
48
|
# update_instrumented_source("rescue_from")
|
43
49
|
|
@@ -29,32 +29,4 @@ class EnvironmentTest < Minitest::Test
|
|
29
29
|
def test_framework_ruby
|
30
30
|
assert_equal :ruby, ScoutApm::Environment.send(:new).framework
|
31
31
|
end
|
32
|
-
|
33
|
-
############################################################
|
34
|
-
|
35
|
-
def fake_rails(version)
|
36
|
-
Kernel.const_set("Rails", Module.new)
|
37
|
-
Kernel.const_set("ActionController", Module.new)
|
38
|
-
r = Kernel.const_get("Rails")
|
39
|
-
r.const_set("VERSION", Module.new)
|
40
|
-
v = r.const_get("VERSION")
|
41
|
-
v.const_set("MAJOR", version)
|
42
|
-
|
43
|
-
assert_equal version, Rails::VERSION::MAJOR
|
44
|
-
end
|
45
|
-
|
46
|
-
def clean_fake_rails
|
47
|
-
Kernel.send(:remove_const, "Rails") if defined?(Kernel::Rails)
|
48
|
-
Kernel.send(:remove_const, "ActionController") if defined?(Kernel::ActionController)
|
49
|
-
end
|
50
|
-
|
51
|
-
def fake_sinatra
|
52
|
-
Kernel.const_set("Sinatra", Module.new)
|
53
|
-
s = Kernel.const_get("Sinatra")
|
54
|
-
s.const_set("Base", Module.new)
|
55
|
-
end
|
56
|
-
|
57
|
-
def clean_fake_sinatra
|
58
|
-
Kernel.const_unset("Sinatra") if defined?(Kernel::Sinatra)
|
59
|
-
end
|
60
32
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# Most of this was taken from Rails:
|
2
|
+
# https://github.com/rails/rails/blob/v7.1.3/actionview/test/actionpack/controller/render_test.rb
|
3
|
+
# https://github.com/rails/rails/blob/v7.1.3/actionview/test/abstract_unit.rb
|
4
|
+
|
5
|
+
if (ENV["SCOUT_TEST_FEATURES"] || "").include?("instruments")
|
6
|
+
require 'test_helper'
|
7
|
+
require 'action_view'
|
8
|
+
require 'action_pack'
|
9
|
+
require 'action_controller'
|
10
|
+
|
11
|
+
FIXTURE_LOAD_PATH = File.expand_path("fixtures", __dir__)
|
12
|
+
|
13
|
+
include ActionView::Context
|
14
|
+
include ActionView::Helpers::TagHelper
|
15
|
+
include ActionView::Helpers::TextHelper
|
16
|
+
|
17
|
+
module ActionController
|
18
|
+
|
19
|
+
class Base
|
20
|
+
self.view_paths = FIXTURE_LOAD_PATH
|
21
|
+
|
22
|
+
def self.test_routes(&block)
|
23
|
+
routes = ActionDispatch::Routing::RouteSet.new
|
24
|
+
routes.draw(&block)
|
25
|
+
include routes.url_helpers
|
26
|
+
routes
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class TestCase
|
31
|
+
include ActionDispatch::TestProcess
|
32
|
+
|
33
|
+
def self.with_routes(&block)
|
34
|
+
routes = ActionDispatch::Routing::RouteSet.new
|
35
|
+
routes.draw(&block)
|
36
|
+
include Module.new {
|
37
|
+
define_method(:setup) do
|
38
|
+
super()
|
39
|
+
@routes = routes
|
40
|
+
@controller.singleton_class.include @routes.url_helpers if @controller
|
41
|
+
end
|
42
|
+
}
|
43
|
+
routes
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class TestController < ActionController::Base
|
49
|
+
|
50
|
+
def render_test_view
|
51
|
+
render template: "test_view"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class RenderTest < ActionController::TestCase
|
56
|
+
|
57
|
+
tests TestController
|
58
|
+
|
59
|
+
with_routes do
|
60
|
+
get :render_test_view, to: "test#render_test_view"
|
61
|
+
end
|
62
|
+
|
63
|
+
def setup
|
64
|
+
super
|
65
|
+
@controller.logger = ActiveSupport::Logger.new(nil)
|
66
|
+
ActionView::Base.logger = ActiveSupport::Logger.new(nil)
|
67
|
+
|
68
|
+
@request.host = "www.scoutapm.com"
|
69
|
+
|
70
|
+
@old_view_paths = ActionController::Base.view_paths
|
71
|
+
ActionController::Base.view_paths = FIXTURE_LOAD_PATH
|
72
|
+
end
|
73
|
+
|
74
|
+
def teardown
|
75
|
+
ActionView::Base.logger = nil
|
76
|
+
|
77
|
+
ActionController::Base.view_paths = @old_view_paths
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_partial_instrumentation
|
81
|
+
recorder = FakeRecorder.new
|
82
|
+
agent_context.recorder = recorder
|
83
|
+
|
84
|
+
instrument = ScoutApm::Instruments::ActionView.new(agent_context)
|
85
|
+
instrument.install(prepend: true)
|
86
|
+
|
87
|
+
get :render_test_view
|
88
|
+
assert_response :success
|
89
|
+
|
90
|
+
root_layer = recorder.requests.first.root_layer
|
91
|
+
children = root_layer.children.to_a
|
92
|
+
assert_equal 2, children.size
|
93
|
+
|
94
|
+
partial_layer = children[0]
|
95
|
+
collection_layer = children[1]
|
96
|
+
|
97
|
+
assert_equal "test_view/Rendering", root_layer.name
|
98
|
+
assert_equal "test/_test_partial/Rendering", partial_layer.name
|
99
|
+
assert_equal "test/_test_partial_collection/Rendering", collection_layer.name
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -24,6 +24,36 @@ class ActiveRecordTest < Minitest::Test
|
|
24
24
|
class User < ActiveRecord::Base
|
25
25
|
end
|
26
26
|
|
27
|
+
class DumbRailsConfig
|
28
|
+
def self.after_initialize; end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_old_rails_initialization
|
32
|
+
recorder = FakeRecorder.new
|
33
|
+
agent_context.recorder = recorder
|
34
|
+
old_rails_version = (1..2).to_a.sample
|
35
|
+
fake_rails(old_rails_version)
|
36
|
+
|
37
|
+
::Rails.expects(:configuration).never
|
38
|
+
|
39
|
+
instrument = ScoutApm::Instruments::ActiveRecord.new(agent_context)
|
40
|
+
instrument.install(prepend: false)
|
41
|
+
clean_fake_rails
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_modern_rails_initialization
|
45
|
+
recorder = FakeRecorder.new
|
46
|
+
agent_context.recorder = recorder
|
47
|
+
modern_rails_version = (3..7).to_a.sample
|
48
|
+
fake_rails(modern_rails_version)
|
49
|
+
|
50
|
+
::Rails.expects(:configuration).returns(DumbRailsConfig).once
|
51
|
+
|
52
|
+
instrument = ScoutApm::Instruments::ActiveRecord.new(agent_context)
|
53
|
+
instrument.install(prepend: false)
|
54
|
+
clean_fake_rails
|
55
|
+
end
|
56
|
+
|
27
57
|
def test_instrumentation
|
28
58
|
recorder = FakeRecorder.new
|
29
59
|
agent_context.recorder = recorder
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scout_apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.3.
|
4
|
+
version: 5.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derek Haynes
|
8
8
|
- Andre Lewis
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-02-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -423,6 +423,8 @@ files:
|
|
423
423
|
- test/unit/auto_instrument/controller-instrumented.rb
|
424
424
|
- test/unit/auto_instrument/controller.rb
|
425
425
|
- test/unit/auto_instrument/hanging_method.rb
|
426
|
+
- test/unit/auto_instrument/hash_shorthand_controller-instrumented.rb
|
427
|
+
- test/unit/auto_instrument/hash_shorthand_controller.rb
|
426
428
|
- test/unit/auto_instrument/rescue_from-instrumented.rb
|
427
429
|
- test/unit/auto_instrument/rescue_from.rb
|
428
430
|
- test/unit/auto_instrument_test.rb
|
@@ -442,7 +444,11 @@ files:
|
|
442
444
|
- test/unit/git_revision_test.rb
|
443
445
|
- test/unit/histogram_test.rb
|
444
446
|
- test/unit/ignored_uris_test.rb
|
447
|
+
- test/unit/instruments/action_view_test.rb
|
445
448
|
- test/unit/instruments/active_record_test.rb
|
449
|
+
- test/unit/instruments/fixtures/test/_test_partial.html.erb
|
450
|
+
- test/unit/instruments/fixtures/test/_test_partial_collection.html.erb
|
451
|
+
- test/unit/instruments/fixtures/test_view.html.erb
|
446
452
|
- test/unit/instruments/http_client_test.rb
|
447
453
|
- test/unit/instruments/http_test.rb
|
448
454
|
- test/unit/instruments/moped_test.rb
|
@@ -479,7 +485,7 @@ homepage: https://github.com/scoutapp/scout_apm_ruby
|
|
479
485
|
licenses:
|
480
486
|
- MIT
|
481
487
|
metadata: {}
|
482
|
-
post_install_message:
|
488
|
+
post_install_message:
|
483
489
|
rdoc_options: []
|
484
490
|
require_paths:
|
485
491
|
- lib
|
@@ -495,8 +501,78 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
495
501
|
- !ruby/object:Gem::Version
|
496
502
|
version: '0'
|
497
503
|
requirements: []
|
498
|
-
rubygems_version: 3.0.
|
499
|
-
signing_key:
|
504
|
+
rubygems_version: 3.0.8
|
505
|
+
signing_key:
|
500
506
|
specification_version: 4
|
501
507
|
summary: Ruby application performance monitoring
|
502
|
-
test_files:
|
508
|
+
test_files:
|
509
|
+
- test/data/config_test_1.yml
|
510
|
+
- test/test_helper.rb
|
511
|
+
- test/tmp/README.md
|
512
|
+
- test/unit/agent_context_test.rb
|
513
|
+
- test/unit/agent_test.rb
|
514
|
+
- test/unit/auto_instrument/anonymous_block_value.rb
|
515
|
+
- test/unit/auto_instrument/assignments-instrumented.rb
|
516
|
+
- test/unit/auto_instrument/assignments.rb
|
517
|
+
- test/unit/auto_instrument/controller-ast.txt
|
518
|
+
- test/unit/auto_instrument/controller-instrumented.rb
|
519
|
+
- test/unit/auto_instrument/controller.rb
|
520
|
+
- test/unit/auto_instrument/hanging_method.rb
|
521
|
+
- test/unit/auto_instrument/hash_shorthand_controller-instrumented.rb
|
522
|
+
- test/unit/auto_instrument/hash_shorthand_controller.rb
|
523
|
+
- test/unit/auto_instrument/rescue_from-instrumented.rb
|
524
|
+
- test/unit/auto_instrument/rescue_from.rb
|
525
|
+
- test/unit/auto_instrument_test.rb
|
526
|
+
- test/unit/background_job_integrations/sidekiq_test.rb
|
527
|
+
- test/unit/config_test.rb
|
528
|
+
- test/unit/context_test.rb
|
529
|
+
- test/unit/db_query_metric_set_test.rb
|
530
|
+
- test/unit/db_query_metric_stats_test.rb
|
531
|
+
- test/unit/environment_test.rb
|
532
|
+
- test/unit/error_service/error_buffer_test.rb
|
533
|
+
- test/unit/error_service/ignored_exceptions_test.rb
|
534
|
+
- test/unit/extensions/periodic_callbacks_test.rb
|
535
|
+
- test/unit/extensions/transaction_callbacks_test.rb
|
536
|
+
- test/unit/external_service_metric_set_test.rb
|
537
|
+
- test/unit/external_service_metric_stats_test.rb
|
538
|
+
- test/unit/fake_store_test.rb
|
539
|
+
- test/unit/git_revision_test.rb
|
540
|
+
- test/unit/histogram_test.rb
|
541
|
+
- test/unit/ignored_uris_test.rb
|
542
|
+
- test/unit/instruments/action_view_test.rb
|
543
|
+
- test/unit/instruments/active_record_test.rb
|
544
|
+
- test/unit/instruments/fixtures/test/_test_partial.html.erb
|
545
|
+
- test/unit/instruments/fixtures/test/_test_partial_collection.html.erb
|
546
|
+
- test/unit/instruments/fixtures/test_view.html.erb
|
547
|
+
- test/unit/instruments/http_client_test.rb
|
548
|
+
- test/unit/instruments/http_test.rb
|
549
|
+
- test/unit/instruments/moped_test.rb
|
550
|
+
- test/unit/instruments/net_http_test.rb
|
551
|
+
- test/unit/instruments/percentile_sampler_test.rb
|
552
|
+
- test/unit/instruments/redis_test.rb
|
553
|
+
- test/unit/instruments/typhoeus_test.rb
|
554
|
+
- test/unit/layaway_test.rb
|
555
|
+
- test/unit/layer_children_set_test.rb
|
556
|
+
- test/unit/layer_converters/depth_first_walker_test.rb
|
557
|
+
- test/unit/layer_converters/metric_converter_test.rb
|
558
|
+
- test/unit/layer_converters/stubs.rb
|
559
|
+
- test/unit/limited_layer_test.rb
|
560
|
+
- test/unit/logger_test.rb
|
561
|
+
- test/unit/metric_set_test.rb
|
562
|
+
- test/unit/remote/message_test.rb
|
563
|
+
- test/unit/remote/route_test.rb
|
564
|
+
- test/unit/remote/server_test.rb
|
565
|
+
- test/unit/request_histograms_test.rb
|
566
|
+
- test/unit/scored_item_set_test.rb
|
567
|
+
- test/unit/serializers/payload_serializer_test.rb
|
568
|
+
- test/unit/slow_request_policy_test.rb
|
569
|
+
- test/unit/sql_sanitizer_test.rb
|
570
|
+
- test/unit/store_test.rb
|
571
|
+
- test/unit/tracer_test.rb
|
572
|
+
- test/unit/tracked_request_test.rb
|
573
|
+
- test/unit/transaction_test.rb
|
574
|
+
- test/unit/transaction_time_consumed_test.rb
|
575
|
+
- test/unit/utils/active_record_metric_name_test.rb
|
576
|
+
- test/unit/utils/backtrace_parser_test.rb
|
577
|
+
- test/unit/utils/numbers_test.rb
|
578
|
+
- test/unit/utils/scm.rb
|