appsignal 3.9.2-java → 3.9.3-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 +3135 -0
- data/.rubocop.yml +28 -20
- data/.rubocop_todo.yml +7 -33
- data/CHANGELOG.md +38 -0
- data/Rakefile +79 -64
- data/appsignal.gemspec +1 -1
- data/build_matrix.yml +109 -179
- data/ext/base.rb +1 -1
- data/gemfiles/hanami-2.1.gemfile +7 -0
- data/lib/appsignal/cli/diagnose.rb +1 -1
- data/lib/appsignal/config.rb +1 -1
- data/lib/appsignal/demo.rb +0 -1
- data/lib/appsignal/environment.rb +5 -1
- data/lib/appsignal/extension/jruby.rb +1 -1
- data/lib/appsignal/helpers/instrumentation.rb +1 -1
- data/lib/appsignal/integrations/grape.rb +19 -47
- data/lib/appsignal/integrations/hanami.rb +8 -7
- data/lib/appsignal/integrations/padrino.rb +46 -43
- data/lib/appsignal/integrations/railtie.rb +0 -3
- data/lib/appsignal/integrations/sinatra.rb +0 -1
- 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 +62 -28
- data/lib/appsignal/rack/event_handler.rb +12 -3
- data/lib/appsignal/rack/grape_middleware.rb +40 -0
- data/lib/appsignal/rack/hanami_middleware.rb +1 -11
- data/lib/appsignal/rack/rails_instrumentation.rb +14 -55
- 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 +34 -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 +7 -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 +9 -19
- 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 +47 -70
- 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 +0 -1
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +28 -39
- 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 +215 -106
- data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -78
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +2 -12
- 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/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 +68 -86
- data/spec/lib/appsignal/transaction_spec.rb +76 -90
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
- data/spec/lib/appsignal_spec.rb +363 -342
- 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 +15 -10
- 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/gemfiles/{hanami.gemfile → hanami-2.0.gemfile} +0 -0
|
@@ -4,6 +4,13 @@ describe Appsignal::Probes::GvlProbe do
|
|
|
4
4
|
|
|
5
5
|
let(:hostname) { "some-host" }
|
|
6
6
|
|
|
7
|
+
around do |example|
|
|
8
|
+
real_program_name = $PROGRAM_NAME
|
|
9
|
+
example.run
|
|
10
|
+
ensure
|
|
11
|
+
$PROGRAM_NAME = real_program_name
|
|
12
|
+
end
|
|
13
|
+
|
|
7
14
|
def gauges_for(metric)
|
|
8
15
|
gauges = appsignal_mock.gauges.select do |gauge|
|
|
9
16
|
gauge[0] == metric
|
|
@@ -14,7 +21,7 @@ describe Appsignal::Probes::GvlProbe do
|
|
|
14
21
|
end
|
|
15
22
|
end
|
|
16
23
|
|
|
17
|
-
after
|
|
24
|
+
after { FakeGVLTools.reset }
|
|
18
25
|
|
|
19
26
|
it "gauges the global timer delta" do
|
|
20
27
|
FakeGVLTools::GlobalTimer.monotonic_time = 100_000_000
|
|
@@ -26,6 +33,11 @@ describe Appsignal::Probes::GvlProbe do
|
|
|
26
33
|
probe.call
|
|
27
34
|
|
|
28
35
|
expect(gauges_for("gvl_global_timer")).to eq [
|
|
36
|
+
[200, {
|
|
37
|
+
:hostname => hostname,
|
|
38
|
+
:process_name => "rspec",
|
|
39
|
+
:process_id => Process.pid
|
|
40
|
+
}],
|
|
29
41
|
[200, { :hostname => hostname }]
|
|
30
42
|
]
|
|
31
43
|
end
|
|
@@ -58,7 +70,7 @@ describe Appsignal::Probes::GvlProbe do
|
|
|
58
70
|
end
|
|
59
71
|
|
|
60
72
|
context "when the waiting threads count is enabled" do
|
|
61
|
-
before
|
|
73
|
+
before do
|
|
62
74
|
FakeGVLTools::WaitingThreads.enabled = true
|
|
63
75
|
end
|
|
64
76
|
|
|
@@ -67,13 +79,18 @@ describe Appsignal::Probes::GvlProbe do
|
|
|
67
79
|
probe.call
|
|
68
80
|
|
|
69
81
|
expect(gauges_for("gvl_waiting_threads")).to eq [
|
|
82
|
+
[3, {
|
|
83
|
+
:hostname => hostname,
|
|
84
|
+
:process_name => "rspec",
|
|
85
|
+
:process_id => Process.pid
|
|
86
|
+
}],
|
|
70
87
|
[3, { :hostname => hostname }]
|
|
71
88
|
]
|
|
72
89
|
end
|
|
73
90
|
end
|
|
74
91
|
|
|
75
92
|
context "when the waiting threads count is disabled" do
|
|
76
|
-
before
|
|
93
|
+
before do
|
|
77
94
|
FakeGVLTools::WaitingThreads.enabled = false
|
|
78
95
|
end
|
|
79
96
|
|
|
@@ -84,4 +101,64 @@ describe Appsignal::Probes::GvlProbe do
|
|
|
84
101
|
expect(gauges_for("gvl_waiting_threads")).to be_empty
|
|
85
102
|
end
|
|
86
103
|
end
|
|
104
|
+
|
|
105
|
+
context "when the process name is a custom value" do
|
|
106
|
+
before do
|
|
107
|
+
FakeGVLTools::WaitingThreads.enabled = true
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "uses only the first word as the process name" do
|
|
111
|
+
$PROGRAM_NAME = "sidekiq 7.1.6 app [0 of 5 busy]"
|
|
112
|
+
probe.call
|
|
113
|
+
|
|
114
|
+
expect(gauges_for("gvl_waiting_threads")).to eq [
|
|
115
|
+
[0, {
|
|
116
|
+
:hostname => hostname,
|
|
117
|
+
:process_name => "sidekiq",
|
|
118
|
+
:process_id => Process.pid
|
|
119
|
+
}],
|
|
120
|
+
[0, { :hostname => hostname }]
|
|
121
|
+
]
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
context "when the process name is a path" do
|
|
126
|
+
before do
|
|
127
|
+
FakeGVLTools::WaitingThreads.enabled = true
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "uses only the binary name as the process name" do
|
|
131
|
+
$PROGRAM_NAME = "/foo/folder with spaces/bin/rails"
|
|
132
|
+
probe.call
|
|
133
|
+
|
|
134
|
+
expect(gauges_for("gvl_waiting_threads")).to eq [
|
|
135
|
+
[0, {
|
|
136
|
+
:hostname => hostname,
|
|
137
|
+
:process_name => "rails",
|
|
138
|
+
:process_id => Process.pid
|
|
139
|
+
}],
|
|
140
|
+
[0, { :hostname => hostname }]
|
|
141
|
+
]
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
context "when the process name is an empty string" do
|
|
146
|
+
before do
|
|
147
|
+
FakeGVLTools::WaitingThreads.enabled = true
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "uses [unknown process] as the process name" do
|
|
151
|
+
$PROGRAM_NAME = ""
|
|
152
|
+
probe.call
|
|
153
|
+
|
|
154
|
+
expect(gauges_for("gvl_waiting_threads")).to eq [
|
|
155
|
+
[0, {
|
|
156
|
+
:hostname => hostname,
|
|
157
|
+
:process_name => "[unknown process]",
|
|
158
|
+
:process_id => Process.pid
|
|
159
|
+
}],
|
|
160
|
+
[0, { :hostname => hostname }]
|
|
161
|
+
]
|
|
162
|
+
end
|
|
163
|
+
end
|
|
87
164
|
end
|
|
@@ -20,7 +20,7 @@ describe Appsignal::Probes do
|
|
|
20
20
|
.to include("appsignal WARNING: The constant Appsignal::Minutely has been deprecated.")
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
it "logs a warning
|
|
23
|
+
it "logs a warning" do
|
|
24
24
|
logs =
|
|
25
25
|
capture_logs do
|
|
26
26
|
silence do
|
|
@@ -28,7 +28,10 @@ describe Appsignal::Probes do
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
expect(logs).to
|
|
31
|
+
expect(logs).to contains_log(
|
|
32
|
+
:warn,
|
|
33
|
+
"The constant Appsignal::Minutely has been deprecated."
|
|
34
|
+
)
|
|
32
35
|
end
|
|
33
36
|
end
|
|
34
37
|
|
|
@@ -78,7 +81,7 @@ describe Appsignal::Probes do
|
|
|
78
81
|
describe ".started?" do
|
|
79
82
|
it "returns true when the probes thread has been started" do
|
|
80
83
|
expect(Appsignal::Probes.started?).to be_falsy
|
|
81
|
-
Appsignal::Probes.register :my_probe,
|
|
84
|
+
Appsignal::Probes.register :my_probe, lambda {}
|
|
82
85
|
Appsignal::Probes.start
|
|
83
86
|
expect(Appsignal::Probes.started?).to be_truthy
|
|
84
87
|
end
|
|
@@ -475,7 +478,7 @@ describe Appsignal::Probes do
|
|
|
475
478
|
probe = lambda {}
|
|
476
479
|
collection.internal_register :my_probe, probe
|
|
477
480
|
list = []
|
|
478
|
-
collection.each do |name, p|
|
|
481
|
+
collection.each do |name, p| # rubocop:disable Style/MapIntoArray
|
|
479
482
|
list << [name, p]
|
|
480
483
|
end
|
|
481
484
|
expect(list).to eql([[:my_probe, probe]])
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
describe Appsignal::Rack::AbstractMiddleware do
|
|
2
|
-
let(:app) {
|
|
2
|
+
let(:app) { DummyApp.new }
|
|
3
3
|
let(:request_path) { "/some/path" }
|
|
4
4
|
let(:env) do
|
|
5
5
|
Rack::MockRequest.env_for(
|
|
@@ -9,176 +9,235 @@ describe Appsignal::Rack::AbstractMiddleware do
|
|
|
9
9
|
)
|
|
10
10
|
end
|
|
11
11
|
let(:options) { {} }
|
|
12
|
-
let(:middleware) {
|
|
12
|
+
let(:middleware) { described_class.new(app, options) }
|
|
13
13
|
|
|
14
14
|
before(:context) { start_agent }
|
|
15
15
|
around { |example| keep_transactions { example.run } }
|
|
16
16
|
|
|
17
|
-
def make_request
|
|
17
|
+
def make_request
|
|
18
18
|
middleware.call(env)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def make_request_with_error(
|
|
22
|
-
expect { make_request
|
|
21
|
+
def make_request_with_error(error_class, error_message)
|
|
22
|
+
expect { make_request }.to raise_error(error_class, error_message)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
describe "#call" do
|
|
26
|
-
context "when
|
|
26
|
+
context "when not active" do
|
|
27
27
|
before { allow(Appsignal).to receive(:active?).and_return(false) }
|
|
28
28
|
|
|
29
|
-
it "does not instrument
|
|
30
|
-
expect { make_request
|
|
29
|
+
it "does not instrument the request" do
|
|
30
|
+
expect { make_request }.to_not(change { created_transactions.count })
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it "calls the next middleware in the stack" do
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
make_request
|
|
35
|
+
expect(app).to be_called
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
context "when appsignal is active" do
|
|
40
40
|
before { allow(Appsignal).to receive(:active?).and_return(true) }
|
|
41
41
|
|
|
42
|
-
it "
|
|
43
|
-
make_request(
|
|
42
|
+
it "creates a transaction for the request" do
|
|
43
|
+
expect { make_request }.to(change { created_transactions.count }.by(1))
|
|
44
44
|
|
|
45
|
-
expect(
|
|
45
|
+
expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
context "without an
|
|
49
|
-
|
|
50
|
-
expect { make_request(env) }.to(change { created_transactions.count }.by(1))
|
|
48
|
+
context "without an error" do
|
|
49
|
+
before { make_request }
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"action" => nil,
|
|
55
|
-
"error" => nil
|
|
56
|
-
)
|
|
51
|
+
it "calls the next middleware in the stack" do
|
|
52
|
+
expect(app).to be_called
|
|
57
53
|
end
|
|
58
54
|
|
|
59
|
-
it "
|
|
60
|
-
|
|
55
|
+
it "does not record an error" do
|
|
56
|
+
expect(last_transaction).to_not have_error
|
|
57
|
+
end
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
hash_including(
|
|
65
|
-
"body" => "",
|
|
66
|
-
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
|
67
|
-
"count" => 1,
|
|
68
|
-
"name" => "process.abstract",
|
|
69
|
-
"title" => ""
|
|
70
|
-
)
|
|
71
|
-
]
|
|
72
|
-
)
|
|
59
|
+
it "records an instrumentation event" do
|
|
60
|
+
expect(last_transaction).to include_event(:name => "process.abstract")
|
|
73
61
|
end
|
|
74
62
|
|
|
75
63
|
it "completes the transaction" do
|
|
76
|
-
make_request(env)
|
|
77
64
|
expect(last_transaction).to be_completed
|
|
65
|
+
expect(Appsignal::Transaction.current)
|
|
66
|
+
.to be_kind_of(Appsignal::Transaction::NilTransaction)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context "when instrument_span_name option is nil" do
|
|
70
|
+
let(:options) { { :instrument_span_name => nil } }
|
|
71
|
+
|
|
72
|
+
it "does not record an instrumentation event" do
|
|
73
|
+
expect(last_transaction).to_not include_events
|
|
74
|
+
end
|
|
78
75
|
end
|
|
79
76
|
end
|
|
80
77
|
|
|
81
|
-
context "with an
|
|
78
|
+
context "with an error" do
|
|
82
79
|
let(:error) { ExampleException.new("error message") }
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
80
|
+
let(:app) { lambda { |_env| raise ExampleException, "error message" } }
|
|
81
|
+
|
|
82
|
+
it "create a transaction for the request" do
|
|
83
|
+
expect { make_request_with_error(ExampleException, "error message") }
|
|
86
84
|
.to(change { created_transactions.count }.by(1))
|
|
87
|
-
end
|
|
88
85
|
|
|
89
|
-
|
|
90
|
-
expect(last_transaction.to_h).to include(
|
|
91
|
-
"error" => hash_including(
|
|
92
|
-
"name" => "ExampleException",
|
|
93
|
-
"message" => "error message"
|
|
94
|
-
)
|
|
95
|
-
)
|
|
86
|
+
expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
96
87
|
end
|
|
97
88
|
|
|
98
|
-
|
|
99
|
-
|
|
89
|
+
describe "error" do
|
|
90
|
+
before do
|
|
91
|
+
make_request_with_error(ExampleException, "error message")
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "records the error" do
|
|
95
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "completes the transaction" do
|
|
99
|
+
expect(last_transaction).to be_completed
|
|
100
|
+
expect(Appsignal::Transaction.current)
|
|
101
|
+
.to be_kind_of(Appsignal::Transaction::NilTransaction)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
context "with :report_errors set to false" do
|
|
105
|
+
let(:app) { lambda { |_env| raise ExampleException, "error message" } }
|
|
106
|
+
let(:options) { { :report_errors => false } }
|
|
107
|
+
|
|
108
|
+
it "does not record the exception on the transaction" do
|
|
109
|
+
expect(last_transaction).to_not have_error
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context "with :report_errors set to true" do
|
|
114
|
+
let(:app) { lambda { |_env| raise ExampleException, "error message" } }
|
|
115
|
+
let(:options) { { :report_errors => true } }
|
|
116
|
+
|
|
117
|
+
it "records the exception on the transaction" do
|
|
118
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
context "with :report_errors set to a lambda that returns false" do
|
|
123
|
+
let(:app) { lambda { |_env| raise ExampleException, "error message" } }
|
|
124
|
+
let(:options) { { :report_errors => lambda { |_env| false } } }
|
|
125
|
+
|
|
126
|
+
it "does not record the exception on the transaction" do
|
|
127
|
+
expect(last_transaction).to_not have_error
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context "with :report_errors set to a lambda that returns true" do
|
|
132
|
+
let(:app) { lambda { |_env| raise ExampleException, "error message" } }
|
|
133
|
+
let(:options) { { :report_errors => lambda { |_env| true } } }
|
|
134
|
+
|
|
135
|
+
it "records the exception on the transaction" do
|
|
136
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
|
137
|
+
end
|
|
138
|
+
end
|
|
100
139
|
end
|
|
101
140
|
end
|
|
102
141
|
|
|
103
142
|
context "without action name metadata" do
|
|
104
143
|
it "reports no action name" do
|
|
105
|
-
make_request
|
|
144
|
+
make_request
|
|
106
145
|
|
|
107
|
-
expect(last_transaction
|
|
146
|
+
expect(last_transaction).to_not have_action
|
|
108
147
|
end
|
|
109
148
|
end
|
|
110
149
|
|
|
111
150
|
context "with appsignal.route env" do
|
|
112
|
-
before do
|
|
113
|
-
env["appsignal.route"] = "POST /my-route"
|
|
114
|
-
end
|
|
115
|
-
|
|
116
151
|
it "reports the appsignal.route value as the action name" do
|
|
117
|
-
|
|
152
|
+
env["appsignal.route"] = "POST /my-route"
|
|
153
|
+
make_request
|
|
118
154
|
|
|
119
|
-
expect(last_transaction
|
|
155
|
+
expect(last_transaction).to have_action("POST /my-route")
|
|
120
156
|
end
|
|
121
157
|
end
|
|
122
158
|
|
|
123
159
|
context "with appsignal.action env" do
|
|
124
|
-
before do
|
|
125
|
-
env["appsignal.action"] = "POST /my-action"
|
|
126
|
-
end
|
|
127
|
-
|
|
128
160
|
it "reports the appsignal.route value as the action name" do
|
|
129
|
-
|
|
161
|
+
env["appsignal.action"] = "POST /my-action"
|
|
162
|
+
make_request
|
|
130
163
|
|
|
131
|
-
expect(last_transaction
|
|
164
|
+
expect(last_transaction).to have_action("POST /my-action")
|
|
132
165
|
end
|
|
133
166
|
end
|
|
134
167
|
|
|
135
168
|
describe "request metadata" do
|
|
136
|
-
before do
|
|
137
|
-
env.merge("PATH_INFO" => "/some/path", "REQUEST_METHOD" => "GET")
|
|
138
|
-
end
|
|
139
|
-
|
|
140
169
|
it "sets request metadata" do
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
# and more, but we don't need to test Rack mock defaults
|
|
153
|
-
)
|
|
154
|
-
)
|
|
170
|
+
env.merge!("PATH_INFO" => "/some/path", "REQUEST_METHOD" => "GET")
|
|
171
|
+
make_request
|
|
172
|
+
|
|
173
|
+
expect(last_transaction).to include_metadata(
|
|
174
|
+
"method" => "GET",
|
|
175
|
+
"path" => "/some/path"
|
|
176
|
+
)
|
|
177
|
+
expect(last_transaction).to include_environment(
|
|
178
|
+
"REQUEST_METHOD" => "GET",
|
|
179
|
+
"PATH_INFO" => "/some/path"
|
|
180
|
+
# and more, but we don't need to test Rack mock defaults
|
|
155
181
|
)
|
|
156
182
|
end
|
|
157
183
|
|
|
184
|
+
context "with an invalid HTTP request method" do
|
|
185
|
+
it "stores the invalid HTTP request method" do
|
|
186
|
+
env["REQUEST_METHOD"] = "FOO"
|
|
187
|
+
make_request
|
|
188
|
+
|
|
189
|
+
expect(last_transaction).to include_metadata("method" => "FOO")
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
context "with fetching the request method raises an error" do
|
|
194
|
+
class BrokenRequestMethodRequest < Rack::Request
|
|
195
|
+
def request_method
|
|
196
|
+
raise "uh oh!"
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
let(:options) { { :request_class => BrokenRequestMethodRequest } }
|
|
201
|
+
it "does not store the invalid HTTP request method" do
|
|
202
|
+
env["REQUEST_METHOD"] = "FOO"
|
|
203
|
+
make_request
|
|
204
|
+
|
|
205
|
+
expect(last_transaction).to_not include_metadata("method" => anything)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
158
209
|
it "sets request parameters" do
|
|
159
|
-
make_request
|
|
160
|
-
|
|
161
|
-
expect(last_transaction
|
|
162
|
-
"
|
|
163
|
-
|
|
164
|
-
"page" => "2",
|
|
165
|
-
"query" => "lorem"
|
|
166
|
-
)
|
|
167
|
-
)
|
|
210
|
+
make_request
|
|
211
|
+
|
|
212
|
+
expect(last_transaction).to include_params(
|
|
213
|
+
"page" => "2",
|
|
214
|
+
"query" => "lorem"
|
|
168
215
|
)
|
|
169
216
|
end
|
|
217
|
+
|
|
218
|
+
context "when setting custom params" do
|
|
219
|
+
let(:app) do
|
|
220
|
+
DummyApp.new do |_env|
|
|
221
|
+
Appsignal::Transaction.current.set_params("custom" => "param")
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
it "allow custom request parameters to be set" do
|
|
226
|
+
make_request
|
|
227
|
+
|
|
228
|
+
expect(last_transaction).to include_params("custom" => "param")
|
|
229
|
+
end
|
|
230
|
+
end
|
|
170
231
|
end
|
|
171
232
|
|
|
172
233
|
context "with queue start header" do
|
|
173
234
|
let(:queue_start_time) { fixed_time * 1_000 }
|
|
174
|
-
before do
|
|
175
|
-
env["HTTP_X_REQUEST_START"] = "t=#{queue_start_time.to_i}" # in milliseconds
|
|
176
|
-
end
|
|
177
235
|
|
|
178
236
|
it "sets the queue start" do
|
|
179
|
-
|
|
237
|
+
env["HTTP_X_REQUEST_START"] = "t=#{queue_start_time.to_i}" # in milliseconds
|
|
238
|
+
make_request
|
|
180
239
|
|
|
181
|
-
expect(last_transaction
|
|
240
|
+
expect(last_transaction).to have_queue_start(queue_start_time)
|
|
182
241
|
end
|
|
183
242
|
end
|
|
184
243
|
|
|
@@ -208,13 +267,9 @@ describe Appsignal::Rack::AbstractMiddleware do
|
|
|
208
267
|
end
|
|
209
268
|
|
|
210
269
|
it "uses the overridden request class and params method to fetch params" do
|
|
211
|
-
make_request
|
|
270
|
+
make_request
|
|
212
271
|
|
|
213
|
-
expect(last_transaction
|
|
214
|
-
"sample_data" => hash_including(
|
|
215
|
-
"params" => { "abc" => "123" }
|
|
216
|
-
)
|
|
217
|
-
)
|
|
272
|
+
expect(last_transaction).to include_params("abc" => "123")
|
|
218
273
|
end
|
|
219
274
|
end
|
|
220
275
|
|
|
@@ -224,13 +279,23 @@ describe Appsignal::Rack::AbstractMiddleware do
|
|
|
224
279
|
end
|
|
225
280
|
|
|
226
281
|
it "uses the existing transaction" do
|
|
227
|
-
make_request
|
|
282
|
+
make_request
|
|
228
283
|
|
|
229
|
-
expect { make_request
|
|
284
|
+
expect { make_request }.to_not(change { created_transactions.count })
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
context "with error" do
|
|
288
|
+
let(:app) { lambda { |_env| raise ExampleException, "error message" } }
|
|
289
|
+
|
|
290
|
+
it "doesn't record the error on the transaction" do
|
|
291
|
+
make_request_with_error(ExampleException, "error message")
|
|
292
|
+
|
|
293
|
+
expect(last_transaction).to_not have_error
|
|
294
|
+
end
|
|
230
295
|
end
|
|
231
296
|
|
|
232
297
|
it "doesn't complete the existing transaction" do
|
|
233
|
-
make_request
|
|
298
|
+
make_request
|
|
234
299
|
|
|
235
300
|
expect(env[Appsignal::Rack::APPSIGNAL_TRANSACTION]).to_not be_completed
|
|
236
301
|
end
|
|
@@ -239,9 +304,53 @@ describe Appsignal::Rack::AbstractMiddleware do
|
|
|
239
304
|
it "does not overwrite the action name" do
|
|
240
305
|
env[Appsignal::Rack::APPSIGNAL_TRANSACTION].set_action("My custom action")
|
|
241
306
|
env["appsignal.action"] = "POST /my-action"
|
|
242
|
-
make_request
|
|
307
|
+
make_request
|
|
308
|
+
|
|
309
|
+
expect(last_transaction).to have_action("My custom action")
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
context "with :report_errors set to false" do
|
|
314
|
+
let(:app) { lambda { |_env| raise ExampleException, "error message" } }
|
|
315
|
+
let(:options) { { :report_errors => false } }
|
|
316
|
+
|
|
317
|
+
it "does not record the error on the transaction" do
|
|
318
|
+
make_request_with_error(ExampleException, "error message")
|
|
319
|
+
|
|
320
|
+
expect(last_transaction).to_not have_error
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
context "with :report_errors set to true" do
|
|
325
|
+
let(:app) { lambda { |_env| raise ExampleException, "error message" } }
|
|
326
|
+
let(:options) { { :report_errors => true } }
|
|
327
|
+
|
|
328
|
+
it "records the error on the transaction" do
|
|
329
|
+
make_request_with_error(ExampleException, "error message")
|
|
330
|
+
|
|
331
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
context "with :report_errors set to a lambda that returns false" do
|
|
336
|
+
let(:app) { lambda { |_env| raise ExampleException, "error message" } }
|
|
337
|
+
let(:options) { { :report_errors => lambda { |_env| false } } }
|
|
338
|
+
|
|
339
|
+
it "does not record the exception on the transaction" do
|
|
340
|
+
make_request_with_error(ExampleException, "error message")
|
|
341
|
+
|
|
342
|
+
expect(last_transaction).to_not have_error
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
context "with :report_errors set to a lambda that returns true" do
|
|
347
|
+
let(:app) { lambda { |_env| raise ExampleException, "error message" } }
|
|
348
|
+
let(:options) { { :report_errors => lambda { |_env| true } } }
|
|
349
|
+
|
|
350
|
+
it "records the error on the transaction" do
|
|
351
|
+
make_request_with_error(ExampleException, "error message")
|
|
243
352
|
|
|
244
|
-
expect(last_transaction
|
|
353
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
|
245
354
|
end
|
|
246
355
|
end
|
|
247
356
|
end
|