appsignal 2.11.0.alpha.2-java → 2.11.0.beta.5-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/.semaphore/semaphore.yml +94 -10
  4. data/CHANGELOG.md +31 -1
  5. data/README.md +4 -4
  6. data/Rakefile +16 -4
  7. data/appsignal.gemspec +1 -1
  8. data/build_matrix.yml +7 -3
  9. data/ext/Rakefile +2 -0
  10. data/ext/agent.yml +19 -19
  11. data/ext/base.rb +7 -0
  12. data/ext/extconf.rb +2 -0
  13. data/gemfiles/rails-4.2.gemfile +9 -2
  14. data/gemfiles/rails-5.0.gemfile +1 -0
  15. data/gemfiles/rails-5.1.gemfile +1 -0
  16. data/gemfiles/rails-5.2.gemfile +1 -0
  17. data/gemfiles/rails-6.0.gemfile +1 -0
  18. data/gemfiles/resque-1.gemfile +7 -0
  19. data/gemfiles/{resque.gemfile → resque-2.gemfile} +1 -1
  20. data/lib/appsignal.rb +1 -0
  21. data/lib/appsignal/auth_check.rb +4 -2
  22. data/lib/appsignal/cli/diagnose.rb +1 -1
  23. data/lib/appsignal/config.rb +35 -2
  24. data/lib/appsignal/extension.rb +6 -5
  25. data/lib/appsignal/extension/jruby.rb +6 -5
  26. data/lib/appsignal/hooks.rb +25 -0
  27. data/lib/appsignal/hooks/active_job.rb +137 -0
  28. data/lib/appsignal/hooks/puma.rb +0 -1
  29. data/lib/appsignal/hooks/resque.rb +60 -0
  30. data/lib/appsignal/hooks/sidekiq.rb +17 -94
  31. data/lib/appsignal/integrations/delayed_job_plugin.rb +1 -1
  32. data/lib/appsignal/integrations/que.rb +1 -1
  33. data/lib/appsignal/integrations/resque.rb +9 -12
  34. data/lib/appsignal/integrations/resque_active_job.rb +9 -32
  35. data/lib/appsignal/probes.rb +7 -0
  36. data/lib/appsignal/probes/puma.rb +1 -1
  37. data/lib/appsignal/probes/sidekiq.rb +3 -1
  38. data/lib/appsignal/transaction.rb +10 -0
  39. data/lib/appsignal/utils/deprecation_message.rb +6 -2
  40. data/lib/appsignal/version.rb +1 -1
  41. data/spec/lib/appsignal/auth_check_spec.rb +23 -0
  42. data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
  43. data/spec/lib/appsignal/capistrano3_spec.rb +1 -1
  44. data/spec/lib/appsignal/cli/diagnose_spec.rb +42 -0
  45. data/spec/lib/appsignal/config_spec.rb +21 -0
  46. data/spec/lib/appsignal/extension/jruby_spec.rb +31 -28
  47. data/spec/lib/appsignal/extension_install_failure_spec.rb +23 -0
  48. data/spec/lib/appsignal/hooks/activejob_spec.rb +591 -0
  49. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +3 -14
  50. data/spec/lib/appsignal/hooks/resque_spec.rb +185 -0
  51. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +222 -268
  52. data/spec/lib/appsignal/hooks_spec.rb +57 -0
  53. data/spec/lib/appsignal/integrations/que_spec.rb +25 -6
  54. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +20 -179
  55. data/spec/lib/appsignal/integrations/resque_spec.rb +20 -85
  56. data/spec/lib/appsignal/marker_spec.rb +1 -1
  57. data/spec/lib/appsignal/probes/sidekiq_spec.rb +10 -7
  58. data/spec/lib/appsignal/transaction_spec.rb +5 -7
  59. data/spec/spec_helper.rb +5 -0
  60. data/spec/support/helpers/action_mailer_helpers.rb +25 -0
  61. data/spec/support/helpers/config_helpers.rb +3 -2
  62. data/spec/support/helpers/dependency_helper.rb +9 -2
  63. data/spec/support/helpers/transaction_helpers.rb +6 -0
  64. data/spec/support/stubs/sidekiq/api.rb +1 -1
  65. data/spec/support/testing.rb +19 -19
  66. metadata +16 -4
