appsignal 2.11.0.alpha.2-java → 2.11.0.beta.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 (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")