appsignal 3.4.12-java → 3.4.14-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.semaphore/semaphore.yml +126 -0
- data/CHANGELOG.md +41 -1
- data/README.md +1 -0
- data/build_matrix.yml +14 -0
- data/ext/agent.rb +27 -27
- data/gemfiles/dry-monitor.gemfile +5 -0
- data/gemfiles/rails-7.1.gemfile +7 -0
- data/lib/appsignal/cli/diagnose.rb +9 -0
- data/lib/appsignal/config.rb +6 -0
- data/lib/appsignal/event_formatter/rom/sql_formatter.rb +18 -0
- data/lib/appsignal/helpers/instrumentation.rb +3 -3
- data/lib/appsignal/hooks/active_support_notifications.rb +18 -9
- data/lib/appsignal/hooks/dry_monitor.rb +20 -0
- data/lib/appsignal/hooks.rb +1 -0
- data/lib/appsignal/integrations/active_support_notifications.rb +26 -0
- data/lib/appsignal/integrations/dry_monitor.rb +22 -0
- data/lib/appsignal/integrations/railtie.rb +8 -3
- data/lib/appsignal/integrations/sidekiq.rb +1 -1
- data/lib/appsignal/probes/sidekiq.rb +5 -3
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +33 -1
- data/spec/lib/appsignal/event_formatter/rom/sql_formatter_spec.rb +22 -0
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +6 -0
- data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +104 -0
- data/spec/lib/appsignal/integrations/railtie_spec.rb +91 -74
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +16 -11
- data/spec/lib/appsignal/probes/sidekiq_spec.rb +29 -6
- data/spec/support/helpers/dependency_helper.rb +4 -0
- data/spec/support/helpers/rails_helper.rb +28 -0
- metadata +11 -3
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appsignal
|
4
|
+
module Integrations
|
5
|
+
module DryMonitorIntegration
|
6
|
+
def instrument(event_id, payload = {}, &block)
|
7
|
+
Appsignal::Transaction.current.start_event
|
8
|
+
|
9
|
+
super
|
10
|
+
ensure
|
11
|
+
title, body, body_format = Appsignal::EventFormatter.format("#{event_id}.dry", payload)
|
12
|
+
|
13
|
+
Appsignal::Transaction.current.finish_event(
|
14
|
+
title || event_id.to_s,
|
15
|
+
title,
|
16
|
+
body,
|
17
|
+
body_format
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -36,9 +36,14 @@ module Appsignal
|
|
36
36
|
|
37
37
|
Appsignal.start
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
initialize_error_reporter
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.initialize_error_reporter
|
43
|
+
return unless Appsignal.config[:enable_rails_error_reporter]
|
44
|
+
return unless Rails.respond_to?(:error)
|
45
|
+
|
46
|
+
Rails.error.subscribe(Appsignal::Integrations::RailsErrorReporterSubscriber)
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
@@ -78,9 +78,9 @@ module Appsignal
|
|
78
78
|
redis_info = adapter.redis_info
|
79
79
|
return unless redis_info
|
80
80
|
|
81
|
-
gauge "connection_count", redis_info
|
82
|
-
gauge "memory_usage", redis_info
|
83
|
-
gauge "memory_usage_rss", redis_info
|
81
|
+
gauge "connection_count", redis_info["connected_clients"]
|
82
|
+
gauge "memory_usage", redis_info["used_memory"]
|
83
|
+
gauge "memory_usage_rss", redis_info["used_memory_rss"]
|
84
84
|
end
|
85
85
|
|
86
86
|
def track_stats
|
@@ -112,6 +112,8 @@ module Appsignal
|
|
112
112
|
|
113
113
|
# Track a gauge metric with the `sidekiq_` prefix
|
114
114
|
def gauge(key, value, tags = {})
|
115
|
+
return if value.nil?
|
116
|
+
|
115
117
|
tags[:hostname] = hostname if hostname
|
116
118
|
Appsignal.set_gauge "sidekiq_#{key}", value, tags
|
117
119
|
end
|
data/lib/appsignal/version.rb
CHANGED
@@ -436,7 +436,8 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
436
436
|
"boot" => { "started" => { "result" => true } },
|
437
437
|
"host" => {
|
438
438
|
"uid" => { "result" => Process.uid },
|
439
|
-
"gid" => { "result" => Process.gid }
|
439
|
+
"gid" => { "result" => Process.gid },
|
440
|
+
"running_in_container" => { "result" => Appsignal::Extension.running_in_container? }
|
440
441
|
},
|
441
442
|
"config" => { "valid" => { "result" => true } },
|
442
443
|
"logger" => { "started" => { "result" => true } },
|
@@ -781,6 +782,9 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
781
782
|
"file" => {},
|
782
783
|
"env" => {},
|
783
784
|
"override" => { "send_session_data" => true }
|
785
|
+
},
|
786
|
+
"modifiers" => {
|
787
|
+
"APPSIGNAL_INACTIVE_ON_CONFIG_FILE_ERROR" => ""
|
784
788
|
}
|
785
789
|
)
|
786
790
|
end
|
@@ -912,6 +916,28 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
912
916
|
end
|
913
917
|
end
|
914
918
|
|
919
|
+
describe "modifiers" do
|
920
|
+
before do
|
921
|
+
ENV["APPSIGNAL_INACTIVE_ON_CONFIG_FILE_ERROR"] = "1"
|
922
|
+
run
|
923
|
+
end
|
924
|
+
|
925
|
+
it "outputs config modifiers" do
|
926
|
+
expect(output).to include(
|
927
|
+
"Configuration modifiers\n" \
|
928
|
+
" APPSIGNAL_INACTIVE_ON_CONFIG_FILE_ERROR: \"1\""
|
929
|
+
)
|
930
|
+
end
|
931
|
+
|
932
|
+
it "transmits config modifiers in report" do
|
933
|
+
expect(received_report["config"]).to include(
|
934
|
+
"modifiers" => {
|
935
|
+
"APPSIGNAL_INACTIVE_ON_CONFIG_FILE_ERROR" => "1"
|
936
|
+
}
|
937
|
+
)
|
938
|
+
end
|
939
|
+
end
|
940
|
+
|
915
941
|
it "transmits config in report" do
|
916
942
|
run
|
917
943
|
additional_initial_config = {}
|
@@ -935,6 +961,9 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
935
961
|
"file" => hash_with_string_keys(config.file_config),
|
936
962
|
"env" => {},
|
937
963
|
"override" => { "send_session_data" => true }
|
964
|
+
},
|
965
|
+
"modifiers" => {
|
966
|
+
"APPSIGNAL_INACTIVE_ON_CONFIG_FILE_ERROR" => ""
|
938
967
|
}
|
939
968
|
)
|
940
969
|
end
|
@@ -963,6 +992,9 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
963
992
|
"file" => hash_with_string_keys(config.file_config),
|
964
993
|
"env" => {},
|
965
994
|
"override" => { "send_session_data" => true }
|
995
|
+
},
|
996
|
+
"modifiers" => {
|
997
|
+
"APPSIGNAL_INACTIVE_ON_CONFIG_FILE_ERROR" => ""
|
966
998
|
}
|
967
999
|
)
|
968
1000
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Appsignal::EventFormatter::Rom::SqlFormatter do
|
4
|
+
let(:klass) { described_class }
|
5
|
+
let(:formatter) { klass.new }
|
6
|
+
|
7
|
+
it "registers the sql event formatter" do
|
8
|
+
expect(Appsignal::EventFormatter.registered?("sql.dry", klass)).to be_truthy
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#format" do
|
12
|
+
let(:payload) do
|
13
|
+
{
|
14
|
+
:name => "postgres",
|
15
|
+
:query => "SELECT * FROM users"
|
16
|
+
}
|
17
|
+
end
|
18
|
+
subject { formatter.format(payload) }
|
19
|
+
|
20
|
+
it { is_expected.to eq ["query.postgres", "SELECT * FROM users", 1] }
|
21
|
+
end
|
22
|
+
end
|
@@ -22,6 +22,12 @@ describe Appsignal::Hooks::ActiveSupportNotificationsHook do
|
|
22
22
|
|
23
23
|
it_behaves_like "activesupport instrument override"
|
24
24
|
|
25
|
+
if defined?(::ActiveSupport::Notifications::Fanout::Handle)
|
26
|
+
require_relative "./active_support_notifications/start_finish_shared_examples"
|
27
|
+
|
28
|
+
it_behaves_like "activesupport start finish override"
|
29
|
+
end
|
30
|
+
|
25
31
|
if ::ActiveSupport::Notifications::Instrumenter.method_defined?(:start)
|
26
32
|
require_relative "./active_support_notifications/start_finish_shared_examples"
|
27
33
|
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if DependencyHelper.dry_monitor_present?
|
4
|
+
require "dry-monitor"
|
5
|
+
|
6
|
+
describe Appsignal::Hooks::DryMonitorHook do
|
7
|
+
describe "#dependencies_present?" do
|
8
|
+
subject { described_class.new.dependencies_present? }
|
9
|
+
|
10
|
+
context "when Dry::Monitor::Notifications constant is found" do
|
11
|
+
before { stub_const "Dry::Monitor::Notifications", Class.new }
|
12
|
+
|
13
|
+
it { is_expected.to be_truthy }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when Dry::Monitor::Notifications constant is not found" do
|
17
|
+
before { hide_const "Dry::Monitor::Notifications" }
|
18
|
+
|
19
|
+
it { is_expected.to be_falsy }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#install" do
|
25
|
+
it "installs the dry-monitor hook" do
|
26
|
+
start_agent
|
27
|
+
|
28
|
+
expect(Dry::Monitor::Notifications.included_modules).to include(
|
29
|
+
Appsignal::Integrations::DryMonitorIntegration
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "Dry Monitor Integration" do
|
35
|
+
before :context do
|
36
|
+
start_agent
|
37
|
+
end
|
38
|
+
|
39
|
+
let!(:transaction) do
|
40
|
+
Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST, "test")
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:notifications) { Dry::Monitor::Notifications.new(:test) }
|
44
|
+
|
45
|
+
context "when is a dry-sql event" do
|
46
|
+
let(:event_id) { :sql }
|
47
|
+
let(:payload) do
|
48
|
+
{
|
49
|
+
:name => "postgres",
|
50
|
+
:query => "SELECT * FROM users"
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
it "creates an sql event" do
|
55
|
+
notifications.instrument(event_id, payload)
|
56
|
+
expect(transaction.to_h["events"]).to match([
|
57
|
+
{
|
58
|
+
"allocation_count" => kind_of(Integer),
|
59
|
+
"body" => "SELECT * FROM users",
|
60
|
+
"body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
|
61
|
+
"child_allocation_count" => kind_of(Integer),
|
62
|
+
"child_duration" => kind_of(Float),
|
63
|
+
"child_gc_duration" => kind_of(Float),
|
64
|
+
"count" => 1,
|
65
|
+
"duration" => kind_of(Float),
|
66
|
+
"gc_duration" => kind_of(Float),
|
67
|
+
"name" => "query.postgres",
|
68
|
+
"start" => kind_of(Float),
|
69
|
+
"title" => "query.postgres"
|
70
|
+
}
|
71
|
+
])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "when is an unregistered formatter event" do
|
76
|
+
let(:event_id) { :foo }
|
77
|
+
let(:payload) do
|
78
|
+
{
|
79
|
+
:name => "foo"
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
it "creates a generic event" do
|
84
|
+
notifications.instrument(event_id, payload)
|
85
|
+
expect(transaction.to_h["events"]).to match([
|
86
|
+
{
|
87
|
+
"allocation_count" => kind_of(Integer),
|
88
|
+
"body" => "",
|
89
|
+
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
90
|
+
"child_allocation_count" => kind_of(Integer),
|
91
|
+
"child_duration" => kind_of(Float),
|
92
|
+
"child_gc_duration" => kind_of(Float),
|
93
|
+
"count" => 1,
|
94
|
+
"duration" => kind_of(Float),
|
95
|
+
"gc_duration" => kind_of(Float),
|
96
|
+
"name" => "foo",
|
97
|
+
"start" => kind_of(Float),
|
98
|
+
"title" => ""
|
99
|
+
}
|
100
|
+
])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -2,6 +2,10 @@ if DependencyHelper.rails_present?
|
|
2
2
|
require "action_mailer"
|
3
3
|
|
4
4
|
describe Appsignal::Integrations::Railtie do
|
5
|
+
include RailsHelper
|
6
|
+
|
7
|
+
after { clear_rails_error_reporter! }
|
8
|
+
|
5
9
|
context "after initializing the app" do
|
6
10
|
it "should call initialize_appsignal" do
|
7
11
|
expect(Appsignal::Integrations::Railtie).to receive(:initialize_appsignal)
|
@@ -125,17 +129,16 @@ if DependencyHelper.rails_present?
|
|
125
129
|
|
126
130
|
if Rails.respond_to?(:error)
|
127
131
|
describe "Rails error reporter" do
|
128
|
-
before
|
129
|
-
Appsignal::Integrations::Railtie.initialize_appsignal(app)
|
130
|
-
start_agent
|
131
|
-
end
|
132
|
+
before { start_agent }
|
132
133
|
around { |example| keep_transactions { example.run } }
|
133
134
|
|
134
135
|
context "when error is not handled (reraises the error)" do
|
135
136
|
it "does nothing" do
|
136
|
-
|
137
|
-
|
138
|
-
|
137
|
+
with_rails_error_reporter do
|
138
|
+
expect do
|
139
|
+
Rails.error.record { raise ExampleStandardError }
|
140
|
+
end.to raise_error(ExampleStandardError)
|
141
|
+
end
|
139
142
|
|
140
143
|
expect(created_transactions).to be_empty
|
141
144
|
end
|
@@ -151,26 +154,28 @@ if DependencyHelper.rails_present?
|
|
151
154
|
:duplicated_tag => "duplicated value"
|
152
155
|
)
|
153
156
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
"
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
"
|
169
|
-
"
|
170
|
-
|
171
|
-
|
157
|
+
with_rails_error_reporter do
|
158
|
+
with_current_transaction current_transaction do
|
159
|
+
Rails.error.handle { raise ExampleStandardError }
|
160
|
+
|
161
|
+
transaction = last_transaction
|
162
|
+
transaction_hash = transaction.to_h
|
163
|
+
expect(transaction_hash).to include(
|
164
|
+
"action" => "CustomAction",
|
165
|
+
"namespace" => "custom",
|
166
|
+
"error" => {
|
167
|
+
"name" => "ExampleStandardError",
|
168
|
+
"message" => "ExampleStandardError",
|
169
|
+
"backtrace" => kind_of(String)
|
170
|
+
},
|
171
|
+
"sample_data" => hash_including(
|
172
|
+
"tags" => hash_including(
|
173
|
+
"duplicated_tag" => "duplicated value",
|
174
|
+
"severity" => "warning"
|
175
|
+
)
|
176
|
+
)
|
172
177
|
)
|
173
|
-
|
178
|
+
end
|
174
179
|
end
|
175
180
|
end
|
176
181
|
|
@@ -178,48 +183,52 @@ if DependencyHelper.rails_present?
|
|
178
183
|
current_transaction = http_request_transaction
|
179
184
|
current_transaction.set_tags(:tag1 => "duplicated value")
|
180
185
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
"
|
190
|
-
"
|
191
|
-
|
192
|
-
|
193
|
-
|
186
|
+
with_rails_error_reporter do
|
187
|
+
with_current_transaction current_transaction do
|
188
|
+
given_context = { :tag1 => "value1", :tag2 => "value2" }
|
189
|
+
Rails.error.handle(:context => given_context) { raise ExampleStandardError }
|
190
|
+
|
191
|
+
transaction = last_transaction
|
192
|
+
transaction_hash = transaction.to_h
|
193
|
+
expect(transaction_hash).to include(
|
194
|
+
"sample_data" => hash_including(
|
195
|
+
"tags" => hash_including(
|
196
|
+
"tag1" => "value1",
|
197
|
+
"tag2" => "value2",
|
198
|
+
"severity" => "warning"
|
199
|
+
)
|
200
|
+
)
|
194
201
|
)
|
195
|
-
|
202
|
+
end
|
196
203
|
end
|
197
204
|
end
|
198
205
|
|
199
206
|
it "sends tags stored in :appsignal -> :custom_data as custom data" do
|
200
207
|
current_transaction = http_request_transaction
|
201
208
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
:
|
206
|
-
:
|
207
|
-
|
209
|
+
with_rails_error_reporter do
|
210
|
+
with_current_transaction current_transaction do
|
211
|
+
given_context = {
|
212
|
+
:appsignal => {
|
213
|
+
:custom_data => {
|
214
|
+
:array => [1, 2],
|
215
|
+
:hash => { :one => 1, :two => 2 }
|
216
|
+
}
|
208
217
|
}
|
209
218
|
}
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
219
|
+
Rails.error.handle(:context => given_context) { raise ExampleStandardError }
|
220
|
+
|
221
|
+
transaction = last_transaction
|
222
|
+
transaction_hash = transaction.to_h
|
223
|
+
expect(transaction_hash).to include(
|
224
|
+
"sample_data" => hash_including(
|
225
|
+
"custom_data" => {
|
226
|
+
"array" => [1, 2],
|
227
|
+
"hash" => { "one" => 1, "two" => 2 }
|
228
|
+
}
|
229
|
+
)
|
221
230
|
)
|
222
|
-
|
231
|
+
end
|
223
232
|
end
|
224
233
|
end
|
225
234
|
|
@@ -228,18 +237,20 @@ if DependencyHelper.rails_present?
|
|
228
237
|
current_transaction.set_namespace "custom"
|
229
238
|
current_transaction.set_action "CustomAction"
|
230
239
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
240
|
+
with_rails_error_reporter do
|
241
|
+
with_current_transaction current_transaction do
|
242
|
+
given_context = {
|
243
|
+
:appsignal => { :namespace => "context", :action => "ContextAction" }
|
244
|
+
}
|
245
|
+
Rails.error.handle(:context => given_context) { raise ExampleStandardError }
|
236
246
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
247
|
+
transaction = last_transaction
|
248
|
+
transaction_hash = transaction.to_h
|
249
|
+
expect(transaction_hash).to include(
|
250
|
+
"namespace" => "context",
|
251
|
+
"action" => "ContextAction"
|
252
|
+
)
|
253
|
+
end
|
243
254
|
end
|
244
255
|
end
|
245
256
|
end
|
@@ -267,7 +278,9 @@ if DependencyHelper.rails_present?
|
|
267
278
|
it "fetches the action from the controller in the context" do
|
268
279
|
# The controller key is set by Rails when raised in a controller
|
269
280
|
given_context = { :controller => ExampleRailsControllerMock.new }
|
270
|
-
|
281
|
+
with_rails_error_reporter do
|
282
|
+
Rails.error.handle(:context => given_context) { raise ExampleStandardError }
|
283
|
+
end
|
271
284
|
|
272
285
|
transaction = last_transaction
|
273
286
|
transaction_hash = transaction.to_h
|
@@ -278,7 +291,9 @@ if DependencyHelper.rails_present?
|
|
278
291
|
|
279
292
|
it "sets no action if no execution context is present" do
|
280
293
|
# The controller key is set by Rails when raised in a controller
|
281
|
-
|
294
|
+
with_rails_error_reporter do
|
295
|
+
Rails.error.handle { raise ExampleStandardError }
|
296
|
+
end
|
282
297
|
|
283
298
|
transaction = last_transaction
|
284
299
|
transaction_hash = transaction.to_h
|
@@ -296,17 +311,19 @@ if DependencyHelper.rails_present?
|
|
296
311
|
:tag1 => "value1",
|
297
312
|
:tag2 => "value2"
|
298
313
|
}
|
299
|
-
|
314
|
+
with_rails_error_reporter do
|
315
|
+
Rails.error.handle(:context => given_context) { raise ExampleStandardError }
|
316
|
+
end
|
300
317
|
|
301
318
|
transaction = last_transaction
|
302
319
|
transaction_hash = transaction.to_h
|
303
320
|
expect(transaction_hash).to include(
|
304
321
|
"sample_data" => hash_including(
|
305
|
-
"tags" =>
|
322
|
+
"tags" => hash_including(
|
306
323
|
"tag1" => "value1",
|
307
324
|
"tag2" => "value2",
|
308
325
|
"severity" => "warning"
|
309
|
-
|
326
|
+
)
|
310
327
|
)
|
311
328
|
)
|
312
329
|
end
|
@@ -266,13 +266,16 @@ describe Appsignal::Integrations::SidekiqMiddleware, :with_yaml_parse_error => f
|
|
266
266
|
|
267
267
|
if DependencyHelper.rails7_present?
|
268
268
|
context "with Rails error reporter" do
|
269
|
+
include RailsHelper
|
270
|
+
|
269
271
|
it "reports the worker name as the action, copies the namespace and tags" do
|
270
|
-
Appsignal::Integrations::Railtie.initialize_appsignal(MyApp::Application.new)
|
271
272
|
Appsignal.config = project_fixture_config("production")
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
273
|
+
with_rails_error_reporter do
|
274
|
+
perform_job do
|
275
|
+
Appsignal.tag_job("test_tag" => "value")
|
276
|
+
Rails.error.handle do
|
277
|
+
raise ExampleStandardError, "uh oh"
|
278
|
+
end
|
276
279
|
end
|
277
280
|
end
|
278
281
|
|
@@ -363,7 +366,9 @@ if DependencyHelper.active_job_present?
|
|
363
366
|
require "sidekiq/testing"
|
364
367
|
|
365
368
|
describe "Sidekiq ActiveJob integration" do
|
369
|
+
include RailsHelper
|
366
370
|
include ActiveJobHelpers
|
371
|
+
|
367
372
|
let(:namespace) { Appsignal::Transaction::BACKGROUND_JOB }
|
368
373
|
let(:time) { Time.parse("2001-01-01 10:00:00UTC") }
|
369
374
|
let(:log) { StringIO.new }
|
@@ -416,7 +421,7 @@ if DependencyHelper.active_job_present?
|
|
416
421
|
["perform_job.sidekiq", "perform_start.active_job", "perform.active_job"]
|
417
422
|
end
|
418
423
|
end
|
419
|
-
|
424
|
+
around do |example|
|
420
425
|
start_agent
|
421
426
|
Appsignal.logger = test_logger(log)
|
422
427
|
ActiveJob::Base.queue_adapter = :sidekiq
|
@@ -441,11 +446,11 @@ if DependencyHelper.active_job_present?
|
|
441
446
|
Sidekiq::Testing.server_middleware do |chain|
|
442
447
|
chain.add Appsignal::Integrations::SidekiqMiddleware
|
443
448
|
end
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
+
with_rails_error_reporter do
|
450
|
+
keep_transactions do
|
451
|
+
Sidekiq::Testing.fake! do
|
452
|
+
example.run
|
453
|
+
end
|
449
454
|
end
|
450
455
|
end
|
451
456
|
end
|
@@ -73,6 +73,20 @@ describe Appsignal::Probes::SidekiqProbe do
|
|
73
73
|
module Sidekiq7Mock
|
74
74
|
VERSION = "7.0.0".freeze
|
75
75
|
|
76
|
+
def self.redis_info_data=(info)
|
77
|
+
@redis_info_data = info
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.redis_info_data
|
81
|
+
return @redis_info_data if defined?(@redis_info_data)
|
82
|
+
|
83
|
+
{
|
84
|
+
"connected_clients" => 2,
|
85
|
+
"used_memory" => 1024,
|
86
|
+
"used_memory_rss" => 512
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
76
90
|
def self.redis
|
77
91
|
yield Client.new
|
78
92
|
end
|
@@ -83,11 +97,7 @@ describe Appsignal::Probes::SidekiqProbe do
|
|
83
97
|
end
|
84
98
|
|
85
99
|
def info
|
86
|
-
|
87
|
-
"connected_clients" => 2,
|
88
|
-
"used_memory" => 1024,
|
89
|
-
"used_memory_rss" => 512
|
90
|
-
}
|
100
|
+
Sidekiq7Mock.redis_info_data
|
91
101
|
end
|
92
102
|
end
|
93
103
|
|
@@ -227,6 +237,19 @@ describe Appsignal::Probes::SidekiqProbe do
|
|
227
237
|
probe.call
|
228
238
|
probe.call
|
229
239
|
end
|
240
|
+
|
241
|
+
context "when redis info doesn't contain requested keys" do
|
242
|
+
before { Sidekiq7Mock.redis_info_data = {} }
|
243
|
+
|
244
|
+
it "doesn't create metrics for nil values" do
|
245
|
+
expect_gauge("connection_count").never
|
246
|
+
expect_gauge("memory_usage").never
|
247
|
+
expect_gauge("memory_usage_rss").never
|
248
|
+
# Call probe twice so we can calculate the delta for some gauge values
|
249
|
+
probe.call
|
250
|
+
probe.call
|
251
|
+
end
|
252
|
+
end
|
230
253
|
end
|
231
254
|
|
232
255
|
context "with Sidekiq 6" do
|
@@ -301,7 +324,7 @@ describe Appsignal::Probes::SidekiqProbe do
|
|
301
324
|
end
|
302
325
|
end
|
303
326
|
|
304
|
-
def expect_gauge(key, value, tags = {})
|
327
|
+
def expect_gauge(key, value = anything, tags = {})
|
305
328
|
expect(Appsignal).to receive(:set_gauge)
|
306
329
|
.with("sidekiq_#{key}", value, expected_default_tags.merge(tags))
|
307
330
|
.and_call_original
|
@@ -115,6 +115,10 @@ module DependencyHelper
|
|
115
115
|
dependency_present? "hanami"
|
116
116
|
end
|
117
117
|
|
118
|
+
def dry_monitor_present?
|
119
|
+
dependency_present? "dry-monitor"
|
120
|
+
end
|
121
|
+
|
118
122
|
def hanami2_present?
|
119
123
|
hanami_present? && Gem.loaded_specs["hanami"].version >= Gem::Version.new("2.0")
|
120
124
|
end
|