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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/.semaphore/semaphore.yml +37 -9
  4. data/CHANGELOG.md +10 -1
  5. data/build_matrix.yml +5 -1
  6. data/gemfiles/rails-4.2.gemfile +9 -2
  7. data/gemfiles/rails-5.0.gemfile +1 -0
  8. data/gemfiles/rails-5.1.gemfile +1 -0
  9. data/gemfiles/rails-5.2.gemfile +1 -0
  10. data/gemfiles/rails-6.0.gemfile +1 -0
  11. data/gemfiles/resque-1.gemfile +7 -0
  12. data/gemfiles/{resque.gemfile → resque-2.gemfile} +1 -1
  13. data/lib/appsignal/hooks.rb +2 -0
  14. data/lib/appsignal/hooks/active_job.rb +89 -0
  15. data/lib/appsignal/hooks/resque.rb +60 -0
  16. data/lib/appsignal/hooks/sidekiq.rb +16 -92
  17. data/lib/appsignal/integrations/que.rb +1 -1
  18. data/lib/appsignal/integrations/resque.rb +9 -12
  19. data/lib/appsignal/integrations/resque_active_job.rb +9 -32
  20. data/lib/appsignal/transaction.rb +10 -0
  21. data/lib/appsignal/utils/deprecation_message.rb +5 -1
  22. data/lib/appsignal/version.rb +1 -1
  23. data/spec/lib/appsignal/hooks/activejob_spec.rb +458 -0
  24. data/spec/lib/appsignal/hooks/resque_spec.rb +185 -0
  25. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +215 -263
  26. data/spec/lib/appsignal/integrations/que_spec.rb +25 -6
  27. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +20 -179
  28. data/spec/lib/appsignal/integrations/resque_spec.rb +20 -85
  29. data/spec/lib/appsignal/probes/sidekiq_spec.rb +10 -7
  30. data/spec/lib/appsignal/transaction_spec.rb +5 -7
  31. data/spec/support/helpers/action_mailer_helpers.rb +25 -0
  32. data/spec/support/helpers/dependency_helper.rb +9 -2
  33. data/spec/support/helpers/transaction_helpers.rb +6 -0
  34. data/spec/support/stubs/sidekiq/api.rb +1 -1
  35. metadata +12 -3
@@ -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
@@ -7,7 +7,7 @@ describe Appsignal::Probes::SidekiqProbe do
7
7
  let(:expected_default_tags) { { :hostname => "localhost" } }
8
8
  before do
9
9
  Appsignal.config = project_fixture_config
10
- module Sidekiq
10
+ module SidekiqMock
11
11
  def self.redis_info
12
12
  {
13
13
  "connected_clients" => 2,
@@ -88,15 +88,14 @@ describe Appsignal::Probes::SidekiqProbe do
88
88
  end
89
89
  end
90
90
  end
91
+ stub_const("Sidekiq", SidekiqMock)
91
92
  end
92
- after { Object.send(:remove_const, "Sidekiq") }
93
+ after { Object.send(:remove_const, :SidekiqMock) }
93
94
 
94
95
  describe ".dependencies_present?" do
95
96
  before do
96
- class Redis; end
97
- Redis.const_set(:VERSION, version)
97
+ stub_const("Redis::VERSION", version)
98
98
  end
99
- after { Object.send(:remove_const, "Redis") }
100
99
 
101
100
  context "when Redis version is < 3.3.5" do
102
101
  let(:version) { "3.3.4" }
@@ -116,9 +115,13 @@ describe Appsignal::Probes::SidekiqProbe do
116
115
  end
117
116
 
118
117
  it "loads Sidekiq::API" do
119
- expect(defined?(Sidekiq::API)).to be_falsy
118
+ # Hide the Sidekiq constant if it was already loaded. It will be
119
+ # redefined by loading "sidekiq/api" in the probe.
120
+ hide_const "Sidekiq::Stats"
121
+
122
+ expect(defined?(Sidekiq::Stats)).to be_falsy
120
123
  probe
121
- expect(defined?(Sidekiq::API)).to be_truthy
124
+ expect(defined?(Sidekiq::Stats)).to be_truthy
122
125
  end
123
126
 
124
127
  it "logs config on initialize" do
@@ -473,22 +473,20 @@ describe Appsignal::Transaction do
473
473
  end
474
474
  end
475
475
 
476
- describe "set_queue_start" do
477
- it "should set the queue start in extension" do
478
- expect(transaction.ext).to receive(:set_queue_start).with(
479
- 10.0
480
- ).once
476
+ describe "#set_queue_start" do
477
+ it "sets the queue start in extension" do
478
+ expect(transaction.ext).to receive(:set_queue_start).with(10.0).once
481
479
 
482
480
  transaction.set_queue_start(10.0)
483
481
  end
484
482
 
485
- it "should not set the queue start in extension when value is nil" do
483
+ it "does not set the queue start in extension when value is nil" do
486
484
  expect(transaction.ext).to_not receive(:set_queue_start)
487
485
 
488
486
  transaction.set_queue_start(nil)
489
487
  end
490
488
 
491
- it "should not raise an error when the queue start is too big" do
489
+ it "does not raise an error when the queue start is too big" do
492
490
  expect(transaction.ext).to receive(:set_queue_start).and_raise(RangeError)
493
491
 
494
492
  expect(Appsignal.logger).to receive(:warn).with("Queue start value 10 is too big")