appsignal 3.4.12-java → 3.4.14-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/.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
|