appsignal 2.9.18-java → 2.10.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +0 -6
- data/CHANGELOG.md +17 -1
- data/Rakefile +16 -2
- data/lib/appsignal/cli.rb +9 -2
- data/lib/appsignal/cli/diagnose.rb +20 -19
- data/lib/appsignal/cli/helpers.rb +22 -10
- data/lib/appsignal/cli/install.rb +2 -1
- data/lib/appsignal/config.rb +18 -7
- data/lib/appsignal/event_formatter.rb +4 -4
- data/lib/appsignal/minutely.rb +4 -4
- data/lib/appsignal/rack/js_exception_catcher.rb +6 -0
- data/lib/appsignal/transaction.rb +1 -1
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +54 -11
- data/spec/lib/appsignal/cli/helpers_spec.rb +11 -3
- data/spec/lib/appsignal/cli/install_spec.rb +30 -1
- data/spec/lib/appsignal/config_spec.rb +75 -7
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +1 -5
- data/spec/lib/appsignal/hooks/rake_spec.rb +41 -39
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +2 -15
- data/spec/lib/appsignal/integrations/object_spec.rb +2 -2
- data/spec/lib/appsignal/integrations/que_spec.rb +26 -39
- data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +108 -46
- data/spec/lib/appsignal/integrations/resque_spec.rb +40 -39
- data/spec/lib/appsignal/minutely_spec.rb +3 -3
- data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +19 -5
- data/spec/lib/appsignal/transaction_spec.rb +4 -12
- data/spec/lib/appsignal_spec.rb +7 -8
- data/spec/spec_helper.rb +11 -11
- data/spec/support/fixtures/projects/broken/config/appsignal.yml +1 -0
- data/spec/support/helpers/cli_helpers.rb +15 -1
- data/spec/support/helpers/transaction_helpers.rb +53 -0
- data/spec/support/matchers/be_completed.rb +5 -0
- data/spec/support/matchers/have_colorized_text.rb +28 -0
- data/spec/support/testing.rb +113 -0
- metadata +10 -2
@@ -17,67 +17,129 @@ if DependencyHelper.resque_present? && DependencyHelper.active_job_present?
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
:method => "perform",
|
25
|
-
:params => ["argument"],
|
26
|
-
:metadata => {
|
27
|
-
:id => kind_of(String),
|
28
|
-
:queue => "default"
|
29
|
-
}
|
30
|
-
)
|
20
|
+
def perform
|
21
|
+
keep_transactions do
|
22
|
+
job.perform_now
|
23
|
+
end
|
31
24
|
end
|
32
25
|
|
33
|
-
context "
|
34
|
-
|
35
|
-
{
|
36
|
-
|
37
|
-
|
38
|
-
|
26
|
+
context "without error" do
|
27
|
+
it "creates a new transaction" do
|
28
|
+
expect { perform }.to change { created_transactions.length }.by(1)
|
29
|
+
|
30
|
+
expect(last_transaction.to_h).to include(
|
31
|
+
"namespace" => Appsignal::Transaction::BACKGROUND_JOB,
|
32
|
+
"action" => "TestActiveJob#perform",
|
33
|
+
"error" => nil,
|
34
|
+
"events" => [
|
35
|
+
hash_including(
|
36
|
+
"name" => "perform_job.resque",
|
37
|
+
"title" => "",
|
38
|
+
"body" => "",
|
39
|
+
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
40
|
+
"count" => 1,
|
41
|
+
"duration" => kind_of(Float)
|
42
|
+
)
|
43
|
+
],
|
44
|
+
"sample_data" => hash_including(
|
45
|
+
"params" => ["argument"],
|
46
|
+
"metadata" => {
|
47
|
+
"id" => kind_of(String),
|
48
|
+
"queue" => "default"
|
49
|
+
}
|
50
|
+
)
|
51
|
+
)
|
39
52
|
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "with error" do
|
56
|
+
let(:job) do
|
57
|
+
class BrokenTestActiveJob < ActiveJob::Base
|
58
|
+
include Appsignal::Integrations::ResqueActiveJobPlugin
|
40
59
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
60
|
+
def perform(_)
|
61
|
+
raise ExampleException, "my error message"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
BrokenTestActiveJob.new(args)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "creates a new transaction with an error" do
|
69
|
+
expect do
|
70
|
+
expect { perform }.to raise_error(ExampleException, "my error message")
|
71
|
+
end.to change { created_transactions.length }.by(1)
|
72
|
+
|
73
|
+
expect(last_transaction.to_h).to include(
|
74
|
+
"namespace" => Appsignal::Transaction::BACKGROUND_JOB,
|
75
|
+
"action" => "BrokenTestActiveJob#perform",
|
76
|
+
"error" => {
|
77
|
+
"name" => "ExampleException",
|
78
|
+
"message" => "my error message",
|
79
|
+
"backtrace" => kind_of(String)
|
80
|
+
},
|
81
|
+
"sample_data" => hash_including(
|
82
|
+
"params" => ["argument"],
|
83
|
+
"metadata" => {
|
84
|
+
"id" => kind_of(String),
|
85
|
+
"queue" => "default"
|
86
|
+
}
|
87
|
+
)
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "with complex arguments" do
|
93
|
+
context "with too long values" do
|
94
|
+
let(:args) do
|
95
|
+
{
|
47
96
|
:foo => "Foo",
|
48
|
-
:bar => "
|
49
|
-
],
|
50
|
-
:metadata => {
|
51
|
-
:id => kind_of(String),
|
52
|
-
:queue => "default"
|
97
|
+
:bar => "a" * 2001
|
53
98
|
}
|
54
|
-
|
99
|
+
end
|
100
|
+
|
101
|
+
it "truncates large argument values" do
|
102
|
+
perform
|
103
|
+
expect(last_transaction.to_h).to include(
|
104
|
+
"namespace" => Appsignal::Transaction::BACKGROUND_JOB,
|
105
|
+
"action" => "TestActiveJob#perform",
|
106
|
+
"error" => nil,
|
107
|
+
"sample_data" => hash_including(
|
108
|
+
"params" => ["foo" => "Foo", "bar" => "#{"a" * 2000}..."],
|
109
|
+
"metadata" => {
|
110
|
+
"id" => kind_of(String),
|
111
|
+
"queue" => "default"
|
112
|
+
}
|
113
|
+
)
|
114
|
+
)
|
115
|
+
end
|
55
116
|
end
|
56
117
|
|
57
118
|
context "with parameter filtering" do
|
58
|
-
|
59
|
-
|
60
|
-
|
119
|
+
let(:args) do
|
120
|
+
{
|
121
|
+
:foo => "Foo",
|
122
|
+
:bar => "Bar"
|
123
|
+
}
|
61
124
|
end
|
125
|
+
before { Appsignal.config[:filter_parameters] = ["foo"] }
|
62
126
|
|
63
127
|
it "filters selected arguments" do
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
128
|
+
perform
|
129
|
+
expect(last_transaction.to_h).to include(
|
130
|
+
"namespace" => Appsignal::Transaction::BACKGROUND_JOB,
|
131
|
+
"action" => "TestActiveJob#perform",
|
132
|
+
"error" => nil,
|
133
|
+
"sample_data" => hash_including(
|
134
|
+
"params" => ["foo" => "[FILTERED]", "bar" => "Bar"],
|
135
|
+
"metadata" => {
|
136
|
+
"id" => kind_of(String),
|
137
|
+
"queue" => "default"
|
138
|
+
}
|
139
|
+
)
|
76
140
|
)
|
77
141
|
end
|
78
142
|
end
|
79
143
|
end
|
80
|
-
|
81
|
-
after { job.perform_now }
|
82
144
|
end
|
83
145
|
end
|
@@ -18,65 +18,66 @@ if DependencyHelper.resque_present?
|
|
18
18
|
extend Appsignal::Integrations::ResquePlugin
|
19
19
|
|
20
20
|
def self.perform
|
21
|
-
raise ExampleException
|
21
|
+
raise ExampleException, "my error message"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
describe :around_perform_resque_plugin do
|
27
|
-
let(:transaction) { Appsignal::Transaction.new("1", "background", {}, {}) }
|
28
27
|
let(:job) { ::Resque::Job.new("default", "class" => "TestJob") }
|
29
|
-
before
|
30
|
-
allow(transaction).to receive(:complete).and_return(true)
|
31
|
-
allow(Appsignal::Transaction).to receive(:current).and_return(transaction)
|
32
|
-
expect(Appsignal).to receive(:stop)
|
33
|
-
end
|
28
|
+
before { expect(Appsignal).to receive(:stop) }
|
34
29
|
|
35
30
|
context "without exception" do
|
36
31
|
it "creates a new transaction" do
|
37
|
-
expect
|
38
|
-
|
32
|
+
expect do
|
33
|
+
keep_transactions { job.perform }
|
34
|
+
end.to change { created_transactions.length }.by(1)
|
39
35
|
|
40
|
-
|
41
|
-
expect(
|
42
|
-
"
|
43
|
-
|
44
|
-
|
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
|
+
]
|
45
51
|
)
|
46
52
|
end
|
47
|
-
|
48
|
-
it "closes the transaction" do
|
49
|
-
expect(transaction).to receive(:complete)
|
50
|
-
end
|
51
|
-
|
52
|
-
after { job.perform }
|
53
53
|
end
|
54
54
|
|
55
55
|
context "with exception" do
|
56
56
|
let(:job) { ::Resque::Job.new("default", "class" => "BrokenTestJob") }
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
before do
|
65
|
-
allow(Appsignal::Transaction).to receive(:current).and_return(transaction)
|
66
|
-
expect(Appsignal::Transaction).to receive(:create)
|
67
|
-
.with(
|
68
|
-
kind_of(String),
|
69
|
-
Appsignal::Transaction::BACKGROUND_JOB,
|
70
|
-
kind_of(Appsignal::Transaction::GenericRequest)
|
71
|
-
).and_return(transaction)
|
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
|
72
64
|
end
|
73
65
|
|
74
66
|
it "sets the exception on the transaction" do
|
75
|
-
expect
|
76
|
-
|
67
|
+
expect do
|
68
|
+
perform
|
69
|
+
end.to change { created_transactions.length }.by(1)
|
77
70
|
|
78
|
-
|
79
|
-
expect
|
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
|
+
)
|
80
81
|
end
|
81
82
|
end
|
82
83
|
end
|
@@ -189,7 +189,7 @@ describe Appsignal::Minutely do
|
|
189
189
|
expect(Appsignal::Minutely).to have_received(:initial_wait_time).once
|
190
190
|
expect do
|
191
191
|
# Fetch old thread
|
192
|
-
thread = Appsignal::Minutely.
|
192
|
+
thread = Appsignal::Minutely.instance_variable_get(:@thread)
|
193
193
|
Appsignal::Minutely.start
|
194
194
|
thread && thread.join # Wait for old thread to exit
|
195
195
|
end.to_not(change { alive_thread_counter.call })
|
@@ -203,7 +203,7 @@ describe Appsignal::Minutely do
|
|
203
203
|
|
204
204
|
it "stops the minutely thread" do
|
205
205
|
Appsignal::Minutely.start
|
206
|
-
thread = Appsignal::Minutely.
|
206
|
+
thread = Appsignal::Minutely.instance_variable_get(:@thread)
|
207
207
|
expect(%w[sleep run]).to include(thread.status)
|
208
208
|
Appsignal::Minutely.stop
|
209
209
|
thread.join
|
@@ -213,7 +213,7 @@ describe Appsignal::Minutely do
|
|
213
213
|
it "clears the probe instances array" do
|
214
214
|
Appsignal::Minutely.probes.register :my_probe, lambda {}
|
215
215
|
Appsignal::Minutely.start
|
216
|
-
thread = Appsignal::Minutely.
|
216
|
+
thread = Appsignal::Minutely.instance_variable_get(:@thread)
|
217
217
|
wait_for("probes initialized") do
|
218
218
|
!Appsignal::Minutely.send(:probe_instances).empty?
|
219
219
|
end
|
@@ -3,19 +3,33 @@ describe Appsignal::Rack::JSExceptionCatcher do
|
|
3
3
|
let(:options) { nil }
|
4
4
|
let(:config_options) { { :enable_frontend_error_catching => true } }
|
5
5
|
let(:config) { project_fixture_config("production", config_options) }
|
6
|
+
let(:deprecation_message) do
|
7
|
+
"The Appsignal::Rack::JSExceptionCatcher is deprecated. " \
|
8
|
+
"Please use the official AppSignal JavaScript integration instead. " \
|
9
|
+
"https://docs.appsignal.com/front-end/"
|
10
|
+
end
|
6
11
|
before { Appsignal.config = config }
|
7
12
|
|
8
13
|
describe "#initialize" do
|
9
14
|
it "logs to the logger" do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
stdout = std_stream
|
16
|
+
stderr = std_stream
|
17
|
+
log = capture_logs do
|
18
|
+
capture_std_streams(stdout, stderr) do
|
19
|
+
Appsignal::Rack::JSExceptionCatcher.new(app, options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
expect(log).to contains_log(:warn, deprecation_message)
|
23
|
+
expect(log).to contains_log(:debug, "Initializing Appsignal::Rack::JSExceptionCatcher")
|
24
|
+
expect(stdout.read).to include "appsignal WARNING: #{deprecation_message}"
|
25
|
+
expect(stderr.read).to_not include("appsignal:")
|
14
26
|
end
|
15
27
|
end
|
16
28
|
|
17
29
|
describe "#call" do
|
18
|
-
let(:catcher)
|
30
|
+
let(:catcher) do
|
31
|
+
silence { Appsignal::Rack::JSExceptionCatcher.new(app, options) }
|
32
|
+
end
|
19
33
|
after { catcher.call(env) }
|
20
34
|
|
21
35
|
context "when path is not frontend_error_catching_path" do
|
@@ -64,7 +64,7 @@ describe Appsignal::Transaction do
|
|
64
64
|
|
65
65
|
it "logs a debug message" do
|
66
66
|
create_transaction("2")
|
67
|
-
expect(log_contents(log)).to contains_log :
|
67
|
+
expect(log_contents(log)).to contains_log :warn,
|
68
68
|
"Trying to start new transaction with id '2', but a " \
|
69
69
|
"transaction with id '#{transaction_id}' is already " \
|
70
70
|
"running. Using transaction '#{transaction_id}'."
|
@@ -154,13 +154,8 @@ describe Appsignal::Transaction do
|
|
154
154
|
describe "#complete" do
|
155
155
|
context "when transaction is being sampled" do
|
156
156
|
it "samples data" do
|
157
|
-
expect(transaction.ext).to receive(:finish).and_return(true)
|
158
|
-
# Stub call to extension, because that would remove the transaction
|
159
|
-
# from the extension.
|
160
|
-
expect(transaction.ext).to receive(:complete)
|
161
|
-
|
162
157
|
transaction.set_tags(:foo => "bar")
|
163
|
-
transaction.complete
|
158
|
+
keep_transactions { transaction.complete }
|
164
159
|
expect(transaction.to_h["sample_data"]).to include(
|
165
160
|
"tags" => { "foo" => "bar" }
|
166
161
|
)
|
@@ -169,11 +164,8 @@ describe Appsignal::Transaction do
|
|
169
164
|
|
170
165
|
context "when transaction is not being sampled" do
|
171
166
|
it "does not sample data" do
|
172
|
-
|
173
|
-
expect(transaction.
|
174
|
-
expect(transaction.ext).to receive(:complete).and_call_original
|
175
|
-
|
176
|
-
transaction.complete
|
167
|
+
keep_transactions(:sample => false) { transaction.complete }
|
168
|
+
expect(transaction.to_h["sample_data"]).to be_empty
|
177
169
|
end
|
178
170
|
end
|
179
171
|
|
data/spec/lib/appsignal_spec.rb
CHANGED
@@ -30,7 +30,7 @@ describe Appsignal do
|
|
30
30
|
context "with no config set beforehand" do
|
31
31
|
it "should do nothing when config is not set and there is no valid config in the env" do
|
32
32
|
expect(Appsignal.logger).to receive(:error).with(
|
33
|
-
"Push
|
33
|
+
"Push API key not set after loading config"
|
34
34
|
).once
|
35
35
|
expect(Appsignal.logger).to receive(:error).with(
|
36
36
|
"Not starting, no valid config for this environment"
|
@@ -701,13 +701,12 @@ describe Appsignal do
|
|
701
701
|
context "when given a block" do
|
702
702
|
it "yields the transaction and allows additional metadata to be set" do
|
703
703
|
captured_transaction = nil
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
expect(transaction).to receive(:complete)
|
704
|
+
keep_transactions do
|
705
|
+
Appsignal.send_error(StandardError.new("my_error")) do |transaction|
|
706
|
+
captured_transaction = transaction
|
707
|
+
transaction.set_action("my_action")
|
708
|
+
transaction.set_namespace("my_namespace")
|
709
|
+
end
|
711
710
|
end
|
712
711
|
expect(captured_transaction.to_h).to include(
|
713
712
|
"namespace" => "my_namespace",
|
data/spec/spec_helper.rb
CHANGED
@@ -31,16 +31,9 @@ if DependencyHelper.rails_present?
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
require "appsignal"
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
remove_method :testing?
|
38
|
-
|
39
|
-
def testing?
|
40
|
-
true
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
34
|
+
# Include patches of AppSignal modules and classes to make test helpers
|
35
|
+
# available.
|
36
|
+
require File.join(DirectoryHelper.support_dir, "testing.rb")
|
44
37
|
|
45
38
|
puts "Running specs in #{RUBY_VERSION} on #{RUBY_PLATFORM}\n\n"
|
46
39
|
|
@@ -72,6 +65,12 @@ RSpec.configure do |config|
|
|
72
65
|
|
73
66
|
config.example_status_persistence_file_path = "spec/examples.txt"
|
74
67
|
config.fail_if_no_examples = true
|
68
|
+
config.mock_with :rspec do |mocks|
|
69
|
+
mocks.syntax = :expect
|
70
|
+
end
|
71
|
+
config.expect_with :rspec do |expectations|
|
72
|
+
expectations.syntax = :expect
|
73
|
+
end
|
75
74
|
|
76
75
|
def spec_system_tmp_dir
|
77
76
|
File.join(tmp_dir, "system-tmp")
|
@@ -114,7 +113,8 @@ RSpec.configure do |config|
|
|
114
113
|
end
|
115
114
|
|
116
115
|
config.after do
|
117
|
-
|
116
|
+
Appsignal::Testing.clear!
|
117
|
+
clear_current_transaction!
|
118
118
|
stop_minutely_probes
|
119
119
|
end
|
120
120
|
|