appsignal 3.4.0-java → 3.4.2-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/.rubocop.yml +63 -21
- data/.rubocop_todo.yml +68 -54
- data/.semaphore/semaphore.yml +11 -11
- data/CHANGELOG.md +51 -0
- data/Rakefile +15 -99
- data/appsignal.gemspec +3 -4
- data/bin/appsignal +4 -2
- data/build_matrix.yml +4 -4
- data/ext/._appsignal-agent +0 -0
- data/ext/Rakefile +22 -21
- data/ext/agent.rb +29 -27
- data/ext/base.rb +14 -17
- data/ext/extconf.rb +4 -1
- data/lib/appsignal/auth_check.rb +3 -3
- data/lib/appsignal/capistrano.rb +1 -1
- data/lib/appsignal/cli/demo.rb +5 -2
- data/lib/appsignal/cli/diagnose/paths.rb +4 -1
- data/lib/appsignal/cli/diagnose/utils.rb +7 -3
- data/lib/appsignal/cli/diagnose.rb +7 -5
- data/lib/appsignal/cli/helpers.rb +1 -4
- data/lib/appsignal/cli/install.rb +4 -10
- data/lib/appsignal/cli.rb +3 -2
- data/lib/appsignal/config.rb +106 -103
- data/lib/appsignal/demo.rb +2 -1
- data/lib/appsignal/environment.rb +2 -0
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +2 -1
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +13 -13
- data/lib/appsignal/event_formatter.rb +5 -4
- data/lib/appsignal/extension/jruby.rb +11 -9
- data/lib/appsignal/extension.rb +1 -1
- data/lib/appsignal/helpers/instrumentation.rb +50 -35
- data/lib/appsignal/hooks/action_cable.rb +6 -4
- data/lib/appsignal/hooks/action_mailer.rb +2 -0
- data/lib/appsignal/hooks/active_job.rb +11 -10
- data/lib/appsignal/hooks/active_support_notifications.rb +3 -4
- data/lib/appsignal/hooks/data_mapper.rb +1 -1
- data/lib/appsignal/hooks/gvl.rb +3 -0
- data/lib/appsignal/hooks/http.rb +1 -1
- data/lib/appsignal/hooks/mri.rb +2 -0
- data/lib/appsignal/hooks/net_http.rb +1 -1
- data/lib/appsignal/hooks/que.rb +1 -1
- data/lib/appsignal/hooks/rake.rb +1 -1
- data/lib/appsignal/hooks/redis.rb +1 -1
- data/lib/appsignal/hooks/resque.rb +1 -1
- data/lib/appsignal/hooks/shoryuken.rb +2 -4
- data/lib/appsignal/hooks/sidekiq.rb +1 -1
- data/lib/appsignal/hooks/unicorn.rb +2 -2
- data/lib/appsignal/hooks/webmachine.rb +1 -1
- data/lib/appsignal/hooks.rb +2 -2
- data/lib/appsignal/integrations/active_support_notifications.rb +1 -1
- data/lib/appsignal/integrations/capistrano/appsignal.cap +6 -3
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +5 -4
- data/lib/appsignal/integrations/delayed_job_plugin.rb +3 -5
- data/lib/appsignal/integrations/grape.rb +1 -1
- data/lib/appsignal/integrations/hanami.rb +1 -1
- data/lib/appsignal/integrations/object.rb +2 -3
- data/lib/appsignal/integrations/padrino.rb +2 -4
- data/lib/appsignal/integrations/que.rb +6 -6
- data/lib/appsignal/integrations/railtie.rb +76 -0
- data/lib/appsignal/integrations/sidekiq.rb +9 -11
- data/lib/appsignal/integrations/sinatra.rb +1 -3
- data/lib/appsignal/integrations/webmachine.rb +4 -6
- data/lib/appsignal/logger.rb +31 -6
- data/lib/appsignal/marker.rb +4 -5
- data/lib/appsignal/minutely.rb +7 -7
- data/lib/appsignal/probes/gvl.rb +9 -4
- data/lib/appsignal/probes/helpers.rb +4 -6
- data/lib/appsignal/probes/mri.rb +7 -5
- data/lib/appsignal/probes/sidekiq.rb +3 -0
- data/lib/appsignal/probes.rb +2 -0
- data/lib/appsignal/rack/generic_instrumentation.rb +1 -5
- data/lib/appsignal/rack/sinatra_instrumentation.rb +3 -5
- data/lib/appsignal/rack/streaming_listener.rb +11 -13
- data/lib/appsignal/span.rb +5 -5
- data/lib/appsignal/system.rb +10 -11
- data/lib/appsignal/transaction.rb +49 -25
- data/lib/appsignal/transmitter.rb +4 -2
- data/lib/appsignal/utils/deprecation_message.rb +2 -0
- data/lib/appsignal/utils/hash_sanitizer.rb +1 -1
- data/lib/appsignal/utils/integration_logger.rb +5 -3
- data/lib/appsignal/utils/json.rb +1 -1
- data/lib/appsignal/utils/query_params_sanitizer.rb +1 -1
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +5 -4
- data/lib/puma/plugin/appsignal.rb +16 -18
- data/script/lint_git +1 -1
- data/spec/lib/appsignal/capistrano2_spec.rb +6 -3
- data/spec/lib/appsignal/capistrano3_spec.rb +6 -3
- data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +1 -3
- data/spec/lib/appsignal/cli/diagnose_spec.rb +33 -30
- data/spec/lib/appsignal/cli/install_spec.rb +5 -6
- data/spec/lib/appsignal/cli_spec.rb +1 -1
- data/spec/lib/appsignal/config_spec.rb +43 -37
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +11 -5
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +4 -4
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +1 -4
- data/spec/lib/appsignal/event_formatter_spec.rb +11 -9
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +5 -2
- data/spec/lib/appsignal/hooks/action_mailer_spec.rb +2 -1
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +1 -1
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +1 -1
- data/spec/lib/appsignal/hooks/activejob_spec.rb +21 -12
- data/spec/lib/appsignal/hooks/data_mapper_spec.rb +1 -0
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +12 -12
- data/spec/lib/appsignal/hooks/excon_spec.rb +2 -2
- data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +3 -1
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +4 -2
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +2 -1
- data/spec/lib/appsignal/hooks_spec.rb +5 -4
- data/spec/lib/appsignal/integrations/grape_spec.rb +8 -4
- data/spec/lib/appsignal/integrations/hanami_spec.rb +16 -8
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +2 -4
- data/spec/lib/appsignal/integrations/object_spec.rb +6 -1
- data/spec/lib/appsignal/integrations/padrino_spec.rb +4 -2
- data/spec/lib/appsignal/integrations/railtie_spec.rb +213 -6
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +54 -41
- data/spec/lib/appsignal/logger_spec.rb +20 -4
- data/spec/lib/appsignal/marker_spec.rb +2 -2
- data/spec/lib/appsignal/minutely_spec.rb +3 -3
- data/spec/lib/appsignal/probes/gvl_spec.rb +60 -12
- data/spec/lib/appsignal/probes/mri_spec.rb +7 -4
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +2 -1
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +2 -1
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +10 -5
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +7 -5
- data/spec/lib/appsignal/transaction_spec.rb +20 -13
- data/spec/lib/appsignal/utils/data_spec.rb +10 -1
- data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +11 -11
- data/spec/lib/appsignal/utils/json_spec.rb +4 -2
- data/spec/lib/appsignal_spec.rb +49 -35
- data/spec/lib/puma/appsignal_spec.rb +9 -11
- data/spec/spec_helper.rb +14 -2
- data/spec/support/fixtures/projects/valid/config/appsignal.yml +1 -1
- data/spec/support/helpers/config_helpers.rb +2 -1
- data/spec/support/helpers/dependency_helper.rb +1 -9
- data/spec/support/helpers/std_streams_helper.rb +1 -3
- data/spec/support/helpers/wait_for_helper.rb +2 -3
- data/spec/support/mocks/appsignal_mock.rb +1 -1
- data/spec/support/mocks/fake_gvl_tools.rb +2 -10
- data/spec/support/testing.rb +4 -3
- metadata +9 -135
|
@@ -153,7 +153,8 @@ if DependencyHelper.grape_present?
|
|
|
153
153
|
end
|
|
154
154
|
|
|
155
155
|
it "sets non-unique route_param path" do
|
|
156
|
-
expect(transaction).to receive(:set_action_if_nil)
|
|
156
|
+
expect(transaction).to receive(:set_action_if_nil)
|
|
157
|
+
.with("GET::GrapeExample::Api#/users/:id/")
|
|
157
158
|
expect(transaction).to receive(:set_metadata).with("path", "/users/:id/")
|
|
158
159
|
expect(transaction).to receive(:set_metadata).with("method", "GET")
|
|
159
160
|
end
|
|
@@ -177,7 +178,8 @@ if DependencyHelper.grape_present?
|
|
|
177
178
|
end
|
|
178
179
|
|
|
179
180
|
it "sets namespaced path" do
|
|
180
|
-
expect(transaction).to receive(:set_action_if_nil)
|
|
181
|
+
expect(transaction).to receive(:set_action_if_nil)
|
|
182
|
+
.with("POST::GrapeExample::Api#/v1/beta/ping")
|
|
181
183
|
expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
|
|
182
184
|
expect(transaction).to receive(:set_metadata).with("method", "POST")
|
|
183
185
|
end
|
|
@@ -199,7 +201,8 @@ if DependencyHelper.grape_present?
|
|
|
199
201
|
end
|
|
200
202
|
|
|
201
203
|
it "sets namespaced path" do
|
|
202
|
-
expect(transaction).to receive(:set_action_if_nil)
|
|
204
|
+
expect(transaction).to receive(:set_action_if_nil)
|
|
205
|
+
.with("POST::GrapeExample::Api#/v1/beta/ping")
|
|
203
206
|
expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
|
|
204
207
|
expect(transaction).to receive(:set_metadata).with("method", "POST")
|
|
205
208
|
end
|
|
@@ -220,7 +223,8 @@ if DependencyHelper.grape_present?
|
|
|
220
223
|
end
|
|
221
224
|
|
|
222
225
|
it "sets namespaced path" do
|
|
223
|
-
expect(transaction).to receive(:set_action_if_nil)
|
|
226
|
+
expect(transaction).to receive(:set_action_if_nil)
|
|
227
|
+
.with("POST::GrapeExample::Api#/v1/beta/ping")
|
|
224
228
|
expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
|
|
225
229
|
expect(transaction).to receive(:set_metadata).with("method", "POST")
|
|
226
230
|
end
|
|
@@ -20,14 +20,16 @@ if DependencyHelper.hanami2_present?
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
it "prepends the integration to Hanami" do
|
|
23
|
-
expect(::Hanami::Action).to receive(:
|
|
23
|
+
expect(::Hanami::Action).to receive(:prepend)
|
|
24
|
+
.with(Appsignal::Integrations::HanamiIntegration)
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
context "when not active" do
|
|
27
28
|
before { allow(Appsignal).to receive(:active?).and_return(false) }
|
|
28
29
|
|
|
29
30
|
it "does not prepend the integration" do
|
|
30
|
-
expect(::Hanami::Action).to_not receive(:
|
|
31
|
+
expect(::Hanami::Action).to_not receive(:prepend)
|
|
32
|
+
.with(Appsignal::Integrations::HanamiIntegration)
|
|
31
33
|
end
|
|
32
34
|
end
|
|
33
35
|
|
|
@@ -71,17 +73,22 @@ if DependencyHelper.hanami2_present?
|
|
|
71
73
|
end
|
|
72
74
|
|
|
73
75
|
it "sets the action name" do
|
|
74
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:set_action_if_nil)
|
|
76
|
+
expect_any_instance_of(Appsignal::Transaction).to receive(:set_action_if_nil)
|
|
77
|
+
.with("HanamiApp::Actions::Books::Index")
|
|
75
78
|
end
|
|
76
79
|
|
|
77
80
|
it "sets the metadata" do
|
|
78
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
|
|
79
|
-
|
|
80
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
|
|
81
|
+
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
|
|
82
|
+
.with("status", "200")
|
|
83
|
+
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
|
|
84
|
+
.with("path", "/books")
|
|
85
|
+
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
|
|
86
|
+
.with("method", "GET")
|
|
81
87
|
end
|
|
82
88
|
|
|
83
89
|
it "sets the queue start" do
|
|
84
|
-
expect_any_instance_of(Appsignal::Transaction)
|
|
90
|
+
expect_any_instance_of(Appsignal::Transaction)
|
|
91
|
+
.to receive(:set_http_or_background_queue_start)
|
|
85
92
|
end
|
|
86
93
|
|
|
87
94
|
context "with error", :error => true do
|
|
@@ -92,7 +99,8 @@ if DependencyHelper.hanami2_present?
|
|
|
92
99
|
end
|
|
93
100
|
|
|
94
101
|
it "sets the status to 500" do
|
|
95
|
-
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
|
|
102
|
+
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata)
|
|
103
|
+
.with("status", "500")
|
|
96
104
|
expect_any_instance_of(Appsignal::Transaction).to receive(:set_metadata).twice
|
|
97
105
|
end
|
|
98
106
|
end
|
|
@@ -19,11 +19,8 @@ describe Appsignal::Hooks::MongoMonitorSubscriber do
|
|
|
19
19
|
it "should sanitize command" do
|
|
20
20
|
# TODO: additional curly brackets required for issue
|
|
21
21
|
# https://github.com/rspec/rspec-mocks/issues/1460
|
|
22
|
-
# rubocop:disable Style/BracesAroundHashParameters
|
|
23
22
|
expect(Appsignal::EventFormatter::MongoRubyDriver::QueryFormatter)
|
|
24
23
|
.to receive(:format).with("find", { "foo" => "bar" })
|
|
25
|
-
# rubocop:enable Style/BracesAroundHashParameters
|
|
26
|
-
|
|
27
24
|
subscriber.started(event)
|
|
28
25
|
end
|
|
29
26
|
|
|
@@ -107,7 +104,8 @@ describe Appsignal::Hooks::MongoMonitorSubscriber do
|
|
|
107
104
|
|
|
108
105
|
context "without transaction" do
|
|
109
106
|
before do
|
|
110
|
-
allow(Appsignal::Transaction).to receive(:current)
|
|
107
|
+
allow(Appsignal::Transaction).to receive(:current)
|
|
108
|
+
.and_return(Appsignal::Transaction::NilTransaction.new)
|
|
111
109
|
end
|
|
112
110
|
|
|
113
111
|
it "should not attempt to start an event" do
|
|
@@ -25,7 +25,8 @@ describe Object do
|
|
|
25
25
|
let(:transaction) { http_request_transaction }
|
|
26
26
|
before do
|
|
27
27
|
Appsignal.config = project_fixture_config
|
|
28
|
-
expect(Appsignal::Transaction).to receive(:current)
|
|
28
|
+
expect(Appsignal::Transaction).to receive(:current)
|
|
29
|
+
.at_least(:once).and_return(transaction)
|
|
29
30
|
expect(Appsignal.active?).to be_truthy
|
|
30
31
|
end
|
|
31
32
|
after { Appsignal.config = nil }
|
|
@@ -43,9 +44,11 @@ describe Object do
|
|
|
43
44
|
end
|
|
44
45
|
appsignal_instrument_method :positional_arguments_splat
|
|
45
46
|
|
|
47
|
+
# rubocop:disable Naming/MethodParameterName
|
|
46
48
|
def keyword_arguments(a: nil, b: nil)
|
|
47
49
|
[a, b]
|
|
48
50
|
end
|
|
51
|
+
# rubocop:enable Naming/MethodParameterName
|
|
49
52
|
appsignal_instrument_method :keyword_arguments
|
|
50
53
|
|
|
51
54
|
def keyword_arguments_splat(**kwargs)
|
|
@@ -213,9 +216,11 @@ describe Object do
|
|
|
213
216
|
end
|
|
214
217
|
appsignal_instrument_class_method :positional_arguments_splat
|
|
215
218
|
|
|
219
|
+
# rubocop:disable Naming/MethodParameterName
|
|
216
220
|
def self.keyword_arguments(a: nil, b: nil)
|
|
217
221
|
[a, b]
|
|
218
222
|
end
|
|
223
|
+
# rubocop:enable Naming/MethodParameterName
|
|
219
224
|
appsignal_instrument_class_method :keyword_arguments
|
|
220
225
|
|
|
221
226
|
def self.keyword_arguments_splat(**kwargs)
|
|
@@ -283,7 +283,8 @@ if DependencyHelper.padrino_present?
|
|
|
283
283
|
|
|
284
284
|
it "sets the action with the app name, controller name and action name" do
|
|
285
285
|
expect_a_transaction_to_be_created
|
|
286
|
-
expect(transaction).to receive(:set_action_if_nil)
|
|
286
|
+
expect(transaction).to receive(:set_action_if_nil)
|
|
287
|
+
.with("PadrinoTestApp:my_controller#index")
|
|
287
288
|
end
|
|
288
289
|
end
|
|
289
290
|
|
|
@@ -295,7 +296,8 @@ if DependencyHelper.padrino_present?
|
|
|
295
296
|
|
|
296
297
|
it "sets the action with the app name, controller name and action path" do
|
|
297
298
|
expect_a_transaction_to_be_created
|
|
298
|
-
expect(transaction).to receive(:set_action_if_nil)
|
|
299
|
+
expect(transaction).to receive(:set_action_if_nil)
|
|
300
|
+
.with("PadrinoTestApp:/my_controller#index")
|
|
299
301
|
end
|
|
300
302
|
end
|
|
301
303
|
end
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
if DependencyHelper.rails_present?
|
|
2
|
+
require "action_mailer"
|
|
3
|
+
|
|
2
4
|
describe Appsignal::Integrations::Railtie do
|
|
3
5
|
context "after initializing the app" do
|
|
4
6
|
it "should call initialize_appsignal" do
|
|
@@ -10,11 +12,7 @@ if DependencyHelper.rails_present?
|
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
describe "#initialize_appsignal" do
|
|
13
|
-
let(:app) { MyApp::Application }
|
|
14
|
-
before do
|
|
15
|
-
allow(app.middleware).to receive(:insert_before)
|
|
16
|
-
allow(app.middleware).to receive(:insert_after)
|
|
17
|
-
end
|
|
15
|
+
let(:app) { MyApp::Application.new }
|
|
18
16
|
|
|
19
17
|
describe ".logger" do
|
|
20
18
|
before { Appsignal::Integrations::Railtie.initialize_appsignal(app) }
|
|
@@ -58,6 +56,52 @@ if DependencyHelper.rails_present?
|
|
|
58
56
|
expect(config.env).to eq "env_test"
|
|
59
57
|
end
|
|
60
58
|
end
|
|
59
|
+
|
|
60
|
+
if Rails.respond_to?(:error)
|
|
61
|
+
context "when Rails listens to `error`" do
|
|
62
|
+
class ErrorReporterMock
|
|
63
|
+
attr_reader :subscribers
|
|
64
|
+
|
|
65
|
+
def initialize
|
|
66
|
+
@subscribers = []
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def subscribe(subscriber)
|
|
70
|
+
@subscribers << subscriber
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
let(:error_reporter) { ErrorReporterMock.new }
|
|
75
|
+
before do
|
|
76
|
+
allow(Rails).to receive(:error).and_return(error_reporter)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context "when enable_rails_error_reporter is enabled" do
|
|
80
|
+
it "subscribes to the error reporter" do
|
|
81
|
+
Appsignal::Integrations::Railtie.initialize_appsignal(app)
|
|
82
|
+
|
|
83
|
+
expect(error_reporter.subscribers)
|
|
84
|
+
.to eq([Appsignal::Integrations::RailsErrorReporterSubscriber])
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context "when enable_rails_error_reporter is disabled" do
|
|
89
|
+
it "does not subscribe to the error reporter" do
|
|
90
|
+
ENV["APPSIGNAL_ENABLE_RAILS_ERROR_REPORTER"] = "false"
|
|
91
|
+
Appsignal::Integrations::Railtie.initialize_appsignal(app)
|
|
92
|
+
|
|
93
|
+
expect(error_reporter.subscribers)
|
|
94
|
+
.to_not eq([Appsignal::Integrations::RailsErrorReporterSubscriber])
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
else
|
|
99
|
+
context "when Rails does not listen to `error`" do
|
|
100
|
+
it "does not error trying to subscribe to the error reporter" do
|
|
101
|
+
Appsignal::Integrations::Railtie.initialize_appsignal(app)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
61
105
|
end
|
|
62
106
|
|
|
63
107
|
describe ".initial_config" do
|
|
@@ -75,9 +119,172 @@ if DependencyHelper.rails_present?
|
|
|
75
119
|
ActionDispatch::DebugExceptions,
|
|
76
120
|
Appsignal::Rack::RailsInstrumentation
|
|
77
121
|
)
|
|
122
|
+
Appsignal::Integrations::Railtie.initialize_appsignal(app)
|
|
78
123
|
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
if Rails.respond_to?(:error)
|
|
127
|
+
describe "Rails error reporter" do
|
|
128
|
+
before do
|
|
129
|
+
Appsignal::Integrations::Railtie.initialize_appsignal(app)
|
|
130
|
+
start_agent
|
|
131
|
+
end
|
|
132
|
+
around { |example| keep_transactions { example.run } }
|
|
133
|
+
|
|
134
|
+
context "when error is not handled (reraises the error)" do
|
|
135
|
+
it "does nothing" do
|
|
136
|
+
expect do
|
|
137
|
+
Rails.error.record { raise ExampleStandardError }
|
|
138
|
+
end.to raise_error(ExampleStandardError)
|
|
139
|
+
|
|
140
|
+
expect(created_transactions).to be_empty
|
|
141
|
+
end
|
|
142
|
+
end
|
|
79
143
|
|
|
80
|
-
|
|
144
|
+
context "when error is handled (not reraised)" do
|
|
145
|
+
context "when a transaction is active" do
|
|
146
|
+
it "duplicates the transaction namespace, action and tags" do
|
|
147
|
+
current_transaction = http_request_transaction
|
|
148
|
+
current_transaction.set_namespace "custom"
|
|
149
|
+
current_transaction.set_action "CustomAction"
|
|
150
|
+
current_transaction.set_tags(
|
|
151
|
+
:duplicated_tag => "duplicated value"
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
with_current_transaction current_transaction do
|
|
155
|
+
Rails.error.handle { raise ExampleStandardError }
|
|
156
|
+
|
|
157
|
+
transaction = last_transaction
|
|
158
|
+
transaction_hash = transaction.to_h
|
|
159
|
+
expect(transaction_hash).to include(
|
|
160
|
+
"action" => "CustomAction",
|
|
161
|
+
"namespace" => "custom",
|
|
162
|
+
"error" => {
|
|
163
|
+
"name" => "ExampleStandardError",
|
|
164
|
+
"message" => "ExampleStandardError",
|
|
165
|
+
"backtrace" => kind_of(String)
|
|
166
|
+
},
|
|
167
|
+
"sample_data" => hash_including(
|
|
168
|
+
"tags" => {
|
|
169
|
+
"duplicated_tag" => "duplicated value",
|
|
170
|
+
"severity" => "warning"
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "overwrites duplicated tags with tags from context" do
|
|
178
|
+
current_transaction = http_request_transaction
|
|
179
|
+
current_transaction.set_tags(:tag1 => "duplicated value")
|
|
180
|
+
|
|
181
|
+
with_current_transaction current_transaction do
|
|
182
|
+
given_context = { :tag1 => "value1", :tag2 => "value2" }
|
|
183
|
+
Rails.error.handle(:context => given_context) { raise ExampleStandardError }
|
|
184
|
+
|
|
185
|
+
transaction = last_transaction
|
|
186
|
+
transaction_hash = transaction.to_h
|
|
187
|
+
expect(transaction_hash).to include(
|
|
188
|
+
"sample_data" => hash_including(
|
|
189
|
+
"tags" => {
|
|
190
|
+
"tag1" => "value1",
|
|
191
|
+
"tag2" => "value2",
|
|
192
|
+
"severity" => "warning"
|
|
193
|
+
}
|
|
194
|
+
)
|
|
195
|
+
)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "overwrites duplicated namespace and action with custom from context" do
|
|
200
|
+
current_transaction = http_request_transaction
|
|
201
|
+
current_transaction.set_namespace "custom"
|
|
202
|
+
current_transaction.set_action "CustomAction"
|
|
203
|
+
|
|
204
|
+
with_current_transaction current_transaction do
|
|
205
|
+
given_context = {
|
|
206
|
+
:appsignal => { :namespace => "context", :action => "ContextAction" }
|
|
207
|
+
}
|
|
208
|
+
Rails.error.handle(:context => given_context) { raise ExampleStandardError }
|
|
209
|
+
|
|
210
|
+
transaction = last_transaction
|
|
211
|
+
transaction_hash = transaction.to_h
|
|
212
|
+
expect(transaction_hash).to include(
|
|
213
|
+
"namespace" => "context",
|
|
214
|
+
"action" => "ContextAction"
|
|
215
|
+
)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
context "when no transaction is active" do
|
|
221
|
+
class ExampleRailsControllerMock
|
|
222
|
+
def action_name
|
|
223
|
+
"index"
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
class ExampleRailsJobMock
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
class ExampleRailsMailerMock < ActionMailer::MailDeliveryJob
|
|
231
|
+
def arguments
|
|
232
|
+
["ExampleRailsMailerMock", "send_mail"]
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
before do
|
|
237
|
+
clear_current_transaction!
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "fetches the action from the controller in the context" do
|
|
241
|
+
# The controller key is set by Rails when raised in a controller
|
|
242
|
+
given_context = { :controller => ExampleRailsControllerMock.new }
|
|
243
|
+
Rails.error.handle(:context => given_context) { raise ExampleStandardError }
|
|
244
|
+
|
|
245
|
+
transaction = last_transaction
|
|
246
|
+
transaction_hash = transaction.to_h
|
|
247
|
+
expect(transaction_hash).to include(
|
|
248
|
+
"action" => "ExampleRailsControllerMock#index"
|
|
249
|
+
)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it "sets no action if no execution context is present" do
|
|
253
|
+
# The controller key is set by Rails when raised in a controller
|
|
254
|
+
Rails.error.handle { raise ExampleStandardError }
|
|
255
|
+
|
|
256
|
+
transaction = last_transaction
|
|
257
|
+
transaction_hash = transaction.to_h
|
|
258
|
+
expect(transaction_hash).to include(
|
|
259
|
+
"action" => nil
|
|
260
|
+
)
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it "sets the error context as tags" do
|
|
265
|
+
given_context = {
|
|
266
|
+
:controller => ExampleRailsControllerMock.new, # Not set as tag
|
|
267
|
+
:job => ExampleRailsJobMock.new, # Not set as tag
|
|
268
|
+
:appsignal => { :something => "not used" }, # Not set as tag
|
|
269
|
+
:tag1 => "value1",
|
|
270
|
+
:tag2 => "value2"
|
|
271
|
+
}
|
|
272
|
+
Rails.error.handle(:context => given_context) { raise ExampleStandardError }
|
|
273
|
+
|
|
274
|
+
transaction = last_transaction
|
|
275
|
+
transaction_hash = transaction.to_h
|
|
276
|
+
expect(transaction_hash).to include(
|
|
277
|
+
"sample_data" => hash_including(
|
|
278
|
+
"tags" => {
|
|
279
|
+
"tag1" => "value1",
|
|
280
|
+
"tag2" => "value2",
|
|
281
|
+
"severity" => "warning"
|
|
282
|
+
}
|
|
283
|
+
)
|
|
284
|
+
)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
81
288
|
end
|
|
82
289
|
end
|
|
83
290
|
end
|
|
@@ -10,11 +10,9 @@ describe Appsignal::Integrations::SidekiqErrorHandler do
|
|
|
10
10
|
|
|
11
11
|
context "without a current transction" do
|
|
12
12
|
let(:exception) do
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
error
|
|
17
|
-
end
|
|
13
|
+
raise ExampleStandardError, "uh oh"
|
|
14
|
+
rescue => error
|
|
15
|
+
error
|
|
18
16
|
end
|
|
19
17
|
let(:job_context) do
|
|
20
18
|
{
|
|
@@ -74,14 +72,14 @@ describe Appsignal::Integrations::SidekiqMiddleware, :with_yaml_parse_error => f
|
|
|
74
72
|
let(:jid) { "b4a577edbccf1d805744efa9" }
|
|
75
73
|
let(:item) do
|
|
76
74
|
{
|
|
77
|
-
"jid"
|
|
78
|
-
"class"
|
|
75
|
+
"jid" => jid,
|
|
76
|
+
"class" => job_class,
|
|
79
77
|
"retry_count" => 0,
|
|
80
|
-
"queue"
|
|
81
|
-
"created_at"
|
|
78
|
+
"queue" => "default",
|
|
79
|
+
"created_at" => Time.parse("2001-01-01 10:00:00UTC").to_f,
|
|
82
80
|
"enqueued_at" => Time.parse("2001-01-01 10:00:00UTC").to_f,
|
|
83
|
-
"args"
|
|
84
|
-
"extra"
|
|
81
|
+
"args" => given_args,
|
|
82
|
+
"extra" => "data"
|
|
85
83
|
}
|
|
86
84
|
end
|
|
87
85
|
let(:plugin) { Appsignal::Integrations::SidekiqMiddleware.new }
|
|
@@ -230,13 +228,10 @@ describe Appsignal::Integrations::SidekiqMiddleware, :with_yaml_parse_error => f
|
|
|
230
228
|
it "creates a transaction and adds the error" do
|
|
231
229
|
# TODO: additional curly brackets required for issue
|
|
232
230
|
# https://github.com/rspec/rspec-mocks/issues/1460
|
|
233
|
-
# rubocop:disable Style/BracesAroundHashParameters
|
|
234
231
|
expect(Appsignal).to receive(:increment_counter)
|
|
235
232
|
.with("sidekiq_queue_job_count", 1, { :queue => "default", :status => :failed })
|
|
236
233
|
expect(Appsignal).to receive(:increment_counter)
|
|
237
234
|
.with("sidekiq_queue_job_count", 1, { :queue => "default", :status => :processed })
|
|
238
|
-
# rubocop:enable Style/BracesAroundHashParameters
|
|
239
|
-
|
|
240
235
|
expect do
|
|
241
236
|
perform_job { raise error, "uh oh" }
|
|
242
237
|
end.to raise_error(error)
|
|
@@ -269,15 +264,40 @@ describe Appsignal::Integrations::SidekiqMiddleware, :with_yaml_parse_error => f
|
|
|
269
264
|
end
|
|
270
265
|
end
|
|
271
266
|
|
|
267
|
+
if DependencyHelper.rails7_present?
|
|
268
|
+
context "with Rails error reporter" do
|
|
269
|
+
it "reports the worker name as the action, copies the namespace and tags" do
|
|
270
|
+
Appsignal::Integrations::Railtie.initialize_appsignal(MyApp::Application.new)
|
|
271
|
+
Appsignal.config = project_fixture_config("production")
|
|
272
|
+
perform_job do
|
|
273
|
+
Appsignal.tag_job("test_tag" => "value")
|
|
274
|
+
Rails.error.handle do
|
|
275
|
+
raise error, "uh oh"
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
expect(created_transactions.count).to eq(2)
|
|
280
|
+
expected_transaction = {
|
|
281
|
+
"namespace" => "background_job",
|
|
282
|
+
"action" => "TestClass#perform",
|
|
283
|
+
"sample_data" => hash_including(
|
|
284
|
+
"tags" => hash_including("test_tag" => "value")
|
|
285
|
+
)
|
|
286
|
+
}
|
|
287
|
+
sidekiq_transaction = created_transactions.first.to_h
|
|
288
|
+
error_reporter_transaction = created_transactions.last.to_h
|
|
289
|
+
expect(sidekiq_transaction).to include(expected_transaction)
|
|
290
|
+
expect(error_reporter_transaction).to include(expected_transaction)
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
272
295
|
context "without an error" do
|
|
273
296
|
it "creates a transaction with events" do
|
|
274
297
|
# TODO: additional curly brackets required for issue
|
|
275
298
|
# https://github.com/rspec/rspec-mocks/issues/1460
|
|
276
|
-
# rubocop:disable Style/BracesAroundHashParameters
|
|
277
299
|
expect(Appsignal).to receive(:increment_counter)
|
|
278
300
|
.with("sidekiq_queue_job_count", 1, { :queue => "default", :status => :processed })
|
|
279
|
-
# rubocop:enable Style/BracesAroundHashParameters
|
|
280
|
-
|
|
281
301
|
perform_job
|
|
282
302
|
|
|
283
303
|
transaction_hash = transaction.to_h
|
|
@@ -309,18 +329,14 @@ describe Appsignal::Integrations::SidekiqMiddleware, :with_yaml_parse_error => f
|
|
|
309
329
|
|
|
310
330
|
def perform_job
|
|
311
331
|
Timecop.freeze(Time.parse("2001-01-01 10:01:00UTC")) do
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
yield if block_given?
|
|
316
|
-
end
|
|
317
|
-
rescue Exception => exception # rubocop:disable Lint/RescueException
|
|
318
|
-
raise exception
|
|
319
|
-
ensure
|
|
320
|
-
if exception
|
|
321
|
-
Appsignal::Integrations::SidekiqErrorHandler.new.call(exception, :job => item)
|
|
322
|
-
end
|
|
332
|
+
exception = nil
|
|
333
|
+
plugin.call(worker, item, queue) do
|
|
334
|
+
yield if block_given?
|
|
323
335
|
end
|
|
336
|
+
rescue Exception => exception # rubocop:disable Lint/RescueException
|
|
337
|
+
raise exception
|
|
338
|
+
ensure
|
|
339
|
+
Appsignal::Integrations::SidekiqErrorHandler.new.call(exception, :job => item) if exception
|
|
324
340
|
end
|
|
325
341
|
end
|
|
326
342
|
|
|
@@ -516,7 +532,8 @@ if DependencyHelper.active_job_present?
|
|
|
516
532
|
expect(transaction_hash).to include(
|
|
517
533
|
"action" => "ActionMailerSidekiqTestJob#welcome",
|
|
518
534
|
"sample_data" => hash_including(
|
|
519
|
-
"params" => ["ActionMailerSidekiqTestJob", "welcome",
|
|
535
|
+
"params" => ["ActionMailerSidekiqTestJob", "welcome",
|
|
536
|
+
"deliver_now"] + expected_wrapped_args
|
|
520
537
|
)
|
|
521
538
|
)
|
|
522
539
|
end
|
|
@@ -524,18 +541,14 @@ if DependencyHelper.active_job_present?
|
|
|
524
541
|
|
|
525
542
|
def perform_sidekiq
|
|
526
543
|
Timecop.freeze(time) do
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
if exception
|
|
536
|
-
Appsignal::Integrations::SidekiqErrorHandler.new.call(exception, {})
|
|
537
|
-
end
|
|
538
|
-
end
|
|
544
|
+
yield
|
|
545
|
+
# Combined with Sidekiq::Testing.fake! and drain_all we get a
|
|
546
|
+
# enqueue_at in the job data.
|
|
547
|
+
Sidekiq::Worker.drain_all
|
|
548
|
+
rescue Exception => exception # rubocop:disable Lint/RescueException
|
|
549
|
+
raise exception
|
|
550
|
+
ensure
|
|
551
|
+
Appsignal::Integrations::SidekiqErrorHandler.new.call(exception, {}) if exception
|
|
539
552
|
end
|
|
540
553
|
end
|
|
541
554
|
|
|
@@ -60,13 +60,31 @@ describe Appsignal::Logger do
|
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
it "should log with a level, message and group" do
|
|
63
|
-
expect(Appsignal::Extension).to receive(:log)
|
|
64
|
-
|
|
63
|
+
expect(Appsignal::Extension).to receive(:log).with(
|
|
64
|
+
"other_group",
|
|
65
|
+
3,
|
|
66
|
+
0,
|
|
67
|
+
"formatted: 'Log message'",
|
|
68
|
+
instance_of(Appsignal::Extension::Data)
|
|
69
|
+
)
|
|
65
70
|
logger.add(::Logger::INFO, "Log message", "other_group")
|
|
66
71
|
end
|
|
67
72
|
end
|
|
68
73
|
end
|
|
69
74
|
|
|
75
|
+
describe "#silence" do
|
|
76
|
+
it "calls the given block" do
|
|
77
|
+
num = 1
|
|
78
|
+
|
|
79
|
+
logger.silence do
|
|
80
|
+
num += 1
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
expect(num).to eq(2)
|
|
84
|
+
expect(Appsignal::Extension).not_to receive(:log)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
70
88
|
[
|
|
71
89
|
["debug", 2, ::Logger::INFO],
|
|
72
90
|
["info", 3, ::Logger::WARN],
|
|
@@ -76,11 +94,9 @@ describe Appsignal::Logger do
|
|
|
76
94
|
].each do |method|
|
|
77
95
|
describe "##{method[0]}" do
|
|
78
96
|
it "should log with a message" do
|
|
79
|
-
# rubocop:disable Style/BracesAroundHashParameters
|
|
80
97
|
expect(Appsignal::Utils::Data).to receive(:generate)
|
|
81
98
|
.with({ :attribute => "value" })
|
|
82
99
|
.and_call_original
|
|
83
|
-
# rubocop:enable Style/BracesAroundHashParameters
|
|
84
100
|
expect(Appsignal::Extension).to receive(:log)
|
|
85
101
|
.with("group", method[1], 0, "Log message", instance_of(Appsignal::Extension::Data))
|
|
86
102
|
|
|
@@ -41,8 +41,8 @@ describe Appsignal::Marker do
|
|
|
41
41
|
run
|
|
42
42
|
expect(output).to include \
|
|
43
43
|
"Notifying AppSignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman",
|
|
44
|
-
"Something went wrong while trying to notify AppSignal: 500 at "\
|
|
45
|
-
|
|
44
|
+
"Something went wrong while trying to notify AppSignal: 500 at " \
|
|
45
|
+
"#{config[:endpoint]}/1/markers"
|
|
46
46
|
expect(output).to_not include \
|
|
47
47
|
"AppSignal has been notified of this deploy!"
|
|
48
48
|
end
|
|
@@ -133,7 +133,7 @@ describe Appsignal::Minutely do
|
|
|
133
133
|
"oh no initialize!"
|
|
134
134
|
)
|
|
135
135
|
# Start of the error backtrace as debug log
|
|
136
|
-
expect(log).to contains_log :debug, File.expand_path("
|
|
136
|
+
expect(log).to contains_log :debug, File.expand_path("../../..", __dir__)
|
|
137
137
|
end
|
|
138
138
|
end
|
|
139
139
|
end
|
|
@@ -166,7 +166,7 @@ describe Appsignal::Minutely do
|
|
|
166
166
|
expect(log).to contains_log(:debug, "Gathering minutely metrics with 'my_probe' probe")
|
|
167
167
|
expect(log).to contains_log(:debug, "Gathering minutely metrics with 'broken_probe' probe")
|
|
168
168
|
expect(log).to contains_log(:error, "Error in minutely probe 'broken_probe': oh no!")
|
|
169
|
-
gem_path = File.expand_path("
|
|
169
|
+
gem_path = File.expand_path("../../..", __dir__) # Start of backtrace
|
|
170
170
|
expect(log).to contains_log(:debug, gem_path)
|
|
171
171
|
end
|
|
172
172
|
end
|
|
@@ -191,7 +191,7 @@ describe Appsignal::Minutely do
|
|
|
191
191
|
# Fetch old thread
|
|
192
192
|
thread = Appsignal::Minutely.instance_variable_get(:@thread)
|
|
193
193
|
Appsignal::Minutely.start
|
|
194
|
-
thread
|
|
194
|
+
thread&.join # Wait for old thread to exit
|
|
195
195
|
end.to_not(change { alive_thread_counter.call })
|
|
196
196
|
end
|
|
197
197
|
end
|