appsignal 2.11.8-java → 3.0.1-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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/.rubocop_todo.yml +1 -1
  4. data/.semaphore/semaphore.yml +88 -111
  5. data/CHANGELOG.md +24 -0
  6. data/appsignal.gemspec +1 -1
  7. data/build_matrix.yml +11 -15
  8. data/lib/appsignal.rb +2 -29
  9. data/lib/appsignal/auth_check.rb +2 -8
  10. data/lib/appsignal/cli.rb +1 -23
  11. data/lib/appsignal/config.rb +1 -25
  12. data/lib/appsignal/event_formatter.rb +0 -25
  13. data/lib/appsignal/helpers/instrumentation.rb +69 -5
  14. data/lib/appsignal/hooks.rb +6 -13
  15. data/lib/appsignal/hooks/action_cable.rb +3 -34
  16. data/lib/appsignal/hooks/active_support_notifications.rb +7 -86
  17. data/lib/appsignal/hooks/celluloid.rb +5 -9
  18. data/lib/appsignal/hooks/net_http.rb +2 -12
  19. data/lib/appsignal/hooks/puma.rb +3 -5
  20. data/lib/appsignal/hooks/que.rb +1 -1
  21. data/lib/appsignal/hooks/rake.rb +2 -24
  22. data/lib/appsignal/hooks/redis.rb +2 -13
  23. data/lib/appsignal/hooks/resque.rb +2 -43
  24. data/lib/appsignal/hooks/sidekiq.rb +6 -143
  25. data/lib/appsignal/hooks/unicorn.rb +3 -24
  26. data/lib/appsignal/hooks/webmachine.rb +1 -7
  27. data/lib/appsignal/integrations/action_cable.rb +34 -0
  28. data/lib/appsignal/integrations/active_support_notifications.rb +77 -0
  29. data/lib/appsignal/integrations/net_http.rb +16 -0
  30. data/lib/appsignal/integrations/object.rb +39 -4
  31. data/lib/appsignal/integrations/padrino.rb +5 -7
  32. data/lib/appsignal/integrations/que.rb +26 -33
  33. data/lib/appsignal/integrations/railtie.rb +1 -4
  34. data/lib/appsignal/integrations/rake.rb +26 -2
  35. data/lib/appsignal/integrations/redis.rb +17 -0
  36. data/lib/appsignal/integrations/resque.rb +39 -10
  37. data/lib/appsignal/integrations/sidekiq.rb +171 -0
  38. data/lib/appsignal/integrations/unicorn.rb +28 -0
  39. data/lib/appsignal/integrations/webmachine.rb +22 -24
  40. data/lib/appsignal/minutely.rb +0 -12
  41. data/lib/appsignal/version.rb +1 -1
  42. data/spec/lib/appsignal/auth_check_spec.rb +1 -24
  43. data/spec/lib/appsignal/cli_spec.rb +1 -1
  44. data/spec/lib/appsignal/config_spec.rb +2 -66
  45. data/spec/lib/appsignal/event_formatter_spec.rb +0 -37
  46. data/spec/lib/appsignal/hooks/celluloid_spec.rb +6 -1
  47. data/spec/lib/appsignal/hooks/rake_spec.rb +1 -2
  48. data/spec/lib/appsignal/hooks/redis_spec.rb +50 -15
  49. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +12 -464
  50. data/spec/lib/appsignal/hooks/unicorn_spec.rb +14 -3
  51. data/spec/lib/appsignal/hooks/webmachine_spec.rb +2 -13
  52. data/spec/lib/appsignal/hooks_spec.rb +6 -22
  53. data/spec/lib/appsignal/integrations/object_spec.rb +91 -8
  54. data/spec/lib/appsignal/integrations/padrino_spec.rb +2 -3
  55. data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -45
  56. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +524 -0
  57. data/spec/lib/appsignal/integrations/webmachine_spec.rb +26 -8
  58. data/spec/lib/appsignal/minutely_spec.rb +0 -19
  59. data/spec/lib/appsignal/transaction_spec.rb +1 -14
  60. data/spec/lib/appsignal/transmitter_spec.rb +1 -1
  61. data/spec/lib/appsignal_spec.rb +162 -116
  62. data/spec/spec_helper.rb +1 -15
  63. metadata +11 -21
  64. data/lib/appsignal/cli/notify_of_deploy.rb +0 -131
  65. data/lib/appsignal/integrations/object_ruby_19.rb +0 -37
  66. data/lib/appsignal/integrations/object_ruby_modern.rb +0 -64
  67. data/lib/appsignal/integrations/resque_active_job.rb +0 -19
  68. data/lib/appsignal/js_exception_transaction.rb +0 -56
  69. data/lib/appsignal/rack/js_exception_catcher.rb +0 -80
  70. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +0 -180
  71. data/spec/lib/appsignal/integrations/object_19_spec.rb +0 -266
  72. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +0 -28
  73. data/spec/lib/appsignal/integrations/resque_spec.rb +0 -28
  74. data/spec/lib/appsignal/js_exception_transaction_spec.rb +0 -128
  75. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +0 -170
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appsignal
4
- # @api private
5
- module Rack
6
- # JavaScript error catching middleware.
7
- #
8
- # Listens to the endpoint specified in the `frontend_error_catching_path`
9
- # configuration option.
10
- #
11
- # This is automatically included middleware in Rails apps if the
12
- # `frontend_error_catching_path` configuration option is active.
13
- #
14
- # If AppSignal is not active in the current environment, but does have
15
- # JavaScript error catching turned on, we assume that a JavaScript script
16
- # still sends errors to this endpoint. When AppSignal is not active in this
17
- # scenario this middleware still listens to the endpoint, but won't record
18
- # the error. It will return HTTP status code 202.
19
- #
20
- # @example with a Sinatra app
21
- # Sinatra::Application.use(Appsignal::Rack::JSExceptionCatcher)
22
- #
23
- # @see http://docs.appsignal.com/front-end/error-handling.html
24
- # @api private
25
- class JSExceptionCatcher
26
- include Appsignal::Utils::DeprecationMessage
27
-
28
- def initialize(app, _options = nil)
29
- Appsignal.logger.debug \
30
- "Initializing Appsignal::Rack::JSExceptionCatcher"
31
- deprecation_message "The Appsignal::Rack::JSExceptionCatcher is " \
32
- "deprecated and will be removed in a future version. Please use " \
33
- "the official AppSignal JavaScript integration by disabling " \
34
- "`enable_frontend_error_catching` in your configuration and " \
35
- "installing AppSignal for JavaScript instead. " \
36
- "(https://docs.appsignal.com/front-end/)"
37
- @app = app
38
- end
39
-
40
- def call(env)
41
- # Ignore other paths than the error catching path.
42
- return @app.call(env) unless error_cathing_endpoint?(env)
43
-
44
- # Prevent raising a 404 not found when a non-active environment posts
45
- # to this endpoint.
46
- unless Appsignal.active?
47
- return [
48
- 202,
49
- {},
50
- ["AppSignal JavaScript error catching endpoint is not active."]
51
- ]
52
- end
53
-
54
- begin
55
- body = JSON.parse(env["rack.input"].read)
56
- rescue JSON::ParserError
57
- return [400, {}, ["Request payload is not valid JSON."]]
58
- end
59
-
60
- if body["name"].is_a?(String) && !body["name"].empty?
61
- transaction = JSExceptionTransaction.new(body)
62
- transaction.complete!
63
- code = 200
64
- else
65
- Appsignal.logger.debug \
66
- "JSExceptionCatcher: Could not send exception, 'name' is empty."
67
- code = 422
68
- end
69
-
70
- [code, {}, []]
71
- end
72
-
73
- private
74
-
75
- def error_cathing_endpoint?(env)
76
- env["PATH_INFO"] == Appsignal.config[:frontend_error_catching_path]
77
- end
78
- end
79
- end
80
- end
@@ -1,180 +0,0 @@
1
- require "appsignal/cli"
2
-
3
- describe Appsignal::CLI::NotifyOfDeploy do
4
- include CLIHelpers
5
-
6
- let(:out_stream) { std_stream }
7
- let(:output) { out_stream.read }
8
- let(:err_stream) { std_stream }
9
- let(:stderr) { err_stream.read }
10
-
11
- define :include_deploy_notification do
12
- match do |log|
13
- log.include?("Notifying AppSignal of deploy with: ") &&
14
- log.include?("AppSignal has been notified of this deploy!")
15
- end
16
- end
17
- define :include_deploy_notification_with do |options|
18
- match do |log|
19
- return false unless options
20
- values = "revision: #{options[:revision]}, user: #{options[:user]}"
21
- log.include?("Notifying AppSignal of deploy with: #{values}") &&
22
- log.include?("AppSignal has been notified of this deploy!")
23
- end
24
- end
25
- define :include_config_error do
26
- match do |log|
27
- log.include? "Error: No valid config found."
28
- end
29
- end
30
- define :include_missing_options do |options|
31
- match do |log|
32
- log.include? "Error: Missing options: #{options.join(", ")}"
33
- end
34
- end
35
-
36
- def run
37
- capture_std_streams(out_stream, err_stream) do
38
- run_cli("notify_of_deploy", options)
39
- end
40
- end
41
-
42
- context "without config" do
43
- let(:config) { Appsignal::Config.new(tmp_dir, "production") }
44
- let(:options) { {} }
45
- around do |example|
46
- Dir.chdir tmp_dir do
47
- example.run
48
- end
49
- end
50
-
51
- it "prints a config error" do
52
- expect { run }.to raise_error(SystemExit)
53
- expect(output).to include_config_error
54
- expect(output).to_not include_deploy_notification
55
- end
56
- end
57
-
58
- context "with config" do
59
- let(:config) { project_fixture_config }
60
- before do
61
- config[:name] = options[:name] if options[:name]
62
- stub_api_request config, "markers", :revision => options[:revision],
63
- :user => options[:user]
64
- end
65
- around do |example|
66
- Dir.chdir project_fixture_path do
67
- example.run
68
- end
69
- end
70
-
71
- context "without environment" do
72
- let(:options) { { :environment => "", :revision => "foo", :user => "thijs" } }
73
- before do
74
- # Makes the config "active"
75
- ENV["APPSIGNAL_PUSH_API_KEY"] = "foo"
76
- end
77
-
78
- it "requires environment option" do
79
- expect { run }.to raise_error(SystemExit)
80
- expect(output).to include_missing_options(%w[environment])
81
- expect(output).to_not include_deploy_notification
82
- end
83
- end
84
-
85
- context "without known environment" do
86
- let(:options) { { :environment => "foo" } }
87
-
88
- it "prints a config error" do
89
- expect { run }.to raise_error(SystemExit)
90
- expect(output).to include_config_error
91
- expect(output).to_not include_missing_options([])
92
- expect(output).to_not include_deploy_notification
93
- end
94
- end
95
-
96
- context "with known environment" do
97
- context "without required options" do
98
- let(:options) { { :environment => "production" } }
99
-
100
- it "prints a missing required options error" do
101
- expect { run }.to raise_error(SystemExit)
102
- expect(output).to_not include_config_error
103
- expect(output).to include_missing_options(%w[revision user])
104
- expect(output).to_not include_deploy_notification
105
- end
106
-
107
- context "with empty required option" do
108
- let(:options) { { :environment => "production", :revision => "foo", :user => "" } }
109
-
110
- it "prints a missing required option error" do
111
- expect { run }.to raise_error(SystemExit)
112
- expect(output).to_not include_config_error
113
- expect(output).to include_missing_options(%w[user])
114
- expect(output).to_not include_deploy_notification
115
- end
116
- end
117
- end
118
-
119
- context "with required options" do
120
- let(:options) { { :environment => "production", :revision => "aaaaa", :user => "thijs" } }
121
- let(:log_stream) { std_stream }
122
- let(:log) { log_contents(log_stream) }
123
- before { Appsignal.logger = test_logger(log_stream) }
124
-
125
- it "notifies of a deploy" do
126
- run
127
- expect(output).to_not include_config_error
128
- expect(output).to_not include_missing_options([])
129
- expect(output).to include_deploy_notification_with(options)
130
- end
131
-
132
- it "prints a deprecation message" do
133
- run
134
- deprecation_message = "This command (appsignal notify_of_deploy) has been deprecated"
135
- expect(stderr).to include("appsignal WARNING: #{deprecation_message}")
136
- expect(log).to contains_log :warn, deprecation_message
137
- end
138
-
139
- context "with no app name configured" do
140
- before { ENV["APPSIGNAL_APP_NAME"] = "" }
141
-
142
- context "without name option" do
143
- let(:options) { { :environment => "production", :revision => "aaaaa", :user => "thijs" } }
144
-
145
- it "requires name option" do
146
- expect { run }.to raise_error(SystemExit)
147
- expect(output).to_not include_config_error
148
- expect(output).to include_missing_options(%w[name])
149
- expect(output).to_not include_deploy_notification
150
- end
151
- end
152
-
153
- context "with name option" do
154
- let(:options) { { :environment => "production", :revision => "aaaaa", :user => "thijs", :name => "foo" } }
155
-
156
- it "notifies of a deploy with a custom name" do
157
- run
158
- expect(output).to_not include_config_error
159
- expect(output).to_not include_missing_options([])
160
- expect(output).to include_deploy_notification_with(options)
161
- end
162
- end
163
- end
164
-
165
- context "with name option" do
166
- let(:options) do
167
- { :environment => "production", :revision => "aaaaa", :user => "thijs", :name => "foo" }
168
- end
169
-
170
- it "notifies of a deploy with a custom name" do
171
- run
172
- expect(output).to_not include_config_error
173
- expect(output).to_not include_missing_options([])
174
- expect(output).to include_deploy_notification_with(options)
175
- end
176
- end
177
- end
178
- end
179
- end
180
- end
@@ -1,266 +0,0 @@
1
- require "appsignal/integrations/object"
2
-
3
- def is_ruby_19
4
- RUBY_VERSION < "2.0"
5
- end
6
-
7
- describe Object do
8
- describe "#instrument_method" do
9
- context "with instance method" do
10
- let(:klass) do
11
- Class.new do
12
- def foo(param1, options = {})
13
- [param1, options]
14
- end
15
- appsignal_instrument_method :foo
16
- end
17
- end
18
- let(:instance) { klass.new }
19
-
20
- def call_with_arguments
21
- instance.foo(
22
- "abc",
23
- :foo => "bar"
24
- )
25
- end
26
-
27
- context "when active" do
28
- let(:transaction) { http_request_transaction }
29
- before do
30
- Appsignal.config = project_fixture_config
31
- expect(Appsignal::Transaction).to receive(:current).at_least(:once).and_return(transaction)
32
- end
33
- after { Appsignal.config = nil }
34
-
35
- context "with anonymous class" do
36
- it "instruments the method and calls it" do
37
- expect(Appsignal.active?).to be_truthy
38
- expect(transaction).to receive(:start_event)
39
- expect(transaction).to receive(:finish_event).with \
40
- "foo.AnonymousClass.other", nil, nil, Appsignal::EventFormatter::DEFAULT
41
- expect(call_with_arguments).to eq(["abc", { :foo => "bar" }])
42
- end
43
- end
44
-
45
- context "with named class" do
46
- before do
47
- class NamedClass
48
- def foo
49
- 1
50
- end
51
- appsignal_instrument_method :foo
52
- end
53
- end
54
- after { Object.send(:remove_const, :NamedClass) }
55
- let(:klass) { NamedClass }
56
-
57
- it "instruments the method and calls it" do
58
- expect(Appsignal.active?).to be_truthy
59
- expect(transaction).to receive(:start_event)
60
- expect(transaction).to receive(:finish_event).with \
61
- "foo.NamedClass.other", nil, nil, Appsignal::EventFormatter::DEFAULT
62
- expect(instance.foo).to eq(1)
63
- end
64
- end
65
-
66
- context "with nested named class" do
67
- before do
68
- module MyModule
69
- module NestedModule
70
- class NamedClass
71
- def bar
72
- 2
73
- end
74
- appsignal_instrument_method :bar
75
- end
76
- end
77
- end
78
- end
79
- after { Object.send(:remove_const, :MyModule) }
80
- let(:klass) { MyModule::NestedModule::NamedClass }
81
-
82
- it "instruments the method and calls it" do
83
- expect(Appsignal.active?).to be_truthy
84
- expect(transaction).to receive(:start_event)
85
- expect(transaction).to receive(:finish_event).with \
86
- "bar.NamedClass.NestedModule.MyModule.other", nil, nil,
87
- Appsignal::EventFormatter::DEFAULT
88
- expect(instance.bar).to eq(2)
89
- end
90
- end
91
-
92
- context "with custom name" do
93
- let(:klass) do
94
- Class.new do
95
- def foo
96
- 1
97
- end
98
- appsignal_instrument_method :foo, :name => "my_method.group"
99
- end
100
- end
101
-
102
- it "instruments with custom name" do
103
- expect(Appsignal.active?).to be_truthy
104
- expect(transaction).to receive(:start_event)
105
- expect(transaction).to receive(:finish_event).with \
106
- "my_method.group", nil, nil, Appsignal::EventFormatter::DEFAULT
107
- expect(instance.foo).to eq(1)
108
- end
109
- end
110
-
111
- context "with a method given a block" do
112
- let(:klass) do
113
- Class.new do
114
- def foo
115
- yield
116
- end
117
- appsignal_instrument_method :foo
118
- end
119
- end
120
-
121
- it "should yield the block" do
122
- expect(instance.foo { 42 }).to eq(42)
123
- end
124
- end
125
- end
126
-
127
- context "when not active" do
128
- let(:transaction) { Appsignal::Transaction.current }
129
-
130
- it "does not instrument, but still calls the method" do
131
- expect(Appsignal.active?).to be_falsy
132
- expect(transaction).to_not receive(:start_event)
133
- expect(call_with_arguments).to eq(["abc", { :foo => "bar" }])
134
- end
135
- end
136
- end
137
-
138
- context "with class method" do
139
- let(:klass) do
140
- Class.new do
141
- def self.bar(param1, options = {})
142
- [param1, options]
143
- end
144
- appsignal_instrument_class_method :bar
145
- end
146
- end
147
- def call_with_arguments
148
- klass.bar(
149
- "abc",
150
- :foo => "bar"
151
- )
152
- end
153
-
154
- context "when active" do
155
- let(:transaction) { http_request_transaction }
156
- before do
157
- Appsignal.config = project_fixture_config
158
- expect(Appsignal::Transaction).to receive(:current).at_least(:once)
159
- .and_return(transaction)
160
- end
161
- after { Appsignal.config = nil }
162
-
163
- context "with anonymous class" do
164
- it "instruments the method and calls it" do
165
- expect(Appsignal.active?).to be_truthy
166
- expect(transaction).to receive(:start_event)
167
- expect(transaction).to receive(:finish_event).with \
168
- "bar.class_method.AnonymousClass.other", nil, nil, Appsignal::EventFormatter::DEFAULT
169
- expect(call_with_arguments).to eq(["abc", { :foo => "bar" }])
170
- end
171
- end
172
-
173
- context "with named class" do
174
- before do
175
- class NamedClass
176
- def self.bar
177
- 2
178
- end
179
- appsignal_instrument_class_method :bar
180
- end
181
- end
182
- after { Object.send(:remove_const, :NamedClass) }
183
- let(:klass) { NamedClass }
184
-
185
- it "instruments the method and calls it" do
186
- expect(Appsignal.active?).to be_truthy
187
- expect(transaction).to receive(:start_event)
188
- expect(transaction).to receive(:finish_event).with \
189
- "bar.class_method.NamedClass.other", nil, nil, Appsignal::EventFormatter::DEFAULT
190
- expect(klass.bar).to eq(2)
191
- end
192
-
193
- context "with nested named class" do
194
- before do
195
- module MyModule
196
- module NestedModule
197
- class NamedClass
198
- def self.bar
199
- 2
200
- end
201
- appsignal_instrument_class_method :bar
202
- end
203
- end
204
- end
205
- end
206
- after { Object.send(:remove_const, :MyModule) }
207
- let(:klass) { MyModule::NestedModule::NamedClass }
208
-
209
- it "instruments the method and calls it" do
210
- expect(Appsignal.active?).to be_truthy
211
- expect(transaction).to receive(:start_event)
212
- expect(transaction).to receive(:finish_event).with \
213
- "bar.class_method.NamedClass.NestedModule.MyModule.other", nil, nil,
214
- Appsignal::EventFormatter::DEFAULT
215
- expect(klass.bar).to eq(2)
216
- end
217
- end
218
- end
219
-
220
- context "with custom name" do
221
- let(:klass) do
222
- Class.new do
223
- def self.bar
224
- 2
225
- end
226
- appsignal_instrument_class_method :bar, :name => "my_method.group"
227
- end
228
- end
229
-
230
- it "instruments with custom name" do
231
- expect(Appsignal.active?).to be_truthy
232
- expect(transaction).to receive(:start_event)
233
- expect(transaction).to receive(:finish_event).with \
234
- "my_method.group", nil, nil, Appsignal::EventFormatter::DEFAULT
235
- expect(klass.bar).to eq(2)
236
- end
237
- end
238
-
239
- context "with a method given a block" do
240
- let(:klass) do
241
- Class.new do
242
- def self.bar
243
- yield
244
- end
245
- appsignal_instrument_class_method :bar
246
- end
247
- end
248
-
249
- it "should yield the block" do
250
- expect(klass.bar { 42 }).to eq(42)
251
- end
252
- end
253
- end
254
-
255
- context "when not active" do
256
- let(:transaction) { Appsignal::Transaction.current }
257
-
258
- it "does not instrument, but still call the method" do
259
- expect(Appsignal.active?).to be_falsy
260
- expect(transaction).to_not receive(:start_event)
261
- expect(call_with_arguments).to eq(["abc", { :foo => "bar" }])
262
- end
263
- end
264
- end
265
- end
266
- end