appsignal 4.0.4 → 4.0.6
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 +151 -16
- data/CHANGELOG.md +42 -0
- data/build_matrix.yml +2 -1
- data/ext/agent.rb +27 -27
- data/gemfiles/que-1.gemfile +5 -0
- data/gemfiles/que-2.gemfile +5 -0
- data/lib/appsignal/check_in/scheduler.rb +3 -4
- data/lib/appsignal/config.rb +7 -0
- data/lib/appsignal/hooks/at_exit.rb +1 -0
- data/lib/appsignal/hooks/puma.rb +5 -1
- data/lib/appsignal/integrations/puma.rb +45 -0
- data/lib/appsignal/integrations/que.rb +8 -2
- data/lib/appsignal/rack/abstract_middleware.rb +3 -47
- data/lib/appsignal/rack/event_handler.rb +2 -0
- data/lib/appsignal/rack/hanami_middleware.rb +5 -1
- data/lib/appsignal/rack.rb +68 -0
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/check_in/cron_spec.rb +134 -134
- data/spec/lib/appsignal/check_in/scheduler_spec.rb +297 -224
- data/spec/lib/appsignal/config_spec.rb +13 -0
- data/spec/lib/appsignal/hooks/at_exit_spec.rb +11 -0
- data/spec/lib/appsignal/hooks/puma_spec.rb +31 -23
- data/spec/lib/appsignal/integrations/puma_spec.rb +150 -0
- data/spec/lib/appsignal/integrations/que_spec.rb +56 -21
- data/spec/lib/appsignal/probes_spec.rb +4 -6
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +41 -122
- data/spec/lib/appsignal/rack_spec.rb +180 -0
- data/spec/lib/appsignal/transaction_spec.rb +96 -92
- data/spec/spec_helper.rb +6 -7
- data/spec/support/helpers/api_request_helper.rb +40 -0
- data/spec/support/helpers/config_helpers.rb +2 -1
- data/spec/support/helpers/dependency_helper.rb +5 -0
- data/spec/support/matchers/contains_log.rb +10 -3
- data/spec/support/mocks/hash_like.rb +10 -0
- data/spec/support/mocks/puma_mock.rb +43 -0
- data/spec/support/testing.rb +9 -0
- metadata +8 -3
- data/gemfiles/que.gemfile +0 -5
@@ -1,5 +1,18 @@
|
|
1
1
|
describe Appsignal::Config do
|
2
2
|
describe ".add_loader_defaults" do
|
3
|
+
context "when the config is initialized" do
|
4
|
+
before { Appsignal.configure(:test) }
|
5
|
+
|
6
|
+
it "logs a warning" do
|
7
|
+
logs = capture_logs { described_class.add_loader_defaults(:loader1) }
|
8
|
+
|
9
|
+
expect(logs).to contains_log(
|
10
|
+
:warn,
|
11
|
+
"The config defaults from the 'loader1' loader are ignored"
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
3
16
|
it "adds loader defaults to the list" do
|
4
17
|
described_class.add_loader_defaults(:loader1)
|
5
18
|
|
@@ -40,6 +40,17 @@ describe Appsignal::Hooks::AtExit::AtExitCallback do
|
|
40
40
|
Appsignal::Hooks::AtExit::AtExitCallback.call
|
41
41
|
end
|
42
42
|
|
43
|
+
it "reports no transaction if the process didn't exit with an error" do
|
44
|
+
logs =
|
45
|
+
capture_logs do
|
46
|
+
expect do
|
47
|
+
call_callback
|
48
|
+
end.to_not(change { created_transactions.count })
|
49
|
+
end
|
50
|
+
|
51
|
+
expect(logs).to_not contains_log(:error, "Appsignal.report_error: Cannot add error.")
|
52
|
+
end
|
53
|
+
|
43
54
|
it "reports an error if there's an unhandled error" do
|
44
55
|
expect do
|
45
56
|
with_error(ExampleException, "error message") do
|
@@ -1,34 +1,45 @@
|
|
1
1
|
describe Appsignal::Hooks::PumaHook do
|
2
2
|
context "with puma" do
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
let(:puma_version) { "6.0.0" }
|
4
|
+
before do
|
5
|
+
stub_const("Puma", PumaMock)
|
6
|
+
stub_const("Puma::Const::VERSION", puma_version)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#dependencies_present?" do
|
10
|
+
subject { described_class.new.dependencies_present? }
|
11
|
+
|
12
|
+
context "when Puma present" do
|
13
|
+
context "when Puma is newer than version 3.0.0" do
|
14
|
+
let(:puma_version) { "3.0.0" }
|
7
15
|
|
8
|
-
|
9
|
-
@cli_config ||= CliConfig.new
|
16
|
+
it { is_expected.to be_truthy }
|
10
17
|
end
|
11
|
-
end
|
12
18
|
|
13
|
-
|
14
|
-
|
19
|
+
context "when Puma is older than version 3.0.0" do
|
20
|
+
let(:puma_version) { "2.9.9" }
|
15
21
|
|
16
|
-
|
17
|
-
@options = {}
|
22
|
+
it { is_expected.to be_falsey }
|
18
23
|
end
|
19
24
|
end
|
20
|
-
end
|
21
|
-
after(:context) { Object.send(:remove_const, :Puma) }
|
22
25
|
|
23
|
-
|
24
|
-
|
26
|
+
context "when Puma is not present" do
|
27
|
+
before do
|
28
|
+
hide_const("Puma")
|
29
|
+
end
|
25
30
|
|
26
|
-
|
31
|
+
it { is_expected.to be_falsey }
|
32
|
+
end
|
27
33
|
end
|
28
34
|
|
29
35
|
describe "installation" do
|
30
36
|
before { Appsignal::Probes.probes.clear }
|
31
37
|
|
38
|
+
it "adds the Puma::Server patch" do
|
39
|
+
Appsignal::Hooks::PumaHook.new.install
|
40
|
+
expect(::Puma::Server.included_modules).to include(Appsignal::Integrations::PumaServer)
|
41
|
+
end
|
42
|
+
|
32
43
|
context "when not clustered mode" do
|
33
44
|
it "does not add AppSignal stop behavior Puma::Cluster" do
|
34
45
|
expect(defined?(::Puma::Cluster)).to be_falsy
|
@@ -39,15 +50,12 @@ describe Appsignal::Hooks::PumaHook do
|
|
39
50
|
|
40
51
|
context "when in clustered mode" do
|
41
52
|
before do
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
@called = true
|
46
|
-
end
|
53
|
+
stub_const("Puma::Cluster", Class.new do
|
54
|
+
def stop_workers
|
55
|
+
@called = true
|
47
56
|
end
|
48
|
-
end
|
57
|
+
end)
|
49
58
|
end
|
50
|
-
after { Puma.send(:remove_const, :Cluster) }
|
51
59
|
|
52
60
|
it "adds behavior to Puma::Cluster.stop_workers" do
|
53
61
|
Appsignal::Hooks::PumaHook.new.install
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require "appsignal/integrations/puma"
|
2
|
+
|
3
|
+
describe Appsignal::Integrations::PumaServer do
|
4
|
+
describe "#lowlevel_error" do
|
5
|
+
before do
|
6
|
+
stub_const("Puma", PumaMock)
|
7
|
+
stub_const("Puma::Server", puma_server)
|
8
|
+
start_agent
|
9
|
+
end
|
10
|
+
let(:queue_start_time) { fixed_time * 1_000 }
|
11
|
+
let(:env) do
|
12
|
+
Rack::MockRequest.env_for(
|
13
|
+
"/some/path",
|
14
|
+
"REQUEST_METHOD" => "GET",
|
15
|
+
:params => { "page" => 2, "query" => "lorem" },
|
16
|
+
"rack.session" => { "session" => "data", "user_id" => 123 },
|
17
|
+
"HTTP_X_REQUEST_START" => "t=#{queue_start_time.to_i}" # in milliseconds
|
18
|
+
)
|
19
|
+
end
|
20
|
+
let(:server) { Puma::Server.new }
|
21
|
+
let(:error) { ExampleException.new("error message") }
|
22
|
+
around { |example| keep_transactions { example.run } }
|
23
|
+
before { Appsignal::Hooks::PumaHook.new.install }
|
24
|
+
|
25
|
+
def lowlevel_error(error, env, status = nil)
|
26
|
+
result =
|
27
|
+
if status
|
28
|
+
server.lowlevel_error(error, env, status)
|
29
|
+
else
|
30
|
+
server.lowlevel_error(error, env)
|
31
|
+
end
|
32
|
+
# Transaction is normally closed by the EventHandler's RACK_AFTER_REPLY hook
|
33
|
+
last_transaction&.complete
|
34
|
+
result
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "error reporting" do
|
38
|
+
let(:puma_server) { default_puma_server_mock }
|
39
|
+
|
40
|
+
context "with active transaction" do
|
41
|
+
before { create_transaction }
|
42
|
+
|
43
|
+
it "reports the error to the transaction" do
|
44
|
+
expect do
|
45
|
+
lowlevel_error(error, env)
|
46
|
+
end.to_not(change { created_transactions.count })
|
47
|
+
|
48
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
49
|
+
expect(last_transaction).to include_tags("reported_by" => "puma_lowlevel_error")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# This shouldn't happen if the EventHandler is set up correctly, but if
|
54
|
+
# it's not it will create a new transaction.
|
55
|
+
context "without active transaction" do
|
56
|
+
it "creates a new transaction with the error" do
|
57
|
+
expect do
|
58
|
+
lowlevel_error(error, env)
|
59
|
+
end.to change { created_transactions.count }.by(1)
|
60
|
+
|
61
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
62
|
+
expect(last_transaction).to include_tags("reported_by" => "puma_lowlevel_error")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
it "doesn't report internal Puma errors" do
|
67
|
+
expect do
|
68
|
+
lowlevel_error(Puma::MiniSSL::SSLError.new("error message"), env)
|
69
|
+
lowlevel_error(Puma::HttpParserError.new("error message"), env)
|
70
|
+
lowlevel_error(Puma::HttpParserError501.new("error message"), env)
|
71
|
+
end.to_not(change { created_transactions.count })
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "request metadata" do
|
75
|
+
it "sets request metadata" do
|
76
|
+
lowlevel_error(error, env)
|
77
|
+
|
78
|
+
expect(last_transaction).to include_metadata(
|
79
|
+
"request_method" => "GET",
|
80
|
+
"method" => "GET",
|
81
|
+
"request_path" => "/some/path",
|
82
|
+
"path" => "/some/path"
|
83
|
+
)
|
84
|
+
expect(last_transaction).to include_environment(
|
85
|
+
"REQUEST_METHOD" => "GET",
|
86
|
+
"PATH_INFO" => "/some/path"
|
87
|
+
# and more, but we don't need to test Rack mock defaults
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "sets request parameters" do
|
92
|
+
lowlevel_error(error, env)
|
93
|
+
|
94
|
+
expect(last_transaction).to include_params(
|
95
|
+
"page" => "2",
|
96
|
+
"query" => "lorem"
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "sets session data" do
|
101
|
+
lowlevel_error(error, env)
|
102
|
+
|
103
|
+
expect(last_transaction).to include_session_data("session" => "data", "user_id" => 123)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "sets the queue start" do
|
107
|
+
lowlevel_error(error, env)
|
108
|
+
|
109
|
+
expect(last_transaction).to have_queue_start(queue_start_time)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "with Puma::Server#lowlevel_error accepting 3 arguments" do
|
115
|
+
let(:puma_server) { default_puma_server_mock }
|
116
|
+
|
117
|
+
it "calls the super class with 3 arguments" do
|
118
|
+
result = lowlevel_error(error, env, 501)
|
119
|
+
expect(result).to eq([501, {}, ""])
|
120
|
+
|
121
|
+
expect(last_transaction).to include_tags("response_status" => 501)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "with Puma::Server#lowlevel_error accepting 2 arguments" do
|
126
|
+
let(:puma_server) do
|
127
|
+
Class.new do
|
128
|
+
def lowlevel_error(_error, _env)
|
129
|
+
[500, {}, ""]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it "calls the super class with 3 arguments" do
|
135
|
+
result = lowlevel_error(error, env)
|
136
|
+
expect(result).to eq([500, {}, ""])
|
137
|
+
|
138
|
+
expect(last_transaction).to include_tags("response_status" => 500)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def default_puma_server_mock
|
144
|
+
Class.new do
|
145
|
+
def lowlevel_error(_error, _env, status = 500)
|
146
|
+
[status, {}, ""]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -9,28 +9,16 @@ if DependencyHelper.que_present?
|
|
9
9
|
:queue => "dfl",
|
10
10
|
:job_class => "MyQueJob",
|
11
11
|
:priority => 100,
|
12
|
-
:args => %w[
|
12
|
+
:args => %w[post_id_123 user_id_123],
|
13
13
|
:run_at => fixed_time,
|
14
14
|
:error_count => 0
|
15
|
-
}
|
16
|
-
|
17
|
-
|
18
|
-
{
|
19
|
-
:class => "MyQueJob",
|
20
|
-
:method => "run",
|
21
|
-
:metadata => {
|
22
|
-
:id => 123,
|
23
|
-
:queue => "dfl",
|
24
|
-
:priority => 100,
|
25
|
-
:run_at => fixed_time.to_s,
|
26
|
-
:attempts => 0
|
27
|
-
},
|
28
|
-
:params => %w[1 birds]
|
29
|
-
}
|
15
|
+
}.tap do |hash|
|
16
|
+
hash[:kwargs] = {} if DependencyHelper.que2_present?
|
17
|
+
end
|
30
18
|
end
|
31
19
|
let(:job) do
|
32
20
|
Class.new(::Que::Job) do
|
33
|
-
def run(
|
21
|
+
def run(post_id, user_id)
|
34
22
|
end
|
35
23
|
end
|
36
24
|
end
|
@@ -46,7 +34,7 @@ if DependencyHelper.que_present?
|
|
46
34
|
job._run
|
47
35
|
end
|
48
36
|
|
49
|
-
context "
|
37
|
+
context "without exception" do
|
50
38
|
it "creates a transaction for a job" do
|
51
39
|
expect do
|
52
40
|
perform_que_job(instance)
|
@@ -64,7 +52,18 @@ if DependencyHelper.que_present?
|
|
64
52
|
"name" => "perform_job.que",
|
65
53
|
"title" => ""
|
66
54
|
)
|
67
|
-
expect(transaction).to include_params(
|
55
|
+
expect(transaction).to include_params(
|
56
|
+
"arguments" => %w[post_id_123 user_id_123]
|
57
|
+
)
|
58
|
+
if DependencyHelper.que2_present?
|
59
|
+
expect(transaction).to include_params(
|
60
|
+
"keyword_arguments" => {}
|
61
|
+
)
|
62
|
+
else
|
63
|
+
expect(transaction).to_not include_params(
|
64
|
+
"keyword_arguments" => anything
|
65
|
+
)
|
66
|
+
end
|
68
67
|
expect(transaction).to include_tags(
|
69
68
|
"attempts" => 0,
|
70
69
|
"id" => 123,
|
@@ -93,7 +92,9 @@ if DependencyHelper.que_present?
|
|
93
92
|
expect(transaction).to have_action("MyQueJob#run")
|
94
93
|
expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
|
95
94
|
expect(transaction).to have_error(error.class.name, error.message)
|
96
|
-
expect(transaction).to include_params(
|
95
|
+
expect(transaction).to include_params(
|
96
|
+
"arguments" => %w[post_id_123 user_id_123]
|
97
|
+
)
|
97
98
|
expect(transaction).to include_tags(
|
98
99
|
"attempts" => 0,
|
99
100
|
"id" => 123,
|
@@ -118,7 +119,9 @@ if DependencyHelper.que_present?
|
|
118
119
|
expect(transaction).to have_action("MyQueJob#run")
|
119
120
|
expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
|
120
121
|
expect(transaction).to have_error(error.class.name, error.message)
|
121
|
-
expect(transaction).to include_params(
|
122
|
+
expect(transaction).to include_params(
|
123
|
+
"arguments" => %w[post_id_123 user_id_123]
|
124
|
+
)
|
122
125
|
expect(transaction).to include_tags(
|
123
126
|
"attempts" => 0,
|
124
127
|
"id" => 123,
|
@@ -130,6 +133,38 @@ if DependencyHelper.que_present?
|
|
130
133
|
end
|
131
134
|
end
|
132
135
|
|
136
|
+
if DependencyHelper.que2_present?
|
137
|
+
context "with keyword argument" do
|
138
|
+
let(:job_attrs) do
|
139
|
+
{
|
140
|
+
:job_id => 123,
|
141
|
+
:queue => "dfl",
|
142
|
+
:job_class => "MyQueJob",
|
143
|
+
:priority => 100,
|
144
|
+
:args => %w[post_id_123],
|
145
|
+
:kwargs => { :user_id => "user_id_123" },
|
146
|
+
:run_at => fixed_time,
|
147
|
+
:error_count => 0
|
148
|
+
}
|
149
|
+
end
|
150
|
+
let(:job) do
|
151
|
+
Class.new(::Que::Job) do
|
152
|
+
def run(post_id, user_id: nil)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
it "reports keyword arguments as parameters" do
|
158
|
+
perform_que_job(instance)
|
159
|
+
|
160
|
+
expect(last_transaction).to include_params(
|
161
|
+
"arguments" => %w[post_id_123],
|
162
|
+
"keyword_arguments" => { "user_id" => "user_id_123" }
|
163
|
+
)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
133
168
|
context "when action set in job" do
|
134
169
|
let(:job) do
|
135
170
|
Class.new(::Que::Job) do
|
@@ -43,6 +43,9 @@ describe Appsignal::Probes do
|
|
43
43
|
let(:log) { log_contents(log_stream) }
|
44
44
|
before do
|
45
45
|
Appsignal.internal_logger = test_logger(log_stream)
|
46
|
+
# TODO: These logs are here to debug an issue on CI
|
47
|
+
Appsignal.internal_logger.info("a" * 100)
|
48
|
+
Appsignal.internal_logger.info("b" * 100)
|
46
49
|
speed_up_tests!
|
47
50
|
end
|
48
51
|
|
@@ -244,12 +247,7 @@ describe Appsignal::Probes do
|
|
244
247
|
end
|
245
248
|
|
246
249
|
describe ".unregister" do
|
247
|
-
|
248
|
-
let(:log) { log_contents(log_stream) }
|
249
|
-
before do
|
250
|
-
Appsignal.internal_logger = test_logger(log_stream)
|
251
|
-
speed_up_tests!
|
252
|
-
end
|
250
|
+
before { speed_up_tests! }
|
253
251
|
|
254
252
|
it "does not call the initialized probe after unregistering" do
|
255
253
|
probe1_calls = 0
|
@@ -1,19 +1,8 @@
|
|
1
1
|
describe Appsignal::Rack::AbstractMiddleware do
|
2
|
-
class HashLike < Hash
|
3
|
-
def initialize(value)
|
4
|
-
@value = value
|
5
|
-
end
|
6
|
-
|
7
|
-
def to_h
|
8
|
-
@value
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
2
|
let(:app) { DummyApp.new }
|
13
|
-
let(:request_path) { "/some/path" }
|
14
3
|
let(:env) do
|
15
4
|
Rack::MockRequest.env_for(
|
16
|
-
|
5
|
+
"/some/path",
|
17
6
|
"REQUEST_METHOD" => "GET",
|
18
7
|
:params => { "page" => 2, "query" => "lorem" },
|
19
8
|
"rack.session" => { "session" => "data", "user_id" => 123 }
|
@@ -174,13 +163,17 @@ describe Appsignal::Rack::AbstractMiddleware do
|
|
174
163
|
end
|
175
164
|
end
|
176
165
|
|
166
|
+
# Partial duplicate tests from Appsignal::Rack::ApplyRackRequest that
|
167
|
+
# ensure the request metadata is set on via the AbstractMiddleware.
|
177
168
|
describe "request metadata" do
|
178
169
|
it "sets request metadata" do
|
179
170
|
env.merge!("PATH_INFO" => "/some/path", "REQUEST_METHOD" => "GET")
|
180
171
|
make_request
|
181
172
|
|
182
173
|
expect(last_transaction).to include_metadata(
|
174
|
+
"request_method" => "GET",
|
183
175
|
"method" => "GET",
|
176
|
+
"request_path" => "/some/path",
|
184
177
|
"path" => "/some/path"
|
185
178
|
)
|
186
179
|
expect(last_transaction).to include_environment(
|
@@ -190,36 +183,6 @@ describe Appsignal::Rack::AbstractMiddleware do
|
|
190
183
|
)
|
191
184
|
end
|
192
185
|
|
193
|
-
context "with an invalid HTTP request method" do
|
194
|
-
it "stores the invalid HTTP request method" do
|
195
|
-
env["REQUEST_METHOD"] = "FOO"
|
196
|
-
make_request
|
197
|
-
|
198
|
-
expect(last_transaction).to include_metadata("method" => "FOO")
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
context "when fetching the request method raises an error" do
|
203
|
-
class BrokenRequestMethodRequest < Rack::Request
|
204
|
-
def request_method
|
205
|
-
raise "uh oh!"
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
let(:options) { { :request_class => BrokenRequestMethodRequest } }
|
210
|
-
|
211
|
-
it "does not store the invalid HTTP request method" do
|
212
|
-
env["REQUEST_METHOD"] = "FOO"
|
213
|
-
logs = capture_logs { make_request }
|
214
|
-
|
215
|
-
expect(last_transaction).to_not include_metadata("method" => anything)
|
216
|
-
expect(logs).to contains_log(
|
217
|
-
:error,
|
218
|
-
"Exception while fetching the HTTP request method: RuntimeError: uh oh"
|
219
|
-
)
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
186
|
it "sets request parameters" do
|
224
187
|
make_request
|
225
188
|
|
@@ -229,107 +192,63 @@ describe Appsignal::Rack::AbstractMiddleware do
|
|
229
192
|
)
|
230
193
|
end
|
231
194
|
|
232
|
-
context "when setting custom params" do
|
233
|
-
let(:app) do
|
234
|
-
DummyApp.new do |_env|
|
235
|
-
Appsignal::Transaction.current.set_params("custom" => "param")
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
it "allow custom request parameters to be set" do
|
240
|
-
make_request
|
241
|
-
|
242
|
-
expect(last_transaction).to include_params("custom" => "param")
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
context "when fetching the request method raises an error" do
|
247
|
-
class BrokenRequestParamsRequest < Rack::Request
|
248
|
-
def params
|
249
|
-
raise "uh oh!"
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
let(:options) do
|
254
|
-
{ :request_class => BrokenRequestParamsRequest, :params_method => :params }
|
255
|
-
end
|
256
|
-
|
257
|
-
it "does not store the invalid HTTP request method" do
|
258
|
-
logs = capture_logs { make_request }
|
259
|
-
|
260
|
-
expect(last_transaction).to_not include_params
|
261
|
-
expect(logs).to contains_log(
|
262
|
-
:error,
|
263
|
-
"Exception while fetching params " \
|
264
|
-
"from 'BrokenRequestParamsRequest#params': RuntimeError uh oh!"
|
265
|
-
)
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
195
|
it "sets session data" do
|
270
196
|
make_request
|
271
197
|
|
272
198
|
expect(last_transaction).to include_session_data("session" => "data", "user_id" => 123)
|
273
199
|
end
|
274
200
|
|
275
|
-
|
276
|
-
|
277
|
-
make_request
|
278
|
-
|
279
|
-
expect(last_transaction).to include_session_data("hash-like" => "value", "user_id" => 123)
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
context "with queue start header" do
|
284
|
-
let(:queue_start_time) { fixed_time * 1_000 }
|
201
|
+
context "with queue start header" do
|
202
|
+
let(:queue_start_time) { fixed_time * 1_000 }
|
285
203
|
|
286
|
-
|
287
|
-
|
288
|
-
|
204
|
+
it "sets the queue start" do
|
205
|
+
env["HTTP_X_REQUEST_START"] = "t=#{queue_start_time.to_i}" # in milliseconds
|
206
|
+
make_request
|
289
207
|
|
290
|
-
|
208
|
+
expect(last_transaction).to have_queue_start(queue_start_time)
|
209
|
+
end
|
291
210
|
end
|
292
|
-
end
|
293
211
|
|
294
|
-
|
295
|
-
|
212
|
+
class SomeFilteredRequest
|
213
|
+
attr_reader :env
|
296
214
|
|
297
|
-
|
298
|
-
|
299
|
-
|
215
|
+
def initialize(env)
|
216
|
+
@env = env
|
217
|
+
end
|
300
218
|
|
301
|
-
|
302
|
-
|
303
|
-
|
219
|
+
def path
|
220
|
+
"/static/path"
|
221
|
+
end
|
304
222
|
|
305
|
-
|
306
|
-
|
307
|
-
|
223
|
+
def request_method
|
224
|
+
"GET"
|
225
|
+
end
|
308
226
|
|
309
|
-
|
310
|
-
|
311
|
-
|
227
|
+
def filtered_params
|
228
|
+
{ "abc" => "123" }
|
229
|
+
end
|
312
230
|
|
313
|
-
|
314
|
-
|
231
|
+
def session
|
232
|
+
{ "data" => "value" }
|
233
|
+
end
|
315
234
|
end
|
316
|
-
end
|
317
235
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
236
|
+
context "with overridden request class and params method" do
|
237
|
+
let(:options) do
|
238
|
+
{ :request_class => SomeFilteredRequest, :params_method => :filtered_params }
|
239
|
+
end
|
322
240
|
|
323
|
-
|
324
|
-
|
241
|
+
it "uses the overridden request class and params method to fetch params" do
|
242
|
+
make_request
|
325
243
|
|
326
|
-
|
327
|
-
|
244
|
+
expect(last_transaction).to include_params("abc" => "123")
|
245
|
+
end
|
328
246
|
|
329
|
-
|
330
|
-
|
247
|
+
it "uses the overridden request class to fetch session data" do
|
248
|
+
make_request
|
331
249
|
|
332
|
-
|
250
|
+
expect(last_transaction).to include_session_data("data" => "value")
|
251
|
+
end
|
333
252
|
end
|
334
253
|
end
|
335
254
|
|