appsignal 3.9.2-java → 3.10.0-java
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +3138 -0
- data/.rubocop.yml +28 -20
- data/.rubocop_todo.yml +7 -33
- data/CHANGELOG.md +130 -0
- data/README.md +0 -1
- data/Rakefile +80 -65
- data/appsignal.gemspec +1 -1
- data/build_matrix.yml +112 -184
- data/ext/base.rb +1 -1
- data/gemfiles/hanami-2.1.gemfile +7 -0
- data/gemfiles/webmachine1.gemfile +5 -4
- data/lib/appsignal/cli/diagnose.rb +1 -1
- data/lib/appsignal/config.rb +5 -1
- data/lib/appsignal/demo.rb +0 -1
- data/lib/appsignal/environment.rb +11 -2
- data/lib/appsignal/extension/jruby.rb +1 -1
- data/lib/appsignal/helpers/instrumentation.rb +164 -2
- data/lib/appsignal/hooks/active_job.rb +1 -6
- data/lib/appsignal/integrations/grape.rb +19 -47
- data/lib/appsignal/integrations/hanami.rb +8 -7
- data/lib/appsignal/integrations/padrino.rb +51 -52
- data/lib/appsignal/integrations/railtie.rb +0 -3
- data/lib/appsignal/integrations/rake.rb +46 -12
- data/lib/appsignal/integrations/sidekiq.rb +1 -11
- data/lib/appsignal/integrations/sinatra.rb +0 -1
- data/lib/appsignal/integrations/webmachine.rb +15 -9
- data/lib/appsignal/probes/gvl.rb +24 -2
- data/lib/appsignal/probes/sidekiq.rb +1 -1
- data/lib/appsignal/probes.rb +1 -1
- data/lib/appsignal/rack/abstract_middleware.rb +104 -33
- data/lib/appsignal/rack/body_wrapper.rb +143 -0
- data/lib/appsignal/rack/event_handler.rb +12 -3
- data/lib/appsignal/rack/generic_instrumentation.rb +5 -4
- data/lib/appsignal/rack/grape_middleware.rb +40 -0
- data/lib/appsignal/rack/hanami_middleware.rb +2 -12
- data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +14 -57
- data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
- data/lib/appsignal/rack/streaming_listener.rb +13 -59
- data/lib/appsignal/rack.rb +31 -0
- data/lib/appsignal/transaction.rb +50 -8
- data/lib/appsignal/utils/integration_memory_logger.rb +78 -0
- data/lib/appsignal/utils.rb +1 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +36 -33
- data/spec/.rubocop.yml +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -1
- data/spec/lib/appsignal/cli/install_spec.rb +3 -3
- data/spec/lib/appsignal/config_spec.rb +8 -5
- data/spec/lib/appsignal/demo_spec.rb +38 -41
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +86 -167
- data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +8 -20
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +38 -84
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +16 -37
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +4 -4
- data/spec/lib/appsignal/hooks/activejob_spec.rb +111 -200
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +54 -91
- data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +14 -32
- data/spec/lib/appsignal/hooks/excon_spec.rb +8 -12
- data/spec/lib/appsignal/hooks/net_http_spec.rb +7 -42
- data/spec/lib/appsignal/hooks/rake_spec.rb +107 -34
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +18 -30
- data/spec/lib/appsignal/hooks/redis_spec.rb +10 -16
- data/spec/lib/appsignal/hooks/resque_spec.rb +42 -62
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +33 -74
- data/spec/lib/appsignal/integrations/hanami_spec.rb +79 -21
- data/spec/lib/appsignal/integrations/http_spec.rb +12 -20
- data/spec/lib/appsignal/integrations/net_http_spec.rb +33 -0
- data/spec/lib/appsignal/integrations/object_spec.rb +29 -36
- data/spec/lib/appsignal/integrations/padrino_spec.rb +190 -163
- data/spec/lib/appsignal/integrations/que_spec.rb +43 -70
- data/spec/lib/appsignal/integrations/railtie_spec.rb +26 -67
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +86 -160
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -3
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +77 -40
- data/spec/lib/appsignal/probes/gvl_spec.rb +80 -3
- data/spec/lib/appsignal/probes_spec.rb +7 -4
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +302 -105
- data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
- data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -78
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -27
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +234 -0
- data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +2 -16
- data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +67 -131
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +36 -44
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +44 -139
- data/spec/lib/appsignal/transaction_spec.rb +239 -94
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
- data/spec/lib/appsignal_spec.rb +556 -344
- data/spec/support/helpers/dependency_helper.rb +6 -1
- data/spec/support/helpers/std_streams_helper.rb +1 -1
- data/spec/support/helpers/transaction_helpers.rb +8 -0
- data/spec/support/matchers/transaction.rb +185 -0
- data/spec/support/mocks/dummy_app.rb +20 -0
- data/spec/support/shared_examples/instrument.rb +17 -12
- data/spec/support/testing.rb +18 -9
- metadata +20 -11
- data/.semaphore/semaphore.yml +0 -2347
- data/script/lint_git +0 -22
- data/spec/lib/appsignal/integrations/grape_spec.rb +0 -239
- data/spec/support/matchers/be_completed.rb +0 -5
- data/support/check_versions +0 -22
- /data/gemfiles/{hanami.gemfile → hanami-2.0.gemfile} +0 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
if DependencyHelper.grape_present?
|
|
2
|
+
require "appsignal/integrations/grape"
|
|
3
|
+
|
|
4
|
+
context "Appsignal::Grape::Middleware constant" do
|
|
5
|
+
let(:err_stream) { std_stream }
|
|
6
|
+
let(:stderr) { err_stream.read }
|
|
7
|
+
|
|
8
|
+
it "returns the Rack::GrapeMiddleware constant calling the Grape::Middleware constant" do
|
|
9
|
+
silence { expect(Appsignal::Grape::Middleware).to be(Appsignal::Rack::GrapeMiddleware) }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "prints a deprecation warning to STDERR" do
|
|
13
|
+
capture_std_streams(std_stream, err_stream) do
|
|
14
|
+
expect(Appsignal::Grape::Middleware).to be(Appsignal::Rack::GrapeMiddleware)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
expect(stderr).to include(
|
|
18
|
+
"appsignal WARNING: The constant Appsignal::Grape::Middleware has been deprecated."
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "logs a warning" do
|
|
23
|
+
logs =
|
|
24
|
+
capture_logs do
|
|
25
|
+
silence do
|
|
26
|
+
expect(Appsignal::Grape::Middleware).to be(Appsignal::Rack::GrapeMiddleware)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
expect(logs).to contains_log(
|
|
31
|
+
:warn,
|
|
32
|
+
"The constant Appsignal::Grape::Middleware has been deprecated."
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe Appsignal::Rack::GrapeMiddleware do
|
|
38
|
+
let(:app) do
|
|
39
|
+
Class.new(::Grape::API) do
|
|
40
|
+
format :json
|
|
41
|
+
post :ping do
|
|
42
|
+
{ :message => "Hello world!" }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
let(:api_endpoint) { app.endpoints.first }
|
|
47
|
+
let(:env) do
|
|
48
|
+
http_request_env_with_data \
|
|
49
|
+
"api.endpoint" => api_endpoint,
|
|
50
|
+
"REQUEST_METHOD" => "POST",
|
|
51
|
+
:path => "/ping"
|
|
52
|
+
end
|
|
53
|
+
let(:middleware) { Appsignal::Rack::GrapeMiddleware.new(api_endpoint) }
|
|
54
|
+
let(:transaction) { http_request_transaction }
|
|
55
|
+
before(:context) { start_agent }
|
|
56
|
+
around do |example|
|
|
57
|
+
GrapeExample = Module.new
|
|
58
|
+
GrapeExample.send(:const_set, :Api, app)
|
|
59
|
+
keep_transactions { example.run }
|
|
60
|
+
Object.send(:remove_const, :GrapeExample)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def make_request(env)
|
|
64
|
+
middleware.call(env)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def make_request_with_exception(env, exception_class, exception_message)
|
|
68
|
+
expect do
|
|
69
|
+
middleware.call(env)
|
|
70
|
+
end.to raise_error(exception_class, exception_message)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context "with error" do
|
|
74
|
+
let(:app) do
|
|
75
|
+
Class.new(::Grape::API) do
|
|
76
|
+
format :json
|
|
77
|
+
post :ping do
|
|
78
|
+
raise ExampleException, "error message"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "sets the error" do
|
|
84
|
+
make_request_with_exception(env, ExampleException, "error message")
|
|
85
|
+
|
|
86
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "with env['grape.skip_appsignal_error'] = true" do
|
|
90
|
+
let(:app) do
|
|
91
|
+
Class.new(::Grape::API) do
|
|
92
|
+
format :json
|
|
93
|
+
post :ping do
|
|
94
|
+
env["grape.skip_appsignal_error"] = true
|
|
95
|
+
raise ExampleException, "error message"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "does not add the error" do
|
|
101
|
+
make_request_with_exception(env, ExampleException, "error message")
|
|
102
|
+
|
|
103
|
+
expect(last_transaction).to_not have_error
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context "with route" do
|
|
109
|
+
let(:app) do
|
|
110
|
+
Class.new(::Grape::API) do
|
|
111
|
+
route([:get, :post], "hello") do
|
|
112
|
+
"Hello!"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
let(:env) do
|
|
117
|
+
http_request_env_with_data \
|
|
118
|
+
"api.endpoint" => api_endpoint,
|
|
119
|
+
"REQUEST_METHOD" => "GET",
|
|
120
|
+
:path => ""
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "sets non-unique route path" do
|
|
124
|
+
make_request(env)
|
|
125
|
+
|
|
126
|
+
expect(last_transaction).to have_action("GET::GrapeExample::Api#/hello")
|
|
127
|
+
expect(last_transaction).to include_metadata("path" => "/hello", "method" => "GET")
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context "with route_param" do
|
|
132
|
+
let(:app) do
|
|
133
|
+
Class.new(::Grape::API) do
|
|
134
|
+
format :json
|
|
135
|
+
resource :users do
|
|
136
|
+
route_param :id do
|
|
137
|
+
get do
|
|
138
|
+
{ :name => "Tom" }
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
let(:env) do
|
|
145
|
+
http_request_env_with_data \
|
|
146
|
+
"api.endpoint" => api_endpoint,
|
|
147
|
+
"REQUEST_METHOD" => "GET",
|
|
148
|
+
:path => ""
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "sets non-unique route_param path" do
|
|
152
|
+
make_request(env)
|
|
153
|
+
|
|
154
|
+
expect(last_transaction).to have_action("GET::GrapeExample::Api#/users/:id/")
|
|
155
|
+
expect(last_transaction).to include_metadata("path" => "/users/:id/", "method" => "GET")
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
context "with namespaced path" do
|
|
160
|
+
context "with symbols" do
|
|
161
|
+
let(:app) do
|
|
162
|
+
Class.new(::Grape::API) do
|
|
163
|
+
format :json
|
|
164
|
+
namespace :v1 do
|
|
165
|
+
namespace :beta do
|
|
166
|
+
post :ping do
|
|
167
|
+
{ :message => "Hello namespaced world!" }
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "sets namespaced path" do
|
|
175
|
+
make_request(env)
|
|
176
|
+
|
|
177
|
+
expect(last_transaction).to have_action("POST::GrapeExample::Api#/v1/beta/ping")
|
|
178
|
+
expect(last_transaction).to include_metadata("path" => "/v1/beta/ping",
|
|
179
|
+
"method" => "POST")
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
context "with strings" do
|
|
184
|
+
context "without / prefix" do
|
|
185
|
+
let(:app) do
|
|
186
|
+
Class.new(::Grape::API) do
|
|
187
|
+
format :json
|
|
188
|
+
namespace "v1" do
|
|
189
|
+
namespace "beta" do
|
|
190
|
+
post "ping" do
|
|
191
|
+
{ :message => "Hello namespaced world!" }
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "sets namespaced path" do
|
|
199
|
+
make_request(env)
|
|
200
|
+
|
|
201
|
+
expect(last_transaction).to have_action("POST::GrapeExample::Api#/v1/beta/ping")
|
|
202
|
+
expect(last_transaction).to include_metadata(
|
|
203
|
+
"path" => "/v1/beta/ping",
|
|
204
|
+
"method" => "POST"
|
|
205
|
+
)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
context "with / prefix" do
|
|
210
|
+
let(:app) do
|
|
211
|
+
Class.new(::Grape::API) do
|
|
212
|
+
format :json
|
|
213
|
+
namespace "/v1" do
|
|
214
|
+
namespace "/beta" do
|
|
215
|
+
post "/ping" do
|
|
216
|
+
{ :message => "Hello namespaced world!" }
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it "sets namespaced path" do
|
|
224
|
+
make_request(env)
|
|
225
|
+
|
|
226
|
+
expect(last_transaction).to have_action("POST::GrapeExample::Api#/v1/beta/ping")
|
|
227
|
+
expect(last_transaction).to include_metadata("path" => "/v1/beta/ping",
|
|
228
|
+
"method" => "POST")
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
@@ -23,28 +23,14 @@ if DependencyHelper.hanami2_present?
|
|
|
23
23
|
it "sets request parameters on the transaction" do
|
|
24
24
|
make_request(env)
|
|
25
25
|
|
|
26
|
-
expect(last_transaction
|
|
27
|
-
"sample_data" => hash_including(
|
|
28
|
-
"params" => { "param1" => "value1", "param2" => "value2" }
|
|
29
|
-
)
|
|
30
|
-
)
|
|
26
|
+
expect(last_transaction).to include_params("param1" => "value1", "param2" => "value2")
|
|
31
27
|
end
|
|
32
28
|
end
|
|
33
29
|
|
|
34
30
|
it "reports a process_action.hanami event" do
|
|
35
31
|
make_request(env)
|
|
36
32
|
|
|
37
|
-
expect(last_transaction
|
|
38
|
-
"events" => [
|
|
39
|
-
hash_including(
|
|
40
|
-
"body" => "",
|
|
41
|
-
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
|
42
|
-
"count" => 1,
|
|
43
|
-
"name" => "process_action.hanami",
|
|
44
|
-
"title" => ""
|
|
45
|
-
)
|
|
46
|
-
]
|
|
47
|
-
)
|
|
33
|
+
expect(last_transaction).to include_event("name" => "process_action.hanami")
|
|
48
34
|
end
|
|
49
35
|
end
|
|
50
36
|
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
describe Appsignal::Rack::InstrumentationMiddleware do
|
|
2
|
+
let(:app) { DummyApp.new }
|
|
3
|
+
let(:env) { Rack::MockRequest.env_for("/some/path") }
|
|
4
|
+
let(:middleware) { described_class.new(app, {}) }
|
|
5
|
+
|
|
6
|
+
before { start_agent }
|
|
7
|
+
around { |example| keep_transactions { example.run } }
|
|
8
|
+
|
|
9
|
+
def make_request(env)
|
|
10
|
+
middleware.call(env)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context "without an exception" do
|
|
14
|
+
it "reports a process_request_middleware.rack event" do
|
|
15
|
+
make_request(env)
|
|
16
|
+
|
|
17
|
+
expect(last_transaction).to include_event("name" => "process_request_middleware.rack")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "with custom action name" do
|
|
22
|
+
let(:app) { DummyApp.new { |_env| Appsignal.set_action("MyAction") } }
|
|
23
|
+
|
|
24
|
+
it "reports the custom action name" do
|
|
25
|
+
make_request(env)
|
|
26
|
+
|
|
27
|
+
expect(last_transaction).to have_action("MyAction")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "without action name metadata" do
|
|
32
|
+
it "reports no action name" do
|
|
33
|
+
make_request(env)
|
|
34
|
+
|
|
35
|
+
expect(last_transaction).to_not have_action
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -3,11 +3,6 @@ if DependencyHelper.rails_present?
|
|
|
3
3
|
class MockController; end
|
|
4
4
|
|
|
5
5
|
let(:log) { StringIO.new }
|
|
6
|
-
before do
|
|
7
|
-
start_agent
|
|
8
|
-
Appsignal.internal_logger = test_logger(log)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
6
|
let(:transaction) do
|
|
12
7
|
Appsignal::Transaction.new(
|
|
13
8
|
"transaction_id",
|
|
@@ -15,7 +10,7 @@ if DependencyHelper.rails_present?
|
|
|
15
10
|
Rack::Request.new(env)
|
|
16
11
|
)
|
|
17
12
|
end
|
|
18
|
-
let(:app) {
|
|
13
|
+
let(:app) { DummyApp.new }
|
|
19
14
|
let(:params) do
|
|
20
15
|
{
|
|
21
16
|
"controller" => "blog_posts",
|
|
@@ -25,9 +20,8 @@ if DependencyHelper.rails_present?
|
|
|
25
20
|
"password" => "super secret"
|
|
26
21
|
}
|
|
27
22
|
end
|
|
28
|
-
let(:env_extra) { {} }
|
|
29
23
|
let(:env) do
|
|
30
|
-
http_request_env_with_data(
|
|
24
|
+
http_request_env_with_data(
|
|
31
25
|
:params => params,
|
|
32
26
|
:with_queue_start => true,
|
|
33
27
|
"action_dispatch.request_id" => "request_id123",
|
|
@@ -36,160 +30,102 @@ if DependencyHelper.rails_present?
|
|
|
36
30
|
:class => MockController,
|
|
37
31
|
:action_name => "index"
|
|
38
32
|
)
|
|
39
|
-
|
|
33
|
+
)
|
|
40
34
|
end
|
|
41
35
|
let(:middleware) { Appsignal::Rack::RailsInstrumentation.new(app, {}) }
|
|
42
36
|
around { |example| keep_transactions { example.run } }
|
|
43
37
|
before do
|
|
38
|
+
start_agent
|
|
39
|
+
Appsignal.internal_logger = test_logger(log)
|
|
44
40
|
env[Appsignal::Rack::APPSIGNAL_TRANSACTION] = transaction
|
|
45
41
|
end
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
context "when appsignal is active" do
|
|
53
|
-
before { allow(Appsignal).to receive(:active?).and_return(true) }
|
|
54
|
-
|
|
55
|
-
it "calls with monitoring" do
|
|
56
|
-
expect(middleware).to receive(:call_with_appsignal_monitoring).with(env)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
43
|
+
def make_request
|
|
44
|
+
middleware.call(env)
|
|
45
|
+
last_transaction&._sample
|
|
46
|
+
end
|
|
59
47
|
|
|
60
|
-
|
|
61
|
-
|
|
48
|
+
def make_request_with_error(error_class, error_message)
|
|
49
|
+
expect { make_request }.to raise_error(error_class, error_message)
|
|
50
|
+
end
|
|
62
51
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
end
|
|
52
|
+
context "with a request that doesn't raise an error" do
|
|
53
|
+
before { make_request }
|
|
66
54
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
end
|
|
55
|
+
it "calls the next middleware in the stack" do
|
|
56
|
+
expect(app).to be_called
|
|
70
57
|
end
|
|
71
58
|
|
|
72
|
-
|
|
59
|
+
it "does not instrument an event" do
|
|
60
|
+
expect(last_transaction).to_not include_events
|
|
61
|
+
end
|
|
73
62
|
end
|
|
74
63
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
context "with a request that raises an error" do
|
|
65
|
+
let(:app) do
|
|
66
|
+
DummyApp.new { |_env| raise ExampleException, "error message" }
|
|
67
|
+
end
|
|
68
|
+
before do
|
|
69
|
+
make_request_with_error(ExampleException, "error message")
|
|
79
70
|
end
|
|
80
71
|
|
|
81
|
-
it "calls the
|
|
82
|
-
expect
|
|
83
|
-
expect(app).to have_received(:call).with(env)
|
|
72
|
+
it "calls the next middleware in the stack" do
|
|
73
|
+
expect(app).to be_called
|
|
84
74
|
end
|
|
85
75
|
|
|
86
|
-
it "
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
expect(last_transaction.to_h).to include(
|
|
90
|
-
"namespace" => Appsignal::Transaction::HTTP_REQUEST,
|
|
91
|
-
"action" => "MockController#index",
|
|
92
|
-
"metadata" => hash_including(
|
|
93
|
-
"method" => "GET",
|
|
94
|
-
"path" => "/blog"
|
|
95
|
-
),
|
|
96
|
-
"sample_data" => hash_including(
|
|
97
|
-
"tags" => { "request_id" => "request_id123" }
|
|
98
|
-
)
|
|
99
|
-
)
|
|
76
|
+
it "reports the error on the transaction" do
|
|
77
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
|
100
78
|
end
|
|
79
|
+
end
|
|
101
80
|
|
|
102
|
-
|
|
103
|
-
|
|
81
|
+
it "sets the controller action as the action name" do
|
|
82
|
+
make_request
|
|
104
83
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
"my_custom_param" => "[FILTERED]",
|
|
109
|
-
"password" => "[FILTERED]"
|
|
110
|
-
)
|
|
111
|
-
)
|
|
112
|
-
)
|
|
113
|
-
end
|
|
84
|
+
expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
85
|
+
expect(last_transaction).to have_action("MockController#index")
|
|
86
|
+
end
|
|
114
87
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
lambda do |env|
|
|
118
|
-
env[Appsignal::Rack::APPSIGNAL_TRANSACTION].set_params("custom_param" => "yes")
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
it "allows custom params to be set" do
|
|
123
|
-
run
|
|
124
|
-
|
|
125
|
-
expect(last_transaction.to_h).to include(
|
|
126
|
-
"sample_data" => hash_including(
|
|
127
|
-
"params" => {
|
|
128
|
-
"custom_param" => "yes"
|
|
129
|
-
}
|
|
130
|
-
)
|
|
131
|
-
)
|
|
132
|
-
end
|
|
133
|
-
end
|
|
88
|
+
it "sets request metadata on the transaction" do
|
|
89
|
+
make_request
|
|
134
90
|
|
|
135
|
-
|
|
136
|
-
|
|
91
|
+
expect(last_transaction).to include_metadata(
|
|
92
|
+
"method" => "GET",
|
|
93
|
+
"path" => "/blog"
|
|
94
|
+
)
|
|
95
|
+
expect(last_transaction).to include_tags("request_id" => "request_id123")
|
|
96
|
+
end
|
|
137
97
|
|
|
138
|
-
|
|
139
|
-
|
|
98
|
+
it "reports Rails filter parameters" do
|
|
99
|
+
make_request
|
|
140
100
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
101
|
+
expect(last_transaction).to include_params(
|
|
102
|
+
"controller" => "blog_posts",
|
|
103
|
+
"action" => "show",
|
|
104
|
+
"id" => "1",
|
|
105
|
+
"my_custom_param" => "[FILTERED]",
|
|
106
|
+
"password" => "[FILTERED]"
|
|
107
|
+
)
|
|
108
|
+
end
|
|
147
109
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
it "records the exception" do
|
|
157
|
-
expect { run }.to raise_error(error)
|
|
158
|
-
|
|
159
|
-
transaction_hash = last_transaction.to_h
|
|
160
|
-
expect(transaction_hash["error"]).to include(
|
|
161
|
-
"name" => "ExampleException",
|
|
162
|
-
"message" => "ExampleException message",
|
|
163
|
-
"backtrace" => kind_of(String)
|
|
164
|
-
)
|
|
165
|
-
end
|
|
166
|
-
end
|
|
110
|
+
context "with an invalid HTTP request method" do
|
|
111
|
+
it "does not store the invalid HTTP request method" do
|
|
112
|
+
env[:request_method] = "FOO"
|
|
113
|
+
env["REQUEST_METHOD"] = "FOO"
|
|
114
|
+
make_request
|
|
167
115
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
:path => "/unknown-route",
|
|
172
|
-
"action_controller.instance" => nil
|
|
173
|
-
}
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
it "doesn't set an action name" do
|
|
177
|
-
run
|
|
178
|
-
|
|
179
|
-
expect(last_transaction.to_h).to include(
|
|
180
|
-
"action" => nil
|
|
181
|
-
)
|
|
182
|
-
end
|
|
116
|
+
expect(last_transaction).to_not include_metadata("method" => anything)
|
|
117
|
+
expect(log_contents(log))
|
|
118
|
+
.to contains_log(:error, "Unable to report HTTP request method: '")
|
|
183
119
|
end
|
|
184
120
|
end
|
|
185
121
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
122
|
+
context "with a request path that's not a route" do
|
|
123
|
+
it "doesn't set an action name" do
|
|
124
|
+
env[:path] = "/unknown-route"
|
|
125
|
+
env["action_controller.instance"] = nil
|
|
126
|
+
make_request
|
|
190
127
|
|
|
191
|
-
|
|
192
|
-
is_expected.to eq "id"
|
|
128
|
+
expect(last_transaction).to_not have_action
|
|
193
129
|
end
|
|
194
130
|
end
|
|
195
131
|
end
|