appsignal 2.9.2.alpha.1 → 2.9.18.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- data/.github/ISSUE_TEMPLATE/chore.md +14 -0
- data/.gitignore +1 -2
- data/.rubocop.yml +3 -0
- data/.travis.yml +25 -27
- data/CHANGELOG.md +632 -535
- data/README.md +8 -3
- data/Rakefile +118 -122
- data/SUPPORT.md +16 -0
- data/appsignal.gemspec +14 -4
- data/build_matrix.yml +16 -8
- data/ext/Rakefile +2 -3
- data/ext/agent.yml +40 -37
- data/ext/base.rb +37 -14
- data/ext/extconf.rb +3 -4
- data/gemfiles/capistrano2.gemfile +5 -0
- data/gemfiles/capistrano3.gemfile +5 -0
- data/gemfiles/grape.gemfile +5 -0
- data/gemfiles/no_dependencies.gemfile +5 -0
- data/gemfiles/padrino.gemfile +5 -0
- data/gemfiles/que.gemfile +5 -0
- data/gemfiles/que_beta.gemfile +10 -0
- data/gemfiles/rails-3.2.gemfile +5 -0
- data/gemfiles/rails-4.0.gemfile +5 -0
- data/gemfiles/rails-4.1.gemfile +5 -0
- data/gemfiles/rails-4.2.gemfile +5 -0
- data/gemfiles/rails-6.0.gemfile +1 -1
- data/gemfiles/resque.gemfile +5 -0
- data/lib/appsignal.rb +1 -4
- data/lib/appsignal/cli/demo.rb +5 -2
- data/lib/appsignal/cli/diagnose/utils.rb +2 -0
- data/lib/appsignal/cli/install.rb +34 -10
- data/lib/appsignal/cli/notify_of_deploy.rb +10 -0
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +10 -8
- data/lib/appsignal/helpers/instrumentation.rb +18 -9
- data/lib/appsignal/helpers/metrics.rb +0 -1
- data/lib/appsignal/hooks.rb +3 -1
- data/lib/appsignal/hooks/active_support_notifications.rb +2 -5
- data/lib/appsignal/hooks/puma.rb +15 -13
- data/lib/appsignal/hooks/sequel.rb +1 -1
- data/lib/appsignal/hooks/sidekiq.rb +33 -8
- data/lib/appsignal/integrations/que.rb +9 -8
- data/lib/appsignal/minutely.rb +38 -19
- data/lib/appsignal/transaction.rb +5 -0
- data/lib/appsignal/utils/rails_helper.rb +4 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/puma/plugin/appsignal.rb +26 -0
- data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +40 -0
- data/spec/lib/appsignal/cli/install_spec.rb +51 -7
- data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +10 -0
- data/spec/lib/appsignal/config_spec.rb +10 -8
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +38 -28
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +104 -25
- data/spec/lib/appsignal/hooks/puma_spec.rb +69 -39
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +65 -3
- data/spec/lib/appsignal/hooks_spec.rb +4 -0
- data/spec/lib/appsignal/minutely_spec.rb +150 -88
- data/spec/lib/appsignal/transaction_spec.rb +27 -4
- data/spec/lib/appsignal_spec.rb +62 -11
- data/spec/lib/puma/appsignal_spec.rb +91 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/application.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/appsignal.yml +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/development.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/production.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/test.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/log/.gitkeep +0 -0
- data/spec/support/helpers/config_helpers.rb +1 -1
- data/spec/support/helpers/wait_for_helper.rb +28 -0
- data/spec/support/mocks/mock_probe.rb +11 -0
- metadata +37 -30
- data/spec/support/fixtures/containers/cgroups/docker +0 -14
- data/spec/support/fixtures/containers/cgroups/docker_systemd +0 -8
- data/spec/support/fixtures/containers/cgroups/lxc +0 -10
- data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
- data/spec/support/fixtures/containers/cgroups/none +0 -1
@@ -60,6 +60,8 @@ module Appsignal
|
|
60
60
|
# Terminology: Deploy marker
|
61
61
|
class NotifyOfDeploy
|
62
62
|
class << self
|
63
|
+
include Appsignal::Utils::DeprecationMessage
|
64
|
+
|
63
65
|
# @param options [Hash]
|
64
66
|
# @option options :environment [String] environment to load
|
65
67
|
# configuration for.
|
@@ -85,6 +87,14 @@ module Appsignal
|
|
85
87
|
},
|
86
88
|
config
|
87
89
|
).transmit
|
90
|
+
|
91
|
+
puts
|
92
|
+
message = "This command (appsignal notify_of_deploy) has been " \
|
93
|
+
"deprecated in favor of the `revision` config option. Please " \
|
94
|
+
"see our documentation for more information on the recommended " \
|
95
|
+
"method: " \
|
96
|
+
"https://docs.appsignal.com/application/markers/deploy-markers.html"
|
97
|
+
deprecation_message message, Appsignal.logger
|
88
98
|
end
|
89
99
|
|
90
100
|
private
|
@@ -22,11 +22,13 @@ module Appsignal
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
25
|
+
if defined?(Rails)
|
26
|
+
Appsignal::EventFormatter.register(
|
27
|
+
"render_partial.action_view",
|
28
|
+
Appsignal::EventFormatter::ActionView::RenderFormatter
|
29
|
+
)
|
30
|
+
Appsignal::EventFormatter.register(
|
31
|
+
"render_template.action_view",
|
32
|
+
Appsignal::EventFormatter::ActionView::RenderFormatter
|
33
|
+
)
|
34
|
+
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
module Appsignal
|
4
4
|
module Helpers
|
5
|
-
# @api private
|
6
5
|
module Instrumentation # rubocop:disable Metrics/ModuleLength
|
7
6
|
# Creates an AppSignal transaction for the given block.
|
8
7
|
#
|
@@ -57,8 +56,9 @@ module Appsignal
|
|
57
56
|
# @return [Object] the value of the given block is returned.
|
58
57
|
# @since 0.10.0
|
59
58
|
def monitor_transaction(name, env = {})
|
60
|
-
|
61
|
-
|
59
|
+
# Always verify input, even when Appsignal is not active.
|
60
|
+
# This makes it more likely invalid arguments get flagged in test/dev
|
61
|
+
# environments.
|
62
62
|
if name.start_with?("perform_job".freeze)
|
63
63
|
namespace = Appsignal::Transaction::BACKGROUND_JOB
|
64
64
|
request = Appsignal::Transaction::GenericRequest.new(env)
|
@@ -66,9 +66,14 @@ module Appsignal
|
|
66
66
|
namespace = Appsignal::Transaction::HTTP_REQUEST
|
67
67
|
request = ::Rack::Request.new(env)
|
68
68
|
else
|
69
|
-
logger.error
|
70
|
-
|
69
|
+
logger.error "Unrecognized name '#{name}': names must start with " \
|
70
|
+
"either 'perform_job' (for jobs and tasks) or 'process_action' " \
|
71
|
+
"(for HTTP requests)"
|
72
|
+
return yield
|
71
73
|
end
|
74
|
+
|
75
|
+
return yield unless active?
|
76
|
+
|
72
77
|
transaction = Appsignal::Transaction.create(
|
73
78
|
SecureRandom.uuid,
|
74
79
|
namespace,
|
@@ -196,7 +201,8 @@ module Appsignal
|
|
196
201
|
)
|
197
202
|
return unless active?
|
198
203
|
unless error.is_a?(Exception)
|
199
|
-
logger.error
|
204
|
+
logger.error "Appsignal.send_error: Cannot send error. The given " \
|
205
|
+
"value is not an exception: #{error.inspect}"
|
200
206
|
return
|
201
207
|
end
|
202
208
|
transaction = Appsignal::Transaction.new(
|
@@ -251,9 +257,12 @@ module Appsignal
|
|
251
257
|
# Exception handling guide
|
252
258
|
# @since 0.6.6
|
253
259
|
def set_error(exception, tags = nil, namespace = nil)
|
254
|
-
|
255
|
-
|
256
|
-
exception.
|
260
|
+
unless exception.is_a?(Exception)
|
261
|
+
logger.error "Appsignal.set_error: Cannot set error. The given " \
|
262
|
+
"value is not an exception: #{exception.inspect}"
|
263
|
+
return
|
264
|
+
end
|
265
|
+
return if !active? || Appsignal::Transaction.current.nil?
|
257
266
|
transaction = Appsignal::Transaction.current
|
258
267
|
transaction.set_error(exception)
|
259
268
|
transaction.set_tags(tags) if tags
|
data/lib/appsignal/hooks.rb
CHANGED
@@ -37,7 +37,9 @@ module Appsignal
|
|
37
37
|
install
|
38
38
|
@installed = true
|
39
39
|
rescue => ex
|
40
|
-
Appsignal.logger
|
40
|
+
logger = Appsignal.logger
|
41
|
+
logger.error("Error while installing #{name} hook: #{ex}")
|
42
|
+
logger.debug ex.backtrace.join("\n")
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -30,16 +30,13 @@ module Appsignal
|
|
30
30
|
# Events that start with a bang are internal to Rails
|
31
31
|
instrument_this = name[0] != BANG
|
32
32
|
|
33
|
-
if instrument_this
|
34
|
-
transaction = Appsignal::Transaction.current
|
35
|
-
transaction.start_event
|
36
|
-
end
|
33
|
+
Appsignal::Transaction.current.start_event if instrument_this
|
37
34
|
|
38
35
|
instrument_without_appsignal(name, payload, &block)
|
39
36
|
ensure
|
40
37
|
if instrument_this
|
41
38
|
title, body, body_format = Appsignal::EventFormatter.format(name, payload)
|
42
|
-
|
39
|
+
Appsignal::Transaction.current.finish_event(
|
43
40
|
name.to_s,
|
44
41
|
title,
|
45
42
|
body,
|
data/lib/appsignal/hooks/puma.rb
CHANGED
@@ -11,22 +11,24 @@ module Appsignal
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def install
|
14
|
-
if ::Puma.respond_to?(:stats)
|
14
|
+
if ::Puma.respond_to?(:stats) && !defined?(APPSIGNAL_PUMA_PLUGIN_LOADED)
|
15
|
+
# Only install the minutely probe if a user isn't using our Puma
|
16
|
+
# plugin, which lives in `lib/puma/appsignal.rb`. This plugin defines
|
17
|
+
# the {APPSIGNAL_PUMA_PLUGIN_LOADED} constant.
|
18
|
+
#
|
19
|
+
# We prefer people use the AppSignal Puma plugin. This fallback is
|
20
|
+
# only there when users relied on our *magic* integration.
|
21
|
+
#
|
22
|
+
# Using the Puma plugin, the minutely probe thread will still run in
|
23
|
+
# Puma workers, for other non-Puma probes, but the Puma probe only
|
24
|
+
# runs in the Puma main process.
|
25
|
+
# For more information:
|
26
|
+
# https://docs.appsignal.com/ruby/integrations/puma.html
|
15
27
|
Appsignal::Minutely.probes.register :puma, PumaProbe
|
16
28
|
end
|
17
29
|
|
18
|
-
|
19
|
-
|
20
|
-
::Puma.cli_config.options[:before_worker_boot] << proc do |_id|
|
21
|
-
Appsignal.forked
|
22
|
-
end
|
23
|
-
|
24
|
-
::Puma.cli_config.options[:before_worker_shutdown] ||= []
|
25
|
-
::Puma.cli_config.options[:before_worker_shutdown] << proc do |_id|
|
26
|
-
Appsignal.stop("puma before_worker_shutdown")
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
+
return unless defined?(::Puma::Cluster)
|
31
|
+
# For clustered mode with multiple workers
|
30
32
|
::Puma::Cluster.class_eval do
|
31
33
|
alias stop_workers_without_appsignal stop_workers
|
32
34
|
|
@@ -42,7 +42,7 @@ module Appsignal
|
|
42
42
|
|
43
43
|
def install
|
44
44
|
# Register the extension...
|
45
|
-
if ::Sequel::MAJOR >= 4 && ::Sequel::MINOR >= 35
|
45
|
+
if (::Sequel::MAJOR >= 4 && ::Sequel::MINOR >= 35) || ::Sequel::MAJOR >= 5
|
46
46
|
::Sequel::Database.register_extension(
|
47
47
|
:appsignal_integration,
|
48
48
|
Appsignal::Hooks::SequelLogConnectionExtension
|
@@ -25,20 +25,42 @@ module Appsignal
|
|
25
25
|
class SidekiqProbe
|
26
26
|
attr_reader :config
|
27
27
|
|
28
|
+
def self.dependencies_present?
|
29
|
+
Gem::Version.new(::Redis::VERSION) >= Gem::Version.new("3.3.5")
|
30
|
+
end
|
31
|
+
|
28
32
|
def initialize(config = {})
|
29
33
|
@config = config
|
30
34
|
@cache = {}
|
35
|
+
config_string = " with config: #{config}" unless config.empty?
|
36
|
+
Appsignal.logger.debug("Initializing Sidekiq probe#{config_string}")
|
31
37
|
require "sidekiq/api"
|
32
38
|
end
|
33
39
|
|
34
40
|
def call
|
35
|
-
|
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)
|
36
52
|
redis_info = ::Sidekiq.redis_info
|
37
|
-
|
38
|
-
gauge "process_count", stats.processes_size
|
53
|
+
|
39
54
|
gauge "connection_count", redis_info.fetch("connected_clients")
|
40
55
|
gauge "memory_usage", redis_info.fetch("used_memory")
|
41
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
|
42
64
|
gauge_delta :jobs_processed, "job_count", stats.processed,
|
43
65
|
:status => :processed
|
44
66
|
gauge_delta :jobs_failed, "job_count", stats.failed, :status => :failed
|
@@ -46,17 +68,16 @@ module Appsignal
|
|
46
68
|
gauge_delta :jobs_dead, "job_count", stats.dead_size, :status => :died
|
47
69
|
gauge "job_count", stats.scheduled_size, :status => :scheduled
|
48
70
|
gauge "job_count", stats.enqueued, :status => :enqueued
|
71
|
+
end
|
49
72
|
|
73
|
+
def track_queues
|
50
74
|
::Sidekiq::Queue.all.each do |queue|
|
51
75
|
gauge "queue_length", queue.size, :queue => queue.name
|
52
|
-
|
76
|
+
# Convert latency from seconds to milliseconds
|
77
|
+
gauge "queue_latency", queue.latency * 1_000.0, :queue => queue.name
|
53
78
|
end
|
54
79
|
end
|
55
80
|
|
56
|
-
private
|
57
|
-
|
58
|
-
attr_reader :cache
|
59
|
-
|
60
81
|
# Track a gauge metric with the `sidekiq_` prefix
|
61
82
|
def gauge(key, value, tags = {})
|
62
83
|
tags[:hostname] = hostname if hostname
|
@@ -86,11 +107,15 @@ module Appsignal
|
|
86
107
|
return @hostname if defined?(@hostname)
|
87
108
|
if config.key?(:hostname)
|
88
109
|
@hostname = config[:hostname]
|
110
|
+
Appsignal.logger.debug "Sidekiq probe: Using hostname config " \
|
111
|
+
"option #{@hostname.inspect} as hostname"
|
89
112
|
return @hostname
|
90
113
|
end
|
91
114
|
|
92
115
|
host = nil
|
93
116
|
::Sidekiq.redis { |c| host = c.connection[:host] }
|
117
|
+
Appsignal.logger.debug "Sidekiq probe: Using Redis server hostname " \
|
118
|
+
"#{host.inspect} as hostname"
|
94
119
|
@hostname = host
|
95
120
|
end
|
96
121
|
end
|
@@ -5,16 +5,17 @@ module Appsignal
|
|
5
5
|
module QuePlugin
|
6
6
|
def self.included(base)
|
7
7
|
base.class_eval do
|
8
|
-
def _run_with_appsignal
|
8
|
+
def _run_with_appsignal(*)
|
9
|
+
local_attrs = respond_to?(:que_attrs) ? que_attrs : attrs
|
9
10
|
env = {
|
10
11
|
:metadata => {
|
11
|
-
:id =>
|
12
|
-
:queue =>
|
13
|
-
:run_at =>
|
14
|
-
:priority =>
|
15
|
-
:attempts =>
|
12
|
+
:id => local_attrs[:job_id] || local_attrs[:id],
|
13
|
+
:queue => local_attrs[:queue],
|
14
|
+
:run_at => local_attrs[:run_at].to_s,
|
15
|
+
:priority => local_attrs[:priority],
|
16
|
+
:attempts => local_attrs[:error_count].to_i
|
16
17
|
},
|
17
|
-
:params =>
|
18
|
+
:params => local_attrs[:args]
|
18
19
|
}
|
19
20
|
|
20
21
|
request = Appsignal::Transaction::GenericRequest.new(env)
|
@@ -31,7 +32,7 @@ module Appsignal
|
|
31
32
|
transaction.set_error(error)
|
32
33
|
raise error
|
33
34
|
ensure
|
34
|
-
transaction.set_action "#{
|
35
|
+
transaction.set_action "#{local_attrs[:job_class]}#run"
|
35
36
|
Appsignal::Transaction.complete_current!
|
36
37
|
end
|
37
38
|
end
|
data/lib/appsignal/minutely.rb
CHANGED
@@ -135,20 +135,22 @@ module Appsignal
|
|
135
135
|
# @api private
|
136
136
|
def start
|
137
137
|
stop
|
138
|
-
initialize_probes
|
139
138
|
@@thread = Thread.new do
|
139
|
+
sleep initial_wait_time
|
140
|
+
initialize_probes
|
140
141
|
loop do
|
141
142
|
logger = Appsignal.logger
|
142
|
-
logger.debug("Gathering minutely metrics with #{
|
143
|
+
logger.debug("Gathering minutely metrics with #{probe_instances.count} probes")
|
143
144
|
probe_instances.each do |name, probe|
|
144
145
|
begin
|
145
146
|
logger.debug("Gathering minutely metrics with '#{name}' probe")
|
146
147
|
probe.call
|
147
148
|
rescue => ex
|
148
|
-
logger.error
|
149
|
+
logger.error "Error in minutely probe '#{name}': #{ex}"
|
150
|
+
logger.debug ex.backtrace.join("\n")
|
149
151
|
end
|
150
152
|
end
|
151
|
-
sleep
|
153
|
+
sleep wait_time
|
152
154
|
end
|
153
155
|
end
|
154
156
|
end
|
@@ -164,30 +166,47 @@ module Appsignal
|
|
164
166
|
60 - Time.now.sec
|
165
167
|
end
|
166
168
|
|
167
|
-
# @api private
|
168
|
-
def register_garbage_collection_probe
|
169
|
-
probes.register :garbage_collection, GCProbe.new
|
170
|
-
end
|
171
|
-
|
172
169
|
private
|
173
170
|
|
171
|
+
def initial_wait_time
|
172
|
+
remaining_seconds = 60 - Time.now.sec
|
173
|
+
return remaining_seconds if remaining_seconds > 30
|
174
|
+
remaining_seconds + 60
|
175
|
+
end
|
176
|
+
|
174
177
|
def initialize_probes
|
175
178
|
probes.each do |name, probe|
|
176
|
-
|
177
|
-
probe_instances[name] = instance
|
179
|
+
initialize_probe(name, probe)
|
178
180
|
end
|
179
181
|
end
|
180
182
|
|
181
|
-
def
|
182
|
-
|
183
|
+
def initialize_probe(name, probe)
|
184
|
+
if probe.respond_to? :new
|
185
|
+
instance = probe.new
|
186
|
+
klass = probe
|
187
|
+
else
|
188
|
+
instance = probe
|
189
|
+
klass = instance.class
|
190
|
+
end
|
191
|
+
unless dependencies_present?(klass)
|
192
|
+
Appsignal.logger.debug "Skipping '#{name}' probe, " \
|
193
|
+
"#{klass}.dependency_present? returned falsy"
|
194
|
+
return
|
195
|
+
end
|
196
|
+
probe_instances[name] = instance
|
197
|
+
rescue => error
|
198
|
+
logger = Appsignal.logger
|
199
|
+
logger.error "Error while initializing minutely probe '#{name}': #{error}"
|
200
|
+
logger.debug error.backtrace.join("\n")
|
183
201
|
end
|
184
|
-
end
|
185
202
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
203
|
+
def dependencies_present?(probe)
|
204
|
+
return true unless probe.respond_to? :dependencies_present?
|
205
|
+
probe.dependencies_present?
|
206
|
+
end
|
207
|
+
|
208
|
+
def probe_instances
|
209
|
+
@@probe_instances ||= {}
|
191
210
|
end
|
192
211
|
end
|
193
212
|
end
|
@@ -264,6 +264,11 @@ module Appsignal
|
|
264
264
|
end
|
265
265
|
|
266
266
|
def set_error(error)
|
267
|
+
unless error.is_a?(Exception)
|
268
|
+
Appsignal.logger.error "Appsignal::Transaction#set_error: Cannot set error. " \
|
269
|
+
"The given value is not an exception: #{error.inspect}"
|
270
|
+
return
|
271
|
+
end
|
267
272
|
return unless error
|
268
273
|
return unless Appsignal.active?
|
269
274
|
|
data/lib/appsignal/version.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
APPSIGNAL_PUMA_PLUGIN_LOADED = true
|
2
|
+
|
3
|
+
# AppSignal Puma plugin
|
4
|
+
#
|
5
|
+
# This plugin ensures the minutely probe thread is started with the Puma
|
6
|
+
# minutely probe in the Puma master process.
|
7
|
+
#
|
8
|
+
# The constant {APPSIGNAL_PUMA_PLUGIN_LOADED} is here to mark the Plugin as
|
9
|
+
# loaded by the rest of the AppSignal gem. This ensures that the Puma minutely
|
10
|
+
# probe is not also started in every Puma workers, which was the old behavior.
|
11
|
+
# See {Appsignal::Hooks::PumaHook#install} for more information.
|
12
|
+
#
|
13
|
+
# For even more information:
|
14
|
+
# https://docs.appsignal.com/ruby/integrations/puma.html
|
15
|
+
Puma::Plugin.create do
|
16
|
+
def start(launcher = nil)
|
17
|
+
launcher.events.on_booted do
|
18
|
+
require "appsignal"
|
19
|
+
if ::Puma.respond_to?(:stats)
|
20
|
+
Appsignal::Minutely.probes.register :puma, Appsignal::Hooks::PumaProbe
|
21
|
+
end
|
22
|
+
Appsignal.start
|
23
|
+
Appsignal.start_logger
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|