@@ -78,6 +78,63 @@ describe Appsignal::Hooks do
78
78
  expect(Appsignal::Hooks.hooks[:mock_error_hook].installed?).to be_falsy
79
79
  Appsignal::Hooks.hooks.delete(:mock_error_hook)
80
80
  end
81
+
82
+ describe "missing constants" do
83
+ let(:err_stream) { std_stream }
84
+ let(:stderr) { err_stream.read }
85
+ let(:log_stream) { std_stream }
86
+ let(:log) { log_contents(log_stream) }
87
+ before do
88
+ Appsignal.logger = test_logger(log_stream)
89
+ end
90
+
91
+ def call_constant(&block)
92
+ capture_std_streams(std_stream, err_stream, &block)
93
+ end
94
+
95
+ describe "SidekiqProbe" do
96
+ it "logs a deprecation message and returns the new constant" do
97
+ constant = call_constant { Appsignal::Hooks::SidekiqProbe }
98
+
99
+ expect(constant).to eql(Appsignal::Probes::SidekiqProbe)
100
+ expect(constant.name).to eql("Appsignal::Probes::SidekiqProbe")
101
+
102
+ deprecation_message =
103
+ "The constant Appsignal::Hooks::SidekiqProbe has been deprecated. " \
104
+ "Please update the constant name to Appsignal::Probes::SidekiqProbe " \
105
+ "in the following file to remove this message.\n#{__FILE__}:"
106
+ expect(stderr).to include "appsignal WARNING: #{deprecation_message}"
107
+ expect(log).to contains_log :warn, deprecation_message
108
+ end
109
+ end
110
+
111
+ describe "PumaProbe" do
112
+ it "logs a deprecation message and returns the new constant" do
113
+ constant = call_constant { Appsignal::Hooks::PumaProbe }
114
+
115
+ expect(constant).to eql(Appsignal::Probes::PumaProbe)
116
+ expect(constant.name).to eql("Appsignal::Probes::PumaProbe")
117
+
118
+ deprecation_message =
119
+ "The constant Appsignal::Hooks::PumaProbe has been deprecated. " \
120
+ "Please update the constant name to Appsignal::Probes::PumaProbe " \
121
+ "in the following file to remove this message.\n#{__FILE__}:"
122
+ expect(stderr).to include "appsignal WARNING: #{deprecation_message}"
123
+ expect(log).to contains_log :warn, deprecation_message
124
+ end
125
+ end
126
+
127
+ describe "other constant" do
128
+ it "raises a NameError like Ruby normally does" do
129
+ expect do
130
+ call_constant { Appsignal::Hooks::Unknown }
131
+ end.to raise_error(NameError)
132
+
133
+ expect(stderr).to be_empty
134
+ expect(log).to be_empty
135
+ end
136
+ end
137
+ end
81
138
  end
82
139
 
83
140
  describe Appsignal::Hooks::Helpers do
@@ -14,7 +14,6 @@ if DependencyHelper.que_present?
14
14
  :error_count => 0
15
15
  }
16
16
  end
17
-
18
17
  let(:env) do
19
18
  {
20
19
  :class => "MyQueJob",
@@ -29,7 +28,6 @@ if DependencyHelper.que_present?
29
28
  :params => %w[1 birds]
30
29
  }
31
30
  end
32
-
33
31
  let(:job) do
34
32
  Class.new(::Que::Job) do
35
33
  def run(*args)
@@ -37,7 +35,6 @@ if DependencyHelper.que_present?
37
35
  end
38
36
  end
39
37
  let(:instance) { job.new(job_attrs) }
40
-
41
38
  before do
42
39
  allow(Que).to receive(:execute)
43
40
 
@@ -46,10 +43,14 @@ if DependencyHelper.que_present?
46
43
  end
47
44
  around { |example| keep_transactions { example.run } }
48
45
 
46
+ def perform_job(job)
47
+ job._run
48
+ end
49
+
49
50
  context "success" do
50
51
  it "creates a transaction for a job" do
51
52
  expect do
