appsignal 3.4.0-java → 3.4.2-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.
- checksums.yaml +4 -4
- data/.rubocop.yml +63 -21
- data/.rubocop_todo.yml +68 -54
- data/.semaphore/semaphore.yml +11 -11
- data/CHANGELOG.md +51 -0
- data/Rakefile +15 -99
- data/appsignal.gemspec +3 -4
- data/bin/appsignal +4 -2
- data/build_matrix.yml +4 -4
- data/ext/._appsignal-agent +0 -0
- data/ext/Rakefile +22 -21
- data/ext/agent.rb +29 -27
- data/ext/base.rb +14 -17
- data/ext/extconf.rb +4 -1
- data/lib/appsignal/auth_check.rb +3 -3
- data/lib/appsignal/capistrano.rb +1 -1
- data/lib/appsignal/cli/demo.rb +5 -2
- data/lib/appsignal/cli/diagnose/paths.rb +4 -1
- data/lib/appsignal/cli/diagnose/utils.rb +7 -3
- data/lib/appsignal/cli/diagnose.rb +7 -5
- data/lib/appsignal/cli/helpers.rb +1 -4
- data/lib/appsignal/cli/install.rb +4 -10
- data/lib/appsignal/cli.rb +3 -2
- data/lib/appsignal/config.rb +106 -103
- data/lib/appsignal/demo.rb +2 -1
- data/lib/appsignal/environment.rb +2 -0
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +2 -1
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +13 -13
- data/lib/appsignal/event_formatter.rb +5 -4
- data/lib/appsignal/extension/jruby.rb +11 -9
- data/lib/appsignal/extension.rb +1 -1
- data/lib/appsignal/helpers/instrumentation.rb +50 -35
- data/lib/appsignal/hooks/action_cable.rb +6 -4
- data/lib/appsignal/hooks/action_mailer.rb +2 -0
- data/lib/appsignal/hooks/active_job.rb +11 -10
- data/lib/appsignal/hooks/active_support_notifications.rb +3 -4
- data/lib/appsignal/hooks/data_mapper.rb +1 -1
- data/lib/appsignal/hooks/gvl.rb +3 -0
- data/lib/appsignal/hooks/http.rb +1 -1
- data/lib/appsignal/hooks/mri.rb +2 -0
- data/lib/appsignal/hooks/net_http.rb +1 -1
- data/lib/appsignal/hooks/que.rb +1 -1
- data/lib/appsignal/hooks/rake.rb +1 -1
- data/lib/appsignal/hooks/redis.rb +1 -1
- data/lib/appsignal/hooks/resque.rb +1 -1
- data/lib/appsignal/hooks/shoryuken.rb +2 -4
- data/lib/appsignal/hooks/sidekiq.rb +1 -1
- data/lib/appsignal/hooks/unicorn.rb +2 -2
- data/lib/appsignal/hooks/webmachine.rb +1 -1
- data/lib/appsignal/hooks.rb +2 -2
- data/lib/appsignal/integrations/active_support_notifications.rb +1 -1
- data/lib/appsignal/integrations/capistrano/appsignal.cap +6 -3
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +5 -4
- data/lib/appsignal/integrations/delayed_job_plugin.rb +3 -5
- data/lib/appsignal/integrations/grape.rb +1 -1
- data/lib/appsignal/integrations/hanami.rb +1 -1
- data/lib/appsignal/integrations/object.rb +2 -3
- data/lib/appsignal/integrations/padrino.rb +2 -4
- data/lib/appsignal/integrations/que.rb +6 -6
- data/lib/appsignal/integrations/railtie.rb +76 -0
- data/lib/appsignal/integrations/sidekiq.rb +9 -11
- data/lib/appsignal/integrations/sinatra.rb +1 -3
- data/lib/appsignal/integrations/webmachine.rb +4 -6
- data/lib/appsignal/logger.rb +31 -6
- data/lib/appsignal/marker.rb +4 -5
- data/lib/appsignal/minutely.rb +7 -7
- data/lib/appsignal/probes/gvl.rb +9 -4
- data/lib/appsignal/probes/helpers.rb +4 -6
- data/lib/appsignal/probes/mri.rb +7 -5
- data/lib/appsignal/probes/sidekiq.rb +3 -0
- data/lib/appsignal/probes.rb +2 -0
- data/lib/appsignal/rack/generic_instrumentation.rb +1 -5
- data/lib/appsignal/rack/sinatra_instrumentation.rb +3 -5
- data/lib/appsignal/rack/streaming_listener.rb +11 -13
- data/lib/appsignal/span.rb +5 -5
- data/lib/appsignal/system.rb +10 -11
- data/lib/appsignal/transaction.rb +49 -25
- data/lib/appsignal/transmitter.rb +4 -2
- data/lib/appsignal/utils/deprecation_message.rb +2 -0
- data/lib/appsignal/utils/hash_sanitizer.rb +1 -1
- data/lib/appsignal/utils/integration_logger.rb +5 -3
- data/lib/appsignal/utils/json.rb +1 -1
- data/lib/appsignal/utils/query_params_sanitizer.rb +1 -1
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +5 -4
- data/lib/puma/plugin/appsignal.rb +16 -18
- data/script/lint_git +1 -1
- data/spec/lib/appsignal/capistrano2_spec.rb +6 -3
- data/spec/lib/appsignal/capistrano3_spec.rb +6 -3
- data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +1 -3
- data/spec/lib/appsignal/cli/diagnose_spec.rb +33 -30
- data/spec/lib/appsignal/cli/install_spec.rb +5 -6
- data/spec/lib/appsignal/cli_spec.rb +1 -1
- data/spec/lib/appsignal/config_spec.rb +43 -37
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +11 -5
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +4 -4
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +1 -4
- data/spec/lib/appsignal/event_formatter_spec.rb +11 -9
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +5 -2
- data/spec/lib/appsignal/hooks/action_mailer_spec.rb +2 -1
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +1 -1
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +1 -1
- data/spec/lib/appsignal/hooks/activejob_spec.rb +21 -12
- data/spec/lib/appsignal/hooks/data_mapper_spec.rb +1 -0
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +12 -12
- data/spec/lib/appsignal/hooks/excon_spec.rb +2 -2
- data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +3 -1
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +4 -2
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +2 -1
- data/spec/lib/appsignal/hooks_spec.rb +5 -4
- data/spec/lib/appsignal/integrations/grape_spec.rb +8 -4
- data/spec/lib/appsignal/integrations/hanami_spec.rb +16 -8
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +2 -4
- data/spec/lib/appsignal/integrations/object_spec.rb +6 -1
- data/spec/lib/appsignal/integrations/padrino_spec.rb +4 -2
- data/spec/lib/appsignal/integrations/railtie_spec.rb +213 -6
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +54 -41
- data/spec/lib/appsignal/logger_spec.rb +20 -4
- data/spec/lib/appsignal/marker_spec.rb +2 -2
- data/spec/lib/appsignal/minutely_spec.rb +3 -3
- data/spec/lib/appsignal/probes/gvl_spec.rb +60 -12
- data/spec/lib/appsignal/probes/mri_spec.rb +7 -4
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +2 -1
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +2 -1
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +10 -5
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +7 -5
- data/spec/lib/appsignal/transaction_spec.rb +20 -13
- data/spec/lib/appsignal/utils/data_spec.rb +10 -1
- data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +11 -11
- data/spec/lib/appsignal/utils/json_spec.rb +4 -2
- data/spec/lib/appsignal_spec.rb +49 -35
- data/spec/lib/puma/appsignal_spec.rb +9 -11
- data/spec/spec_helper.rb +14 -2
- data/spec/support/fixtures/projects/valid/config/appsignal.yml +1 -1
- data/spec/support/helpers/config_helpers.rb +2 -1
- data/spec/support/helpers/dependency_helper.rb +1 -9
- data/spec/support/helpers/std_streams_helper.rb +1 -3
- data/spec/support/helpers/wait_for_helper.rb +2 -3
- data/spec/support/mocks/appsignal_mock.rb +1 -1
- data/spec/support/mocks/fake_gvl_tools.rb +2 -10
- data/spec/support/testing.rb +4 -3
- metadata +9 -135
|
@@ -4,36 +4,84 @@ describe Appsignal::Probes::GvlProbe do
|
|
|
4
4
|
|
|
5
5
|
let(:hostname) { "some-host" }
|
|
6
6
|
|
|
7
|
+
def gauges_for(metric)
|
|
8
|
+
gauges = appsignal_mock.gauges.select do |gauge|
|
|
9
|
+
gauge[0] == metric
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
gauges.map do |gauge|
|
|
13
|
+
gauge.drop(1)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
7
17
|
after(:each) { FakeGVLTools.reset }
|
|
8
18
|
|
|
9
|
-
|
|
10
|
-
|
|
19
|
+
it "gauges the global timer delta" do
|
|
20
|
+
FakeGVLTools::GlobalTimer.monotonic_time = 100_000_000
|
|
21
|
+
probe.call
|
|
22
|
+
|
|
23
|
+
expect(gauges_for("gvl_global_timer")).to be_empty
|
|
24
|
+
|
|
25
|
+
FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
|
|
26
|
+
probe.call
|
|
11
27
|
|
|
12
|
-
|
|
13
|
-
|
|
28
|
+
expect(gauges_for("gvl_global_timer")).to eq [
|
|
29
|
+
[200, { :hostname => hostname }]
|
|
30
|
+
]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "when the delta is negative" do
|
|
34
|
+
it "does not gauge the global timer delta" do
|
|
35
|
+
FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
|
|
14
36
|
probe.call
|
|
15
37
|
|
|
16
|
-
expect(
|
|
38
|
+
expect(gauges_for("gvl_global_timer")).to be_empty
|
|
39
|
+
|
|
40
|
+
FakeGVLTools::GlobalTimer.monotonic_time = 0
|
|
41
|
+
probe.call
|
|
42
|
+
|
|
43
|
+
expect(gauges_for("gvl_global_timer")).to be_empty
|
|
44
|
+
end
|
|
45
|
+
end
|
|
17
46
|
|
|
47
|
+
context "when the delta is zero" do
|
|
48
|
+
it "does not gauge the global timer delta" do
|
|
18
49
|
FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
|
|
19
50
|
probe.call
|
|
20
51
|
|
|
21
|
-
expect(
|
|
22
|
-
|
|
23
|
-
|
|
52
|
+
expect(gauges_for("gvl_global_timer")).to be_empty
|
|
53
|
+
|
|
54
|
+
probe.call
|
|
55
|
+
|
|
56
|
+
expect(gauges_for("gvl_global_timer")).to be_empty
|
|
24
57
|
end
|
|
25
58
|
end
|
|
26
59
|
|
|
27
|
-
context "
|
|
28
|
-
before(:each)
|
|
60
|
+
context "when the waiting threads count is enabled" do
|
|
61
|
+
before(:each) do
|
|
62
|
+
FakeGVLTools::WaitingThreads.enabled = true
|
|
63
|
+
end
|
|
29
64
|
|
|
30
65
|
it "gauges the waiting threads count" do
|
|
31
66
|
FakeGVLTools::WaitingThreads.count = 3
|
|
32
67
|
probe.call
|
|
33
68
|
|
|
34
|
-
expect(
|
|
35
|
-
[
|
|
69
|
+
expect(gauges_for("gvl_waiting_threads")).to eq [
|
|
70
|
+
[3, { :hostname => hostname }]
|
|
36
71
|
]
|
|
37
72
|
end
|
|
38
73
|
end
|
|
74
|
+
|
|
75
|
+
context "when the waiting threads count is disabled" do
|
|
76
|
+
before(:each) do
|
|
77
|
+
FakeGVLTools::WaitingThreads.enabled = false
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "does not gauge the waiting threads count" do
|
|
81
|
+
FakeGVLTools::WaitingThreads.count = 3
|
|
82
|
+
probe.call
|
|
83
|
+
|
|
84
|
+
expect(gauges_for("gvl_waiting_threads")).to be_empty
|
|
85
|
+
end
|
|
86
|
+
end
|
|
39
87
|
end
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
describe Appsignal::Probes::MriProbe do
|
|
2
2
|
let(:appsignal_mock) { AppsignalMock.new(:hostname => hostname) }
|
|
3
3
|
let(:gc_profiler_mock) { instance_double("Appsignal::GarbageCollectionProfiler") }
|
|
4
|
-
let(:probe)
|
|
4
|
+
let(:probe) do
|
|
5
|
+
described_class.new(:appsignal => appsignal_mock, :gc_profiler => gc_profiler_mock)
|
|
6
|
+
end
|
|
5
7
|
|
|
6
8
|
describe ".dependencies_present?" do
|
|
7
|
-
if DependencyHelper.running_jruby?
|
|
9
|
+
if DependencyHelper.running_jruby?
|
|
8
10
|
it "should not be present" do
|
|
9
11
|
expect(described_class.dependencies_present?).to be_falsy
|
|
10
12
|
end
|
|
@@ -15,7 +17,7 @@ describe Appsignal::Probes::MriProbe do
|
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
|
|
18
|
-
unless DependencyHelper.running_jruby?
|
|
20
|
+
unless DependencyHelper.running_jruby?
|
|
19
21
|
describe "#call" do
|
|
20
22
|
let(:hostname) { nil }
|
|
21
23
|
before do
|
|
@@ -126,7 +128,8 @@ describe Appsignal::Probes::MriProbe do
|
|
|
126
128
|
|
|
127
129
|
it "reports custom hostname tag value" do
|
|
128
130
|
probe.call
|
|
129
|
-
expect_gauge_value("heap_slots",
|
|
131
|
+
expect_gauge_value("heap_slots",
|
|
132
|
+
:tags => { :metric => :heap_live, :hostname => hostname })
|
|
130
133
|
end
|
|
131
134
|
end
|
|
132
135
|
end
|
|
@@ -42,7 +42,8 @@ describe Appsignal::Rack::GenericInstrumentation do
|
|
|
42
42
|
kind_of(String),
|
|
43
43
|
Appsignal::Transaction::HTTP_REQUEST,
|
|
44
44
|
kind_of(Rack::Request)
|
|
45
|
-
).and_return(double(:set_action_if_nil => nil, :set_http_or_background_queue_start => nil,
|
|
45
|
+
).and_return(double(:set_action_if_nil => nil, :set_http_or_background_queue_start => nil,
|
|
46
|
+
:set_metadata => nil))
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
it "should call the app" do
|
|
@@ -113,7 +113,8 @@ if DependencyHelper.rails_present?
|
|
|
113
113
|
|
|
114
114
|
transaction_hash = last_transaction.to_h
|
|
115
115
|
expect(transaction_hash["metadata"]).to_not have_key("method")
|
|
116
|
-
expect(log_contents(log)).to contains_log(:error,
|
|
116
|
+
expect(log_contents(log)).to contains_log(:error,
|
|
117
|
+
"Unable to report HTTP request method: '")
|
|
117
118
|
end
|
|
118
119
|
end
|
|
119
120
|
|
|
@@ -110,7 +110,8 @@ if DependencyHelper.sinatra_present?
|
|
|
110
110
|
Appsignal::Transaction::HTTP_REQUEST,
|
|
111
111
|
kind_of(Sinatra::Request),
|
|
112
112
|
kind_of(Hash)
|
|
113
|
-
).and_return(double(:set_action_if_nil => nil, :set_http_or_background_queue_start => nil,
|
|
113
|
+
).and_return(double(:set_action_if_nil => nil, :set_http_or_background_queue_start => nil,
|
|
114
|
+
:set_metadata => nil))
|
|
114
115
|
end
|
|
115
116
|
|
|
116
117
|
it "should call the app" do
|
|
@@ -158,7 +159,8 @@ if DependencyHelper.sinatra_present?
|
|
|
158
159
|
|
|
159
160
|
describe "action name" do
|
|
160
161
|
it "should set the action" do
|
|
161
|
-
expect_any_instance_of(Appsignal::Transaction)
|
|
162
|
+
expect_any_instance_of(Appsignal::Transaction)
|
|
163
|
+
.to receive(:set_action_if_nil).with("GET /")
|
|
162
164
|
end
|
|
163
165
|
|
|
164
166
|
context "without 'sinatra.route' env" do
|
|
@@ -173,14 +175,16 @@ if DependencyHelper.sinatra_present?
|
|
|
173
175
|
before { env["SCRIPT_NAME"] = "/api" }
|
|
174
176
|
|
|
175
177
|
it "should call set_action with an application prefix path" do
|
|
176
|
-
expect_any_instance_of(Appsignal::Transaction)
|
|
178
|
+
expect_any_instance_of(Appsignal::Transaction)
|
|
179
|
+
.to receive(:set_action_if_nil).with("GET /api/")
|
|
177
180
|
end
|
|
178
181
|
|
|
179
182
|
context "without 'sinatra.route' env" do
|
|
180
183
|
let(:env) { { :path => "/", :method => "GET" } }
|
|
181
184
|
|
|
182
185
|
it "returns nil" do
|
|
183
|
-
expect_any_instance_of(Appsignal::Transaction)
|
|
186
|
+
expect_any_instance_of(Appsignal::Transaction)
|
|
187
|
+
.to receive(:set_action_if_nil).with(nil)
|
|
184
188
|
end
|
|
185
189
|
end
|
|
186
190
|
end
|
|
@@ -191,7 +195,8 @@ if DependencyHelper.sinatra_present?
|
|
|
191
195
|
end
|
|
192
196
|
|
|
193
197
|
it "should set the queue start" do
|
|
194
|
-
expect_any_instance_of(Appsignal::Transaction)
|
|
198
|
+
expect_any_instance_of(Appsignal::Transaction)
|
|
199
|
+
.to receive(:set_http_or_background_queue_start)
|
|
195
200
|
end
|
|
196
201
|
|
|
197
202
|
context "with overridden request class and params method" do
|
|
@@ -4,10 +4,10 @@ describe Appsignal::Rack::StreamingListener do
|
|
|
4
4
|
let(:headers) { {} }
|
|
5
5
|
let(:env) do
|
|
6
6
|
{
|
|
7
|
-
"rack.input"
|
|
7
|
+
"rack.input" => StringIO.new,
|
|
8
8
|
"REQUEST_METHOD" => "GET",
|
|
9
|
-
"PATH_INFO"
|
|
10
|
-
"QUERY_STRING"
|
|
9
|
+
"PATH_INFO" => "/homepage",
|
|
10
|
+
"QUERY_STRING" => "param=something"
|
|
11
11
|
}
|
|
12
12
|
end
|
|
13
13
|
let(:app) { double(:call => [200, headers, "body"]) }
|
|
@@ -114,8 +114,10 @@ end
|
|
|
114
114
|
|
|
115
115
|
describe Appsignal::StreamWrapper do
|
|
116
116
|
let(:stream) { double }
|
|
117
|
-
let(:transaction)
|
|
118
|
-
|
|
117
|
+
let(:transaction) do
|
|
118
|
+
Appsignal::Transaction.create(SecureRandom.uuid, Appsignal::Transaction::HTTP_REQUEST, {})
|
|
119
|
+
end
|
|
120
|
+
let(:wrapper) { Appsignal::StreamWrapper.new(stream, transaction) }
|
|
119
121
|
|
|
120
122
|
describe "#each" do
|
|
121
123
|
it "calls the original stream" do
|
|
@@ -66,8 +66,8 @@ describe Appsignal::Transaction do
|
|
|
66
66
|
create_transaction("2")
|
|
67
67
|
expect(log_contents(log)).to contains_log :warn,
|
|
68
68
|
"Trying to start new transaction with id '2', but a " \
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
"transaction with id '#{transaction_id}' is already " \
|
|
70
|
+
"running. Using transaction '#{transaction_id}'."
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
context "with option :force => true" do
|
|
@@ -741,7 +741,7 @@ describe Appsignal::Transaction do
|
|
|
741
741
|
it "does not add the error" do
|
|
742
742
|
expect(Appsignal.logger).to receive(:error).with(
|
|
743
743
|
"Appsignal::Transaction#set_error: Cannot set error. " \
|
|
744
|
-
|
|
744
|
+
"The given value is not an exception: #{error.inspect}"
|
|
745
745
|
)
|
|
746
746
|
expect(transaction.ext).to_not receive(:set_error)
|
|
747
747
|
|
|
@@ -1083,7 +1083,9 @@ describe Appsignal::Transaction do
|
|
|
1083
1083
|
|
|
1084
1084
|
context "with an array" do
|
|
1085
1085
|
let(:request) do
|
|
1086
|
-
Appsignal::Transaction::GenericRequest.new(
|
|
1086
|
+
Appsignal::Transaction::GenericRequest.new(
|
|
1087
|
+
background_env_with_data(:params => %w[arg1 arg2])
|
|
1088
|
+
)
|
|
1087
1089
|
end
|
|
1088
1090
|
|
|
1089
1091
|
it { is_expected.to eq %w[arg1 arg2] }
|
|
@@ -1099,8 +1101,9 @@ describe Appsignal::Transaction do
|
|
|
1099
1101
|
context "with env" do
|
|
1100
1102
|
context "with sanitization" do
|
|
1101
1103
|
let(:request) do
|
|
1102
|
-
Appsignal::Transaction::GenericRequest.new
|
|
1104
|
+
Appsignal::Transaction::GenericRequest.new(
|
|
1103
1105
|
http_request_env_with_data(:params => { :foo => :bar })
|
|
1106
|
+
)
|
|
1104
1107
|
end
|
|
1105
1108
|
|
|
1106
1109
|
it "should call the params sanitizer" do
|
|
@@ -1110,8 +1113,9 @@ describe Appsignal::Transaction do
|
|
|
1110
1113
|
|
|
1111
1114
|
context "with AppSignal filtering" do
|
|
1112
1115
|
let(:request) do
|
|
1113
|
-
Appsignal::Transaction::GenericRequest.new
|
|
1116
|
+
Appsignal::Transaction::GenericRequest.new(
|
|
1114
1117
|
http_request_env_with_data(:params => { :foo => :bar, :baz => :bat })
|
|
1118
|
+
)
|
|
1115
1119
|
end
|
|
1116
1120
|
before { Appsignal.config.config_hash[:filter_parameters] = %w[foo] }
|
|
1117
1121
|
after { Appsignal.config.config_hash[:filter_parameters] = [] }
|
|
@@ -1233,7 +1237,8 @@ describe Appsignal::Transaction do
|
|
|
1233
1237
|
true
|
|
1234
1238
|
end
|
|
1235
1239
|
end.new
|
|
1236
|
-
ActionDispatch::Request::Session.create(store,
|
|
1240
|
+
ActionDispatch::Request::Session.create(store,
|
|
1241
|
+
ActionDispatch::Request.new("rack.input" => StringIO.new), {})
|
|
1237
1242
|
end
|
|
1238
1243
|
before do
|
|
1239
1244
|
expect(transaction).to respond_to(:request)
|
|
@@ -1334,12 +1339,14 @@ describe Appsignal::Transaction do
|
|
|
1334
1339
|
|
|
1335
1340
|
let(:error) do
|
|
1336
1341
|
PG::UniqueViolation.new(
|
|
1337
|
-
"ERROR: duplicate key value violates unique constraint
|
|
1342
|
+
"ERROR: duplicate key value violates unique constraint " \
|
|
1343
|
+
"\"index_users_on_email\" DETAIL: Key (email)=(test@test.com) already exists."
|
|
1338
1344
|
)
|
|
1339
1345
|
end
|
|
1340
1346
|
|
|
1341
1347
|
it "returns a sanizited error message" do
|
|
1342
|
-
expect(subject).to eq "ERROR: duplicate key value violates unique constraint
|
|
1348
|
+
expect(subject).to eq "ERROR: duplicate key value violates unique constraint " \
|
|
1349
|
+
"\"index_users_on_email\" DETAIL: Key (email)=(?) already exists."
|
|
1343
1350
|
end
|
|
1344
1351
|
end
|
|
1345
1352
|
|
|
@@ -1350,15 +1357,15 @@ describe Appsignal::Transaction do
|
|
|
1350
1357
|
|
|
1351
1358
|
let(:error) do
|
|
1352
1359
|
ActiveRecord::RecordNotUnique.new(
|
|
1353
|
-
"PG::UniqueViolation: ERROR: duplicate key value violates unique constraint
|
|
1354
|
-
|
|
1360
|
+
"PG::UniqueViolation: ERROR: duplicate key value violates unique constraint " \
|
|
1361
|
+
"\"example_constraint\"\nDETAIL: Key (email)=(foo@example.com) already exists."
|
|
1355
1362
|
)
|
|
1356
1363
|
end
|
|
1357
1364
|
|
|
1358
1365
|
it "returns a sanizited error message" do
|
|
1359
1366
|
expect(subject).to eq \
|
|
1360
|
-
"PG::UniqueViolation: ERROR: duplicate key value violates unique constraint
|
|
1361
|
-
|
|
1367
|
+
"PG::UniqueViolation: ERROR: duplicate key value violates unique constraint " \
|
|
1368
|
+
"\"example_constraint\"\nDETAIL: Key (email)=(?) already exists."
|
|
1362
1369
|
end
|
|
1363
1370
|
end
|
|
1364
1371
|
end
|
|
@@ -47,6 +47,7 @@ describe Appsignal::Utils::Data do
|
|
|
47
47
|
|
|
48
48
|
describe "#to_s" do
|
|
49
49
|
it "returns a serialized hash" do
|
|
50
|
+
# rubocop:disable Style/StringConcatenation
|
|
50
51
|
expect(subject.to_s).to eq %({"":"test",) +
|
|
51
52
|
%("1":true,) +
|
|
52
53
|
%("bar":null,) +
|
|
@@ -59,6 +60,7 @@ describe Appsignal::Utils::Data do
|
|
|
59
60
|
%("int63":"bigint:#{1 << 63}",) +
|
|
60
61
|
%("int64":"bigint:#{1 << 64}",) +
|
|
61
62
|
%("the":"payload"})
|
|
63
|
+
# rubocop:enable Style/StringConcatenation
|
|
62
64
|
end
|
|
63
65
|
end
|
|
64
66
|
end
|
|
@@ -73,6 +75,7 @@ describe Appsignal::Utils::Data do
|
|
|
73
75
|
|
|
74
76
|
describe "#to_s" do
|
|
75
77
|
it "returns a serialized array" do
|
|
78
|
+
# rubocop:disable Style/StringConcatenation, Style/RedundantStringEscape
|
|
76
79
|
expect(subject.to_s).to eq %([null,) +
|
|
77
80
|
%(true,) +
|
|
78
81
|
%(false,) +
|
|
@@ -84,6 +87,7 @@ describe Appsignal::Utils::Data do
|
|
|
84
87
|
%("bigint:#{1 << 63}",) +
|
|
85
88
|
%("bigint:#{1 << 64}",) +
|
|
86
89
|
%({\"arr\":[1,2,\"three\"],\"foo\":\"bʊr\"}])
|
|
90
|
+
# rubocop:enable Style/StringConcatenation, Style/RedundantStringEscape
|
|
87
91
|
end
|
|
88
92
|
end
|
|
89
93
|
end
|
|
@@ -105,7 +109,12 @@ describe Appsignal::Utils::Data do
|
|
|
105
109
|
|
|
106
110
|
describe "#to_s" do
|
|
107
111
|
it "returns a JSON representation in a String" do
|
|
108
|
-
|
|
112
|
+
# rubocop:disable Style/StringConcatenation
|
|
113
|
+
expect(subject.to_s).to eq %({"field_four":{"one":"aa�"},) +
|
|
114
|
+
%("field_one":"aa",) +
|
|
115
|
+
%("field_three":["one","aa�"],) +
|
|
116
|
+
%("field_two":"aa�"})
|
|
117
|
+
# rubocop:enable Style/StringConcatenation
|
|
109
118
|
end
|
|
110
119
|
end
|
|
111
120
|
end
|
|
@@ -2,23 +2,23 @@ describe Appsignal::Utils::HashSanitizer do
|
|
|
2
2
|
let(:file) { uploaded_file }
|
|
3
3
|
let(:params) do
|
|
4
4
|
{
|
|
5
|
-
:text
|
|
6
|
-
"string"
|
|
7
|
-
:file
|
|
8
|
-
:float
|
|
9
|
-
:bool_true
|
|
5
|
+
:text => "string",
|
|
6
|
+
"string" => "string key value",
|
|
7
|
+
:file => file,
|
|
8
|
+
:float => 0.0,
|
|
9
|
+
:bool_true => true,
|
|
10
10
|
:bool_false => false,
|
|
11
|
-
:nil
|
|
12
|
-
:int
|
|
13
|
-
:int64
|
|
14
|
-
:hash
|
|
15
|
-
:nested_text
|
|
11
|
+
:nil => nil,
|
|
12
|
+
:int => 1, # Fixnum
|
|
13
|
+
:int64 => 1 << 64, # Bignum
|
|
14
|
+
:hash => {
|
|
15
|
+
:nested_text => "string",
|
|
16
16
|
:nested_array => [
|
|
17
17
|
"something",
|
|
18
18
|
"else",
|
|
19
19
|
file,
|
|
20
20
|
{
|
|
21
|
-
:key
|
|
21
|
+
:key => "value",
|
|
22
22
|
:file => file
|
|
23
23
|
}
|
|
24
24
|
]
|
|
@@ -15,7 +15,8 @@ describe Appsignal::Utils::JSON do
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
it "returns a JSON string" do
|
|
18
|
-
is_expected.to eq %({"the":"payload","1":true,"":"test",
|
|
18
|
+
is_expected.to eq %({"the":"payload","1":true,"":"test",) +
|
|
19
|
+
%("foo":[1,2,"three"],"bar":null,"baz":{"foo":"bar"}})
|
|
19
20
|
end
|
|
20
21
|
end
|
|
21
22
|
|
|
@@ -35,7 +36,8 @@ describe Appsignal::Utils::JSON do
|
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
it "returns a JSON string with invalid UTF-8 content" do
|
|
38
|
-
is_expected.to eq %({"field_one":"aa","field_two":"aa�",
|
|
39
|
+
is_expected.to eq %({"field_one":"aa","field_two":"aa�",) +
|
|
40
|
+
%("field_three":["one","aa�"],"field_four":{"one":"aa�"}})
|
|
39
41
|
end
|
|
40
42
|
end
|
|
41
43
|
end
|
data/spec/lib/appsignal_spec.rb
CHANGED
|
@@ -22,12 +22,10 @@ describe Appsignal do
|
|
|
22
22
|
describe ".start" do
|
|
23
23
|
context "with no config set beforehand" do
|
|
24
24
|
it "should do nothing when config is not set and there is no valid config in the env" do
|
|
25
|
-
expect(Appsignal.logger).to receive(:error)
|
|
26
|
-
"Push API key not set after loading config"
|
|
27
|
-
).
|
|
28
|
-
|
|
29
|
-
"Not starting, no valid config for this environment"
|
|
30
|
-
).once
|
|
25
|
+
expect(Appsignal.logger).to receive(:error)
|
|
26
|
+
.with("Push API key not set after loading config").once
|
|
27
|
+
expect(Appsignal.logger).to receive(:error)
|
|
28
|
+
.with("Not starting, no valid config for this environment").once
|
|
31
29
|
expect(Appsignal::Extension).to_not receive(:start)
|
|
32
30
|
Appsignal.start
|
|
33
31
|
end
|
|
@@ -249,7 +247,7 @@ describe Appsignal do
|
|
|
249
247
|
end
|
|
250
248
|
|
|
251
249
|
it "logs an error" do
|
|
252
|
-
Appsignal.monitor_transaction("unknown.sidekiq") {}
|
|
250
|
+
Appsignal.monitor_transaction("unknown.sidekiq") {} # rubocop:disable Lint/EmptyBlock
|
|
253
251
|
expect(log).to contains_log(
|
|
254
252
|
:error,
|
|
255
253
|
"Unrecognized name 'unknown.sidekiq': names must start with either 'perform_job' " \
|
|
@@ -317,9 +315,8 @@ describe Appsignal do
|
|
|
317
315
|
describe ".monitor_transaction" do
|
|
318
316
|
context "with a successful call" do
|
|
319
317
|
it "should instrument and complete for a background job" do
|
|
320
|
-
expect(Appsignal).to receive(:instrument)
|
|
321
|
-
"perform_job.something"
|
|
322
|
-
).and_yield
|
|
318
|
+
expect(Appsignal).to receive(:instrument)
|
|
319
|
+
.with("perform_job.something").and_yield
|
|
323
320
|
expect(Appsignal::Transaction).to receive(:complete_current!)
|
|
324
321
|
object = double
|
|
325
322
|
expect(object).to receive(:some_method).and_return(1)
|
|
@@ -336,9 +333,8 @@ describe Appsignal do
|
|
|
336
333
|
end
|
|
337
334
|
|
|
338
335
|
it "should instrument and complete for a http request" do
|
|
339
|
-
expect(Appsignal).to receive(:instrument)
|
|
340
|
-
"process_action.something"
|
|
341
|
-
).and_yield
|
|
336
|
+
expect(Appsignal).to receive(:instrument)
|
|
337
|
+
.with("process_action.something").and_yield
|
|
342
338
|
expect(Appsignal::Transaction).to receive(:complete_current!)
|
|
343
339
|
object = double
|
|
344
340
|
expect(object).to receive(:some_method)
|
|
@@ -378,7 +374,7 @@ describe Appsignal do
|
|
|
378
374
|
end
|
|
379
375
|
|
|
380
376
|
it "logs an error" do
|
|
381
|
-
Appsignal.monitor_transaction("unknown.sidekiq") {}
|
|
377
|
+
Appsignal.monitor_transaction("unknown.sidekiq") {} # rubocop:disable Lint/EmptyBlock
|
|
382
378
|
expect(log).to contains_log(
|
|
383
379
|
:error,
|
|
384
380
|
"Unrecognized name 'unknown.sidekiq': names must start with either 'perform_job' " \
|
|
@@ -529,7 +525,8 @@ describe Appsignal do
|
|
|
529
525
|
|
|
530
526
|
describe ".set_gauge" do
|
|
531
527
|
it "should call set_gauge on the extension with a string key and float" do
|
|
532
|
-
expect(Appsignal::Extension).to receive(:set_gauge)
|
|
528
|
+
expect(Appsignal::Extension).to receive(:set_gauge)
|
|
529
|
+
.with("key", 0.1, Appsignal::Extension.data_map_new)
|
|
533
530
|
Appsignal.set_gauge("key", 0.1)
|
|
534
531
|
end
|
|
535
532
|
|
|
@@ -540,12 +537,14 @@ describe Appsignal do
|
|
|
540
537
|
end
|
|
541
538
|
|
|
542
539
|
it "should call set_gauge on the extension with a symbol key and int" do
|
|
543
|
-
expect(Appsignal::Extension).to receive(:set_gauge)
|
|
540
|
+
expect(Appsignal::Extension).to receive(:set_gauge)
|
|
541
|
+
.with("key", 1.0, Appsignal::Extension.data_map_new)
|
|
544
542
|
Appsignal.set_gauge(:key, 1)
|
|
545
543
|
end
|
|
546
544
|
|
|
547
545
|
it "should not raise an exception when out of range" do
|
|
548
|
-
expect(Appsignal::Extension).to receive(:set_gauge).with("key", 10,
|
|
546
|
+
expect(Appsignal::Extension).to receive(:set_gauge).with("key", 10,
|
|
547
|
+
Appsignal::Extension.data_map_new).and_raise(RangeError)
|
|
549
548
|
expect(Appsignal.logger).to receive(:warn).with("Gauge value 10 for key 'key' is too big")
|
|
550
549
|
expect do
|
|
551
550
|
Appsignal.set_gauge("key", 10)
|
|
@@ -565,8 +564,10 @@ describe Appsignal do
|
|
|
565
564
|
end
|
|
566
565
|
|
|
567
566
|
it "should not raise an exception when out of range" do
|
|
568
|
-
expect(Appsignal::Extension).to receive(:set_host_gauge).with("key",
|
|
569
|
-
|
|
567
|
+
expect(Appsignal::Extension).to receive(:set_host_gauge).with("key",
|
|
568
|
+
10).and_raise(RangeError)
|
|
569
|
+
expect(Appsignal.logger).to receive(:warn)
|
|
570
|
+
.with("Host gauge value 10 for key 'key' is too big")
|
|
570
571
|
expect do
|
|
571
572
|
Appsignal.set_host_gauge("key", 10)
|
|
572
573
|
end.to_not raise_error
|
|
@@ -585,8 +586,10 @@ describe Appsignal do
|
|
|
585
586
|
end
|
|
586
587
|
|
|
587
588
|
it "should not raise an exception when out of range" do
|
|
588
|
-
expect(Appsignal::Extension).to receive(:set_process_gauge).with("key",
|
|
589
|
-
|
|
589
|
+
expect(Appsignal::Extension).to receive(:set_process_gauge).with("key",
|
|
590
|
+
10).and_raise(RangeError)
|
|
591
|
+
expect(Appsignal.logger).to receive(:warn)
|
|
592
|
+
.with("Process gauge value 10 for key 'key' is too big")
|
|
590
593
|
expect do
|
|
591
594
|
Appsignal.set_process_gauge("key", 10)
|
|
592
595
|
end.to_not raise_error
|
|
@@ -595,7 +598,8 @@ describe Appsignal do
|
|
|
595
598
|
|
|
596
599
|
describe ".increment_counter" do
|
|
597
600
|
it "should call increment_counter on the extension with a string key" do
|
|
598
|
-
expect(Appsignal::Extension).to receive(:increment_counter)
|
|
601
|
+
expect(Appsignal::Extension).to receive(:increment_counter)
|
|
602
|
+
.with("key", 1, Appsignal::Extension.data_map_new)
|
|
599
603
|
Appsignal.increment_counter("key")
|
|
600
604
|
end
|
|
601
605
|
|
|
@@ -606,18 +610,22 @@ describe Appsignal do
|
|
|
606
610
|
end
|
|
607
611
|
|
|
608
612
|
it "should call increment_counter on the extension with a symbol key" do
|
|
609
|
-
expect(Appsignal::Extension).to receive(:increment_counter)
|
|
613
|
+
expect(Appsignal::Extension).to receive(:increment_counter)
|
|
614
|
+
.with("key", 1, Appsignal::Extension.data_map_new)
|
|
610
615
|
Appsignal.increment_counter(:key)
|
|
611
616
|
end
|
|
612
617
|
|
|
613
618
|
it "should call increment_counter on the extension with a count" do
|
|
614
|
-
expect(Appsignal::Extension).to receive(:increment_counter)
|
|
619
|
+
expect(Appsignal::Extension).to receive(:increment_counter)
|
|
620
|
+
.with("key", 5, Appsignal::Extension.data_map_new)
|
|
615
621
|
Appsignal.increment_counter("key", 5)
|
|
616
622
|
end
|
|
617
623
|
|
|
618
624
|
it "should not raise an exception when out of range" do
|
|
619
|
-
expect(Appsignal::Extension).to receive(:increment_counter)
|
|
620
|
-
|
|
625
|
+
expect(Appsignal::Extension).to receive(:increment_counter)
|
|
626
|
+
.with("key", 10, Appsignal::Extension.data_map_new).and_raise(RangeError)
|
|
627
|
+
expect(Appsignal.logger).to receive(:warn)
|
|
628
|
+
.with("Counter value 10 for key 'key' is too big")
|
|
621
629
|
expect do
|
|
622
630
|
Appsignal.increment_counter("key", 10)
|
|
623
631
|
end.to_not raise_error
|
|
@@ -626,7 +634,8 @@ describe Appsignal do
|
|
|
626
634
|
|
|
627
635
|
describe ".add_distribution_value" do
|
|
628
636
|
it "should call add_distribution_value on the extension with a string key and float" do
|
|
629
|
-
expect(Appsignal::Extension).to receive(:add_distribution_value)
|
|
637
|
+
expect(Appsignal::Extension).to receive(:add_distribution_value)
|
|
638
|
+
.with("key", 0.1, Appsignal::Extension.data_map_new)
|
|
630
639
|
Appsignal.add_distribution_value("key", 0.1)
|
|
631
640
|
end
|
|
632
641
|
|
|
@@ -637,13 +646,16 @@ describe Appsignal do
|
|
|
637
646
|
end
|
|
638
647
|
|
|
639
648
|
it "should call add_distribution_value on the extension with a symbol key and int" do
|
|
640
|
-
expect(Appsignal::Extension).to receive(:add_distribution_value)
|
|
649
|
+
expect(Appsignal::Extension).to receive(:add_distribution_value)
|
|
650
|
+
.with("key", 1.0, Appsignal::Extension.data_map_new)
|
|
641
651
|
Appsignal.add_distribution_value(:key, 1)
|
|
642
652
|
end
|
|
643
653
|
|
|
644
654
|
it "should not raise an exception when out of range" do
|
|
645
|
-
expect(Appsignal::Extension).to receive(:add_distribution_value)
|
|
646
|
-
|
|
655
|
+
expect(Appsignal::Extension).to receive(:add_distribution_value)
|
|
656
|
+
.with("key", 10, Appsignal::Extension.data_map_new).and_raise(RangeError)
|
|
657
|
+
expect(Appsignal.logger).to receive(:warn)
|
|
658
|
+
.with("Distribution value 10 for key 'key' is too big")
|
|
647
659
|
expect do
|
|
648
660
|
Appsignal.add_distribution_value("key", 10)
|
|
649
661
|
end.to_not raise_error
|
|
@@ -1053,14 +1065,16 @@ describe Appsignal do
|
|
|
1053
1065
|
it_behaves_like "instrument helper" do
|
|
1054
1066
|
let(:instrumenter) { Appsignal }
|
|
1055
1067
|
before do
|
|
1056
|
-
expect(Appsignal::Transaction).to receive(:current).at_least(:once)
|
|
1068
|
+
expect(Appsignal::Transaction).to receive(:current).at_least(:once)
|
|
1069
|
+
.and_return(transaction)
|
|
1057
1070
|
end
|
|
1058
1071
|
end
|
|
1059
1072
|
end
|
|
1060
1073
|
|
|
1061
1074
|
describe ".instrument_sql" do
|
|
1062
1075
|
before do
|
|
1063
|
-
expect(Appsignal::Transaction).to receive(:current).at_least(:once)
|
|
1076
|
+
expect(Appsignal::Transaction).to receive(:current).at_least(:once)
|
|
1077
|
+
.and_return(transaction)
|
|
1064
1078
|
end
|
|
1065
1079
|
|
|
1066
1080
|
it "creates an SQL event on the transaction" do
|
|
@@ -1119,7 +1133,7 @@ describe Appsignal do
|
|
|
1119
1133
|
|
|
1120
1134
|
context "when the log path is writable" do
|
|
1121
1135
|
context "when the log file is writable" do
|
|
1122
|
-
let(:log_file_contents) { File.
|
|
1136
|
+
let(:log_file_contents) { File.read(log_file) }
|
|
1123
1137
|
|
|
1124
1138
|
before do
|
|
1125
1139
|
capture_stdout(out_stream) do
|
|
@@ -1198,8 +1212,8 @@ describe Appsignal do
|
|
|
1198
1212
|
|
|
1199
1213
|
it "outputs a warning" do
|
|
1200
1214
|
expect(output).to include \
|
|
1201
|
-
"appsignal: Unable to log to '#{log_path}' "\
|
|
1202
|
-
|
|
1215
|
+
"appsignal: Unable to log to '#{log_path}' " \
|
|
1216
|
+
"or the '#{Appsignal::Config.system_tmp_dir}' fallback."
|
|
1203
1217
|
end
|
|
1204
1218
|
end
|
|
1205
1219
|
|