appsignal 2.11.0.alpha.1-java → 2.11.0.alpha.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/.semaphore/semaphore.yml +39 -53
- data/CHANGELOG.md +3 -1
- data/build_matrix.yml +8 -6
- data/ext/agent.yml +19 -19
- data/gemfiles/padrino.gemfile +2 -2
- data/lib/appsignal/hooks/puma.rb +2 -58
- data/lib/appsignal/hooks/sidekiq.rb +2 -99
- data/lib/appsignal/probes/puma.rb +61 -0
- data/lib/appsignal/probes/sidekiq.rb +102 -0
- data/lib/appsignal/rack/js_exception_catcher.rb +5 -2
- data/lib/appsignal/version.rb +1 -1
- data/lib/puma/plugin/appsignal.rb +2 -1
- data/spec/lib/appsignal/hooks/puma_spec.rb +2 -181
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +256 -462
- data/spec/lib/appsignal/integrations/padrino_spec.rb +1 -1
- data/spec/lib/appsignal/probes/puma_spec.rb +180 -0
- data/spec/lib/appsignal/probes/sidekiq_spec.rb +201 -0
- data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +9 -4
- data/spec/lib/puma/appsignal_spec.rb +1 -1
- data/spec/support/stubs/sidekiq/api.rb +1 -1
- metadata +8 -2
@@ -12,7 +12,8 @@ module Appsignal
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def install
|
15
|
-
|
15
|
+
require "appsignal/probes/sidekiq"
|
16
|
+
Appsignal::Minutely.probes.register :sidekiq, Appsignal::Probes::SidekiqProbe
|
16
17
|
|
17
18
|
::Sidekiq.configure_server do |config|
|
18
19
|
config.server_middleware do |chain|
|
@@ -22,104 +23,6 @@ module Appsignal
|
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
|
-
class SidekiqProbe
|
26
|
-
attr_reader :config
|
27
|
-
|
28
|
-
def self.dependencies_present?
|
29
|
-
Gem::Version.new(::Redis::VERSION) >= Gem::Version.new("3.3.5")
|
30
|
-
end
|
31
|
-
|
32
|
-
def initialize(config = {})
|
33
|
-
@config = config
|
34
|
-
@cache = {}
|
35
|
-
config_string = " with config: #{config}" unless config.empty?
|
36
|
-
Appsignal.logger.debug("Initializing Sidekiq probe#{config_string}")
|
37
|
-
require "sidekiq/api"
|
38
|
-
end
|
39
|
-
|
40
|
-
def call
|
41
|
-
track_redis_info
|
42
|
-
track_stats
|
43
|
-
track_queues
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
attr_reader :cache
|
49
|
-
|
50
|
-
def track_redis_info
|
51
|
-
return unless ::Sidekiq.respond_to?(:redis_info)
|
52
|
-
redis_info = ::Sidekiq.redis_info
|
53
|
-
|
54
|
-
gauge "connection_count", redis_info.fetch("connected_clients")
|
55
|
-
gauge "memory_usage", redis_info.fetch("used_memory")
|
56
|
-
gauge "memory_usage_rss", redis_info.fetch("used_memory_rss")
|
57
|
-
end
|
58
|
-
|
59
|
-
def track_stats
|
60
|
-
stats = ::Sidekiq::Stats.new
|
61
|
-
|
62
|
-
gauge "worker_count", stats.workers_size
|
63
|
-
gauge "process_count", stats.processes_size
|
64
|
-
gauge_delta :jobs_processed, "job_count", stats.processed,
|
65
|
-
:status => :processed
|
66
|
-
gauge_delta :jobs_failed, "job_count", stats.failed, :status => :failed
|
67
|
-
gauge "job_count", stats.retry_size, :status => :retry_queue
|
68
|
-
gauge_delta :jobs_dead, "job_count", stats.dead_size, :status => :died
|
69
|
-
gauge "job_count", stats.scheduled_size, :status => :scheduled
|
70
|
-
gauge "job_count", stats.enqueued, :status => :enqueued
|
71
|
-
end
|
72
|
-
|
73
|
-
def track_queues
|
74
|
-
::Sidekiq::Queue.all.each do |queue|
|
75
|
-
gauge "queue_length", queue.size, :queue => queue.name
|
76
|
-
# Convert latency from seconds to milliseconds
|
77
|
-
gauge "queue_latency", queue.latency * 1_000.0, :queue => queue.name
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# Track a gauge metric with the `sidekiq_` prefix
|
82
|
-
def gauge(key, value, tags = {})
|
83
|
-
tags[:hostname] = hostname if hostname
|
84
|
-
Appsignal.set_gauge "sidekiq_#{key}", value, tags
|
85
|
-
end
|
86
|
-
|
87
|
-
# Track the delta of two values for a gauge metric
|
88
|
-
#
|
89
|
-
# First call will store the data for the metric and the second call will
|
90
|
-
# set a gauge metric with the difference. This is used for absolute
|
91
|
-
# counter values which we want to track as gauges.
|
92
|
-
#
|
93
|
-
# @example
|
94
|
-
# gauge_delta :my_cache_key, "my_gauge", 10
|
95
|
-
# gauge_delta :my_cache_key, "my_gauge", 15
|
96
|
-
# # Creates a gauge with the value `5`
|
97
|
-
# @see #gauge
|
98
|
-
def gauge_delta(cache_key, key, value, tags = {})
|
99
|
-
previous_value = cache[cache_key]
|
100
|
-
cache[cache_key] = value
|
101
|
-
return unless previous_value
|
102
|
-
new_value = value - previous_value
|
103
|
-
gauge key, new_value, tags
|
104
|
-
end
|
105
|
-
|
106
|
-
def hostname
|
107
|
-
return @hostname if defined?(@hostname)
|
108
|
-
if config.key?(:hostname)
|
109
|
-
@hostname = config[:hostname]
|
110
|
-
Appsignal.logger.debug "Sidekiq probe: Using hostname config " \
|
111
|
-
"option #{@hostname.inspect} as hostname"
|
112
|
-
return @hostname
|
113
|
-
end
|
114
|
-
|
115
|
-
host = nil
|
116
|
-
::Sidekiq.redis { |c| host = c.connection[:host] }
|
117
|
-
Appsignal.logger.debug "Sidekiq probe: Using Redis server hostname " \
|
118
|
-
"#{host.inspect} as hostname"
|
119
|
-
@hostname = host
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
26
|
# @api private
|
124
27
|
class SidekiqPlugin # rubocop:disable Metrics/ClassLength
|
125
28
|
include Appsignal::Hooks::Helpers
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Appsignal
|
2
|
+
module Probes
|
3
|
+
# @api private
|
4
|
+
class PumaProbe
|
5
|
+
def initialize
|
6
|
+
@hostname = Appsignal.config[:hostname] || Socket.gethostname
|
7
|
+
end
|
8
|
+
|
9
|
+
def call
|
10
|
+
puma_stats = fetch_puma_stats
|
11
|
+
return unless puma_stats
|
12
|
+
|
13
|
+
stats = JSON.parse puma_stats, :symbolize_names => true
|
14
|
+
counts = {}
|
15
|
+
count_keys = [:backlog, :running, :pool_capacity, :max_threads]
|
16
|
+
|
17
|
+
if stats[:worker_status] # Multiple workers
|
18
|
+
stats[:worker_status].each do |worker|
|
19
|
+
stat = worker[:last_status]
|
20
|
+
count_keys.each do |key|
|
21
|
+
count_if_present counts, key, stat
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
gauge(:workers, stats[:workers], :type => :count)
|
26
|
+
gauge(:workers, stats[:booted_workers], :type => :booted)
|
27
|
+
gauge(:workers, stats[:old_workers], :type => :old)
|
28
|
+
else # Single worker
|
29
|
+
count_keys.each do |key|
|
30
|
+
count_if_present counts, key, stats
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
gauge(:connection_backlog, counts[:backlog]) if counts[:backlog]
|
35
|
+
gauge(:pool_capacity, counts[:pool_capacity]) if counts[:pool_capacity]
|
36
|
+
gauge(:threads, counts[:running], :type => :running) if counts[:running]
|
37
|
+
gauge(:threads, counts[:max_threads], :type => :max) if counts[:max_threads]
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
attr_reader :hostname
|
43
|
+
|
44
|
+
def gauge(field, count, tags = {})
|
45
|
+
Appsignal.set_gauge("puma_#{field}", count, tags.merge(:hostname => hostname))
|
46
|
+
end
|
47
|
+
|
48
|
+
def count_if_present(counts, key, stats)
|
49
|
+
stat_value = stats[key]
|
50
|
+
return unless stat_value
|
51
|
+
counts[key] ||= 0
|
52
|
+
counts[key] += stat_value
|
53
|
+
end
|
54
|
+
|
55
|
+
def fetch_puma_stats
|
56
|
+
::Puma.stats
|
57
|
+
rescue NoMethodError # rubocop:disable Lint/HandleExceptions
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Appsignal
|
2
|
+
module Probes
|
3
|
+
# @api private
|
4
|
+
class SidekiqProbe
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
def self.dependencies_present?
|
8
|
+
Gem::Version.new(::Redis::VERSION) >= Gem::Version.new("3.3.5")
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(config = {})
|
12
|
+
@config = config
|
13
|
+
@cache = {}
|
14
|
+
config_string = " with config: #{config}" unless config.empty?
|
15
|
+
Appsignal.logger.debug("Initializing Sidekiq probe#{config_string}")
|
16
|
+
require "sidekiq/api"
|
17
|
+
end
|
18
|
+
|
19
|
+
def call
|
20
|
+
track_redis_info
|
21
|
+
track_stats
|
22
|
+
track_queues
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :cache
|
28
|
+
|
29
|
+
def track_redis_info
|
30
|
+
return unless ::Sidekiq.respond_to?(:redis_info)
|
31
|
+
redis_info = ::Sidekiq.redis_info
|
32
|
+
|
33
|
+
gauge "connection_count", redis_info.fetch("connected_clients")
|
34
|
+
gauge "memory_usage", redis_info.fetch("used_memory")
|
35
|
+
gauge "memory_usage_rss", redis_info.fetch("used_memory_rss")
|
36
|
+
end
|
37
|
+
|
38
|
+
def track_stats
|
39
|
+
stats = ::Sidekiq::Stats.new
|
40
|
+
|
41
|
+
gauge "worker_count", stats.workers_size
|
42
|
+
gauge "process_count", stats.processes_size
|
43
|
+
gauge_delta :jobs_processed, "job_count", stats.processed,
|
44
|
+
:status => :processed
|
45
|
+
gauge_delta :jobs_failed, "job_count", stats.failed, :status => :failed
|
46
|
+
gauge "job_count", stats.retry_size, :status => :retry_queue
|
47
|
+
gauge_delta :jobs_dead, "job_count", stats.dead_size, :status => :died
|
48
|
+
gauge "job_count", stats.scheduled_size, :status => :scheduled
|
49
|
+
gauge "job_count", stats.enqueued, :status => :enqueued
|
50
|
+
end
|
51
|
+
|
52
|
+
def track_queues
|
53
|
+
::Sidekiq::Queue.all.each do |queue|
|
54
|
+
gauge "queue_length", queue.size, :queue => queue.name
|
55
|
+
# Convert latency from seconds to milliseconds
|
56
|
+
gauge "queue_latency", queue.latency * 1_000.0, :queue => queue.name
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Track a gauge metric with the `sidekiq_` prefix
|
61
|
+
def gauge(key, value, tags = {})
|
62
|
+
tags[:hostname] = hostname if hostname
|
63
|
+
Appsignal.set_gauge "sidekiq_#{key}", value, tags
|
64
|
+
end
|
65
|
+
|
66
|
+
# Track the delta of two values for a gauge metric
|
67
|
+
#
|
68
|
+
# First call will store the data for the metric and the second call will
|
69
|
+
# set a gauge metric with the difference. This is used for absolute
|
70
|
+
# counter values which we want to track as gauges.
|
71
|
+
#
|
72
|
+
# @example
|
73
|
+
# gauge_delta :my_cache_key, "my_gauge", 10
|
74
|
+
# gauge_delta :my_cache_key, "my_gauge", 15
|
75
|
+
# # Creates a gauge with the value `5`
|
76
|
+
# @see #gauge
|
77
|
+
def gauge_delta(cache_key, key, value, tags = {})
|
78
|
+
previous_value = cache[cache_key]
|
79
|
+
cache[cache_key] = value
|
80
|
+
return unless previous_value
|
81
|
+
new_value = value - previous_value
|
82
|
+
gauge key, new_value, tags
|
83
|
+
end
|
84
|
+
|
85
|
+
def hostname
|
86
|
+
return @hostname if defined?(@hostname)
|
87
|
+
if config.key?(:hostname)
|
88
|
+
@hostname = config[:hostname]
|
89
|
+
Appsignal.logger.debug "Sidekiq probe: Using hostname config " \
|
90
|
+
"option #{@hostname.inspect} as hostname"
|
91
|
+
return @hostname
|
92
|
+
end
|
93
|
+
|
94
|
+
host = nil
|
95
|
+
::Sidekiq.redis { |c| host = c.connection[:host] }
|
96
|
+
Appsignal.logger.debug "Sidekiq probe: Using Redis server hostname " \
|
97
|
+
"#{host.inspect} as hostname"
|
98
|
+
@hostname = host
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -29,8 +29,11 @@ module Appsignal
|
|
29
29
|
Appsignal.logger.debug \
|
30
30
|
"Initializing Appsignal::Rack::JSExceptionCatcher"
|
31
31
|
deprecation_message "The Appsignal::Rack::JSExceptionCatcher is " \
|
32
|
-
"deprecated
|
33
|
-
"integration
|
32
|
+
"deprecated and will be removed in a future version. Please use " \
|
33
|
+
"the official AppSignal JavaScript integration by disabling " \
|
34
|
+
"`enable_frontend_error_catching` in your configuration and " \
|
35
|
+
"installing AppSignal for JavaScript instead. " \
|
36
|
+
"(https://docs.appsignal.com/front-end/)"
|
34
37
|
@app = app
|
35
38
|
end
|
36
39
|
|
data/lib/appsignal/version.rb
CHANGED
@@ -17,7 +17,8 @@ Puma::Plugin.create do
|
|
17
17
|
launcher.events.on_booted do
|
18
18
|
require "appsignal"
|
19
19
|
if ::Puma.respond_to?(:stats)
|
20
|
-
|
20
|
+
require "appsignal/probes/puma"
|
21
|
+
Appsignal::Minutely.probes.register :puma, Appsignal::Probes::PumaProbe
|
21
22
|
end
|
22
23
|
Appsignal.start
|
23
24
|
Appsignal.start_logger
|
@@ -55,7 +55,7 @@ describe Appsignal::Hooks::PumaHook do
|
|
55
55
|
|
56
56
|
Appsignal::Hooks::PumaHook.new.install
|
57
57
|
probe = Appsignal::Minutely.probes[:puma]
|
58
|
-
expect(probe).to eql(Appsignal::
|
58
|
+
expect(probe).to eql(Appsignal::Probes::PumaProbe)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -101,7 +101,7 @@ describe Appsignal::Hooks::PumaHook do
|
|
101
101
|
|
102
102
|
Appsignal::Hooks::PumaHook.new.install
|
103
103
|
probe = Appsignal::Minutely.probes[:puma]
|
104
|
-
expect(probe).to eql(Appsignal::
|
104
|
+
expect(probe).to eql(Appsignal::Probes::PumaProbe)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
end
|
@@ -116,182 +116,3 @@ describe Appsignal::Hooks::PumaHook do
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
end
|
119
|
-
|
120
|
-
describe Appsignal::Hooks::PumaProbe do
|
121
|
-
before(:context) do
|
122
|
-
Appsignal.config = project_fixture_config
|
123
|
-
end
|
124
|
-
after(:context) do
|
125
|
-
Appsignal.config = nil
|
126
|
-
end
|
127
|
-
|
128
|
-
let(:probe) { Appsignal::Hooks::PumaProbe.new }
|
129
|
-
|
130
|
-
describe "hostname" do
|
131
|
-
it "returns the socket hostname" do
|
132
|
-
expect(probe.send(:hostname)).to eql(Socket.gethostname)
|
133
|
-
end
|
134
|
-
|
135
|
-
context "with overridden hostname" do
|
136
|
-
around do |sample|
|
137
|
-
Appsignal.config[:hostname] = "frontend1"
|
138
|
-
sample.run
|
139
|
-
Appsignal.config[:hostname] = nil
|
140
|
-
end
|
141
|
-
it "returns the configured host" do
|
142
|
-
expect(probe.send(:hostname)).to eql("frontend1")
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
describe "#call" do
|
148
|
-
let(:expected_default_tags) { { :hostname => Socket.gethostname } }
|
149
|
-
|
150
|
-
context "with multiple worker stats" do
|
151
|
-
before(:context) do
|
152
|
-
class Puma
|
153
|
-
def self.stats
|
154
|
-
{
|
155
|
-
"workers" => 2,
|
156
|
-
"booted_workers" => 2,
|
157
|
-
"old_workers" => 0,
|
158
|
-
"worker_status" => [
|
159
|
-
{
|
160
|
-
"last_status" => {
|
161
|
-
"backlog" => 0,
|
162
|
-
"running" => 5,
|
163
|
-
"pool_capacity" => 5,
|
164
|
-
"max_threads" => 5
|
165
|
-
}
|
166
|
-
},
|
167
|
-
{
|
168
|
-
"last_status" => {
|
169
|
-
"backlog" => 0,
|
170
|
-
"running" => 5,
|
171
|
-
"pool_capacity" => 5,
|
172
|
-
"max_threads" => 5
|
173
|
-
}
|
174
|
-
}
|
175
|
-
]
|
176
|
-
}.to_json
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
-
after(:context) { Object.send(:remove_const, :Puma) }
|
181
|
-
|
182
|
-
it "calls `puma_gauge` with the (summed) worker metrics" do
|
183
|
-
expect_gauge(:workers, 2, :type => :count)
|
184
|
-
expect_gauge(:workers, 2, :type => :booted)
|
185
|
-
expect_gauge(:workers, 0, :type => :old)
|
186
|
-
|
187
|
-
expect_gauge(:connection_backlog, 0)
|
188
|
-
expect_gauge(:pool_capacity, 10)
|
189
|
-
expect_gauge(:threads, 10, :type => :running)
|
190
|
-
expect_gauge(:threads, 10, :type => :max)
|
191
|
-
|
192
|
-
probe.call
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
context "with single worker stats" do
|
197
|
-
before(:context) do
|
198
|
-
class Puma
|
199
|
-
def self.stats
|
200
|
-
{
|
201
|
-
"backlog" => 0,
|
202
|
-
"running" => 5,
|
203
|
-
"pool_capacity" => 5,
|
204
|
-
"max_threads" => 5
|
205
|
-
}.to_json
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
after(:context) { Object.send(:remove_const, :Puma) }
|
210
|
-
|
211
|
-
it "calls `puma_gauge` with the (summed) worker metrics" do
|
212
|
-
expect_gauge(:connection_backlog, 0)
|
213
|
-
expect_gauge(:pool_capacity, 5)
|
214
|
-
expect_gauge(:threads, 5, :type => :running)
|
215
|
-
expect_gauge(:threads, 5, :type => :max)
|
216
|
-
probe.call
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
context "without stats" do
|
221
|
-
before(:context) do
|
222
|
-
class Puma
|
223
|
-
def self.stats
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
after(:context) { Object.send(:remove_const, :Puma) }
|
228
|
-
|
229
|
-
context "when it returns nil" do
|
230
|
-
it "does not track metrics" do
|
231
|
-
expect(probe).to_not receive(:puma_gauge)
|
232
|
-
probe.call
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
# Puma.stats raises a NoMethodError on a nil object on the first call.
|
237
|
-
context "when it returns a NoMethodError on the first call" do
|
238
|
-
let(:log) { StringIO.new }
|
239
|
-
|
240
|
-
it "ignores the first call and tracks the second call" do
|
241
|
-
use_logger_with log do
|
242
|
-
expect(Puma).to receive(:stats)
|
243
|
-
.and_raise(NoMethodError.new("undefined method `stats' for nil:NilClass"))
|
244
|
-
probe.call
|
245
|
-
|
246
|
-
expect(Puma).to receive(:stats).and_return({
|
247
|
-
"backlog" => 1,
|
248
|
-
"running" => 5,
|
249
|
-
"pool_capacity" => 4,
|
250
|
-
"max_threads" => 6
|
251
|
-
}.to_json)
|
252
|
-
|
253
|
-
expect_gauge(:connection_backlog, 1)
|
254
|
-
expect_gauge(:pool_capacity, 4)
|
255
|
-
expect_gauge(:threads, 5, :type => :running)
|
256
|
-
expect_gauge(:threads, 6, :type => :max)
|
257
|
-
probe.call
|
258
|
-
end
|
259
|
-
|
260
|
-
expect(log_contents(log)).to_not contains_log(:error, "Error in minutely probe 'puma'")
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
context "when it does not have a complete stats payload" do
|
265
|
-
let(:log) { StringIO.new }
|
266
|
-
|
267
|
-
it "tracks whatever metrics we do have" do
|
268
|
-
use_logger_with log do
|
269
|
-
expect(Puma).to receive(:stats).and_return({
|
270
|
-
"backlog" => 1,
|
271
|
-
"running" => 5
|
272
|
-
}.to_json)
|
273
|
-
|
274
|
-
expect_gauge(:connection_backlog, 1)
|
275
|
-
expect_no_gauge(:pool_capacity)
|
276
|
-
expect_gauge(:threads, 5, :type => :running)
|
277
|
-
expect_no_gauge(:threads, :type => :max)
|
278
|
-
probe.call
|
279
|
-
end
|
280
|
-
|
281
|
-
expect(log_contents(log)).to_not contains_log(:error, "Error in minutely probe 'puma'")
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
def expect_gauge(key, value, tags = {})
|
287
|
-
expect(Appsignal).to receive(:set_gauge)
|
288
|
-
.with("puma_#{key}", value, expected_default_tags.merge(tags))
|
289
|
-
.and_call_original
|
290
|
-
end
|
291
|
-
|
292
|
-
def expect_no_gauge(key, tags = {})
|
293
|
-
expect(Appsignal).to_not receive(:set_gauge)
|
294
|
-
.with("puma_#{key}", anything, tags)
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|