52
- instance._run
53
+ perform_job(instance)
53
54
  end.to change { created_transactions.length }.by(1)
54
55
 
55
56
  expect(last_transaction).to be_completed
@@ -95,7 +96,7 @@ if DependencyHelper.que_present?
95
96
 
96
97
  expect do
97
98
  expect do
98
- instance._run
99
+ perform_job(instance)
99
100
  end.to raise_error(ExampleException)
100
101
  end.to change { created_transactions.length }.by(1)
101
102
 
@@ -130,7 +131,7 @@ if DependencyHelper.que_present?
130
131
  it "reports errors and not re-raise them" do
131
132
  allow(instance).to receive(:run).and_raise(error)
132
133
 
133
- expect { instance._run }.to change { created_transactions.length }.by(1)
134
+ expect { perform_job(instance) }.to change { created_transactions.length }.by(1)
134
135
 
135
136
  expect(last_transaction).to be_completed
136
137
  transaction_hash = last_transaction.to_h
@@ -156,6 +157,24 @@ if DependencyHelper.que_present?
156
157
  )
157
158
  end
158
159
  end
160
+
161
+ context "when action set in job" do
162
+ let(:job) do
163
+ Class.new(::Que::Job) do
164
+ def run(*_args)
165
+ Appsignal.set_action("MyCustomJob#perform")
166
+ end
167
+ end
168
+ end
169
+
170
+ it "uses the custom action" do
171
+ perform_job(instance)
172
+
173
+ expect(last_transaction).to be_completed
174
+ transaction_hash = last_transaction.to_h
175
+ expect(transaction_hash).to include("action" => "MyCustomJob#perform")
176
+ end
177
+ end
159
178
  end
160
179
  end
161
180
  end
@@ -1,187 +1,28 @@
1
- if DependencyHelper.active_job_present?
2
- require "active_job"
3
- require File.expand_path("lib/appsignal/integrations/resque_active_job.rb")
1
+ require "appsignal/integrations/resque_active_job"
4
2
 
5
- class TestActiveJob < ActiveJob::Base
6
- include Appsignal::Integrations::ResqueActiveJobPlugin
3
+ describe "Legacy Resque ActiveJob integration" do
4
+ let(:err_stream) { std_stream }
5
+ let(:stderr) { err_stream.read }
6
+ let(:log_stream) { std_stream }
7
+ let(:log) { log_contents(log_stream) }
7
8
 
8
- def perform(_)
9
- end
10
- end
11
-
12
- describe Appsignal::Integrations::ResqueActiveJobPlugin do
13
- let(:args) { "argument" }
14
- let(:job) { TestActiveJob.new(args) }
15
- before { start_agent }
16
-
17
- def perform
18
- keep_transactions do
19
- job.perform_now
20
- end
21
- end
22
-
23
- context "without error" do
24
- it "creates a new transaction" do
25
- expect { perform }.to change { created_transactions.length }.by(1)
26
-
27
- expect(last_transaction.to_h).to include(
28
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
29
- "action" => "TestActiveJob#perform",
30
- "error" => nil,
31
- "events" => [
32
- hash_including(
33
- "name" => "perform_job.resque",
34
- "title" => "",
35
- "body" => "",
36
- "body_format" => Appsignal::EventFormatter::DEFAULT,
37
- "count" => 1,
38
- "duration" => kind_of(Float)
39
- )
40
- ],
41
- "sample_data" => hash_including(
42
- "params" => ["argument"],
43
- "metadata" => {
44
- "id" => kind_of(String),
45
- "queue" => "default"
46
- }
47
- )
48
- )
49
- end
50
- end
51
-
52
- context "with error" do
53
- let(:job) do
54
- class BrokenTestActiveJob < ActiveJob::Base
55
- include Appsignal::Integrations::ResqueActiveJobPlugin
56
-
57
- def perform(_)
58
- raise ExampleException, "my error message"
59
- end
60
- end
61
-
62
- BrokenTestActiveJob.new(args)
63
- end
64
-
65
- it "creates a new transaction with an error" do
66
- expect do
67
- expect { perform }.to raise_error(ExampleException, "my error message")
68
- end.to change { created_transactions.length }.by(1)
9
+ it "logs and prints a deprecation message on extend" do
10
+ Appsignal.logger = test_logger(log_stream)
69
11
 
70
- expect(last_transaction.to_h).to include(
71
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
72
- "action" => "BrokenTestActiveJob#perform",
73
- "error" => {
74
- "name" => "ExampleException",
75
- "message" => "my error message",
76
- "backtrace" => kind_of(String)
77
- },
78
- "sample_data" => hash_including(
79
- "params" => ["argument"],
80
- "metadata" => {
81
- "id" => kind_of(String),
82
- "queue" => "default"
83
- }
84
- )
85
- )
12
+ capture_std_streams(std_stream, err_stream) do
13
+ Class.new do
14
+ include Appsignal::Integrations::ResqueActiveJobPlugin
86
15
  end
87
16
  end
88
17
 
89
- context "with complex arguments" do
90
- context "with too long values" do
91
- let(:args) do
92
- {
93
- :foo => "Foo",
94
- :bar => "a" * 2001
95
- }
96
- end
97
-
98
- it "truncates large argument values" do
99
- perform
100
- expect(last_transaction.to_h).to include(
101
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
102
- "action" => "TestActiveJob#perform",
103
- "error" => nil,
104
- "sample_data" => hash_including(
105
- "params" => ["foo" => "Foo", "bar" => "#{"a" * 2000}..."],
106
- "metadata" => {
107
- "id" => kind_of(String),
108
- "queue" => "default"
109
- }
110
- )
111
- )
112
- end
113
- end
114
-
115
- context "with parameter filtering" do
116
- let(:args) do
117
- {
118
- :foo => "Foo",
119
- :bar => "Bar"
120
- }
121
- end
122
- before { Appsignal.config[:filter_parameters] = ["foo"] }
123
-
124
- it "filters selected arguments" do
125
- perform
126
- expect(last_transaction.to_h).to include(
127
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
128
- "action" => "TestActiveJob#perform",
129
- "error" => nil,
130
- "sample_data" => hash_including(
131
- "params" => ["foo" => "[FILTERED]", "bar" => "Bar"],
132
- "metadata" => {
133
- "id" => kind_of(String),
134
- "queue" => "default"
135
- }
136
- )
137
- )
138
- end
139
- end
140
- end
141
-
142
- context "without queue time" do
143
- it "does not add queue time to transaction" do
144
- # TODO: Not available in transaction.to_h yet.
145
- # https://github.com/appsignal/appsignal-agent/issues/293
146
- expect(Appsignal).to receive(:monitor_single_transaction).with(
147
- "perform_job.resque",
148
- a_hash_including(:queue_start => nil)
149
- ).and_call_original
150
-
151
- perform
152
- expect(last_transaction.to_h).to include(
153
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
154
- "action" => "TestActiveJob#perform",
155
- "events" => [
156
- hash_including("name" => "perform_job.resque")
157
- ]
158
- )
159
- end
160
- end
161
-
162
- if DependencyHelper.rails6_present?
163
- context "with queue time" do
164
- it "adds queue time to transction" do
165
- queue_start = "2017-01-01 10:01:00UTC"
166
- queue_start_time = Time.parse(queue_start)
167
- # TODO: Not available in transaction.to_h yet.
168
- # https://github.com/appsignal/appsignal-agent/issues/293
169
- expect(Appsignal).to receive(:monitor_single_transaction).with(
170
- "perform_job.resque",
171
- a_hash_including(:queue_start => queue_start_time)
172
- ).and_call_original
173
- job.enqueued_at = queue_start
174
-
175
- perform
176
- expect(last_transaction.to_h).to include(
177
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
178
- "action" => "TestActiveJob#perform",
179
- "events" => [
180
- hash_including("name" => "perform_job.resque")
181
- ]
182
- )
183
- end
184
- end
185
- end
18
+ deprecation_message =
19
+ "The AppSignal ResqueActiveJobPlugin is deprecated and does " \
20
+ "nothing on extend. In this version of the AppSignal Ruby gem " \
21
+ "the integration with Resque is automatic on all Resque workers. " \
22
+ "Please remove the following line from this file to remove this " \
23
+ "message: include Appsignal::Integrations::ResqueActiveJobPlugin\n" \
24
+ "#{__FILE__}:"
25
+ expect(stderr).to include "appsignal WARNING: #{deprecation_message}"
26
+ expect(log).to contains_log :warn, deprecation_message
186
27
  end
187
28
  end
@@ -1,93 +1,28 @@
1
- if DependencyHelper.resque_present?
2
- describe "Resque integration" do
3
- let(:file) { File.expand_path("lib/appsignal/integrations/resque.rb") }
1
+ require "appsignal/integrations/resque"
4
2
 
5
- context "with resque" do
6
- before do
7
- load file
8
- start_agent
3
+ describe "Legacy Resque integration" do
4
+ let(:err_stream) { std_stream }
5
+ let(:stderr) { err_stream.read }
6
+ let(:log_stream) { std_stream }
7
+ let(:log) { log_contents(log_stream) }
9
8
 
10
- class TestJob
11
- extend Appsignal::Integrations::ResquePlugin
9
+ it "logs and prints a deprecation message on extend" do
10
+ Appsignal.logger = test_logger(log_stream)
12
11
 
13
- def self.perform
14
- end
15
- end
16
-
17
- class BrokenTestJob
18
- extend Appsignal::Integrations::ResquePlugin
19
-
20
- def self.perform
21
- raise ExampleException, "my error message"
22
- end
23
- end
24
- end
25
-
26
- describe :around_perform_resque_plugin do
27
- let(:job) { ::Resque::Job.new("default", "class" => "TestJob") }
28
- before { expect(Appsignal).to receive(:stop) }
29
-
30
- context "without exception" do
31
- it "creates a new transaction" do
32
- expect do
33
- keep_transactions { job.perform }
34
- end.to change { created_transactions.length }.by(1)
35
-
36
- expect(last_transaction).to be_completed
37
- expect(last_transaction.to_h).to include(
38
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
39
- "action" => "TestJob#perform",
40
- "error" => nil,
41
- "events" => [
42
- hash_including(
43
- "name" => "perform_job.resque",
44
- "title" => "",
45
- "body" => "",
46
- "body_format" => Appsignal::EventFormatter::DEFAULT,
47
- "count" => 1,
48
- "duration" => kind_of(Float)
49
- )
50
- ]
51
- )
52
- end
53
- end
54
-
55
- context "with exception" do
56
- let(:job) { ::Resque::Job.new("default", "class" => "BrokenTestJob") }
57
-
58
- def perform
59
- keep_transactions do
60
- expect do
61
- job.perform
62
- end.to raise_error(ExampleException, "my error message")
63
- end
64
- end
65
-
66
- it "sets the exception on the transaction" do
67
- expect do
68
- perform
69
- end.to change { created_transactions.length }.by(1)
70
-
71
- expect(last_transaction).to be_completed
72
- expect(last_transaction.to_h).to include(
73
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
74
- "action" => "BrokenTestJob#perform",
75
- "error" => {
76
- "name" => "ExampleException",
77
- "message" => "my error message",
78
- "backtrace" => kind_of(String)
79
- }
80
- )
81
- end
82
- end
12
+ capture_std_streams(std_stream, err_stream) do
13
+ Class.new do
14
+ extend Appsignal::Integrations::ResquePlugin
83
15
  end
84
16
  end
85
17
 
86
- context "without resque" do
87
- before(:context) { Object.send(:remove_const, :Resque) }
88
-
89
- it { expect { ::Resque }.to raise_error(NameError) }
90
- it { expect { load file }.to_not raise_error }
91
- end
18
+ deprecation_message =
19
+ "The AppSignal ResquePlugin is deprecated and does " \
20
+ "nothing on extend. In this version of the AppSignal Ruby gem " \
21
+ "the integration with Resque is automatic on all Resque workers. " \
22
+ "Please remove the following line from this file to remove this " \
23
+ "message: extend Appsignal::Integrations::ResquePlugin\n" \
24
+ "#{__FILE__}:"
25
+ expect(stderr).to include "appsignal WARNING: #{deprecation_message}"
26
+ expect(log).to contains_log :warn, deprecation_message
92
27
  end
93
28
  end