appsignal 2.11.0.beta.4-java → 2.11.0.beta.5-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 +57 -1
- data/CHANGELOG.md +12 -0
- data/README.md +4 -4
- data/Rakefile +16 -4
- data/appsignal.gemspec +1 -1
- data/build_matrix.yml +2 -2
- data/ext/Rakefile +2 -0
- data/ext/agent.yml +19 -19
- data/ext/base.rb +7 -0
- data/ext/extconf.rb +2 -0
- data/lib/appsignal.rb +1 -0
- data/lib/appsignal/auth_check.rb +4 -2
- data/lib/appsignal/cli/diagnose.rb +1 -1
- data/lib/appsignal/config.rb +35 -2
- data/lib/appsignal/extension.rb +6 -5
- data/lib/appsignal/extension/jruby.rb +6 -5
- data/lib/appsignal/hooks.rb +23 -0
- data/lib/appsignal/hooks/active_job.rb +32 -9
- data/lib/appsignal/hooks/puma.rb +0 -1
- data/lib/appsignal/hooks/sidekiq.rb +0 -1
- data/lib/appsignal/probes.rb +7 -0
- data/lib/appsignal/probes/puma.rb +1 -1
- data/lib/appsignal/probes/sidekiq.rb +3 -1
- data/lib/appsignal/utils/deprecation_message.rb +1 -1
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/auth_check_spec.rb +23 -0
- data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
- data/spec/lib/appsignal/capistrano3_spec.rb +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +42 -0
- data/spec/lib/appsignal/config_spec.rb +21 -0
- data/spec/lib/appsignal/extension/jruby_spec.rb +31 -28
- data/spec/lib/appsignal/extension_install_failure_spec.rb +23 -0
- data/spec/lib/appsignal/hooks/activejob_spec.rb +44 -1
- data/spec/lib/appsignal/hooks_spec.rb +57 -0
- data/spec/lib/appsignal/marker_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/spec/support/helpers/config_helpers.rb +3 -2
- data/spec/support/helpers/transaction_helpers.rb +1 -1
- data/spec/support/testing.rb +19 -19
- metadata +6 -3
data/README.md
CHANGED
@@ -9,7 +9,7 @@ issues.
|
|
9
9
|
- [Ruby code documentation][ruby-doc]
|
10
10
|
- [Support][contact]
|
11
11
|
|
12
|
-
[](https://appsignal.semaphoreci.com/projects/appsignal-ruby)
|
13
13
|
[](http://badge.fury.io/rb/appsignal)
|
14
14
|
[](https://codeclimate.com/github/appsignal/appsignal)
|
15
15
|
|
@@ -183,7 +183,7 @@ installing the AppSignal C-extension.
|
|
183
183
|
# Gemfile
|
184
184
|
gem "appsignal",
|
185
185
|
:git => "https://github.com/appsignal/appsignal-ruby.git",
|
186
|
-
:branch => "
|
186
|
+
:branch => "main"
|
187
187
|
```
|
188
188
|
|
189
189
|
When you need to use a git source of the gem in your JRuby install, you'll need
|
@@ -242,12 +242,12 @@ a number of different Ruby versions.
|
|
242
242
|
|
243
243
|
This gem uses [Semantic Versioning][semver].
|
244
244
|
|
245
|
-
The `
|
245
|
+
The `main` branch corresponds to the current stable release of the gem.
|
246
246
|
|
247
247
|
The `develop` branch is used for development of features that will end up in
|
248
248
|
the next minor release.
|
249
249
|
|
250
|
-
Open a Pull Request on the `
|
250
|
+
Open a Pull Request on the `main` branch if you're fixing a bug. For new new
|
251
251
|
features, open a Pull Request on the `develop` branch.
|
252
252
|
|
253
253
|
Every stable and unstable release is tagged in git with a version tag.
|
data/Rakefile
CHANGED
@@ -70,7 +70,10 @@ namespace :build_matrix do
|
|
70
70
|
job = {
|
71
71
|
"name" => "Ruby #{ruby_version} for #{gem["gem"]}",
|
72
72
|
"env_vars" => env,
|
73
|
-
"commands" => [
|
73
|
+
"commands" => [
|
74
|
+
"./support/bundler_wrapper exec rake test",
|
75
|
+
"./support/bundler_wrapper exec rake test:failure"
|
76
|
+
]
|
74
77
|
}
|
75
78
|
if gem["gem"] == "no_dependencies"
|
76
79
|
ruby_primary_block["task"]["jobs"] << job
|
@@ -364,11 +367,20 @@ end
|
|
364
367
|
|
365
368
|
begin
|
366
369
|
require "rspec/core/rake_task"
|
370
|
+
is_jruby = defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
|
371
|
+
unless is_jruby
|
372
|
+
jruby_opts = "--exclude-pattern=spec/lib/appsignal/extension/jruby_spec.rb"
|
373
|
+
end
|
374
|
+
|
367
375
|
desc "Run the AppSignal gem test suite."
|
368
376
|
RSpec::Core::RakeTask.new :test do |t|
|
369
|
-
|
370
|
-
|
371
|
-
|
377
|
+
t.rspec_opts = jruby_opts
|
378
|
+
end
|
379
|
+
|
380
|
+
namespace :test do
|
381
|
+
desc "Run the Appsignal gem test in an extension failure scenario"
|
382
|
+
RSpec::Core::RakeTask.new :failure do |t|
|
383
|
+
t.rspec_opts = "#{jruby_opts} --tag extension_installation_failure"
|
372
384
|
end
|
373
385
|
end
|
374
386
|
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
data/appsignal.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |gem| # rubocop:disable Metrics/BlockLength
|
|
29
29
|
gem.metadata = {
|
30
30
|
"bug_tracker_uri" => "https://github.com/appsignal/appsignal-ruby/issues",
|
31
31
|
"changelog_uri" =>
|
32
|
-
"https://github.com/appsignal/appsignal-ruby/blob/
|
32
|
+
"https://github.com/appsignal/appsignal-ruby/blob/main/CHANGELOG.md",
|
33
33
|
"documentation_uri" => "https://docs.appsignal.com/ruby/",
|
34
34
|
"homepage_uri" => "https://docs.appsignal.com/ruby/",
|
35
35
|
"source_code_uri" => "https://github.com/appsignal/appsignal-ruby"
|
data/build_matrix.yml
CHANGED
@@ -10,8 +10,8 @@ semaphore: # Default `.semaphore/semaphore.yml` contents
|
|
10
10
|
# Cancel all running and queued workflows before this one
|
11
11
|
auto_cancel:
|
12
12
|
running:
|
13
|
-
# Ignore
|
14
|
-
when: "branch != '
|
13
|
+
# Ignore main AND develop branch as we want it to build all workflows
|
14
|
+
when: "branch != 'main' AND branch != 'develop'"
|
15
15
|
|
16
16
|
global_job_config:
|
17
17
|
env_vars:
|
data/ext/Rakefile
CHANGED
data/ext/agent.yml
CHANGED
@@ -1,70 +1,70 @@
|
|
1
1
|
---
|
2
|
-
version:
|
2
|
+
version: c8f8185
|
3
3
|
mirrors:
|
4
4
|
- https://appsignal-agent-releases.global.ssl.fastly.net
|
5
5
|
- https://d135dj0rjqvssy.cloudfront.net
|
6
6
|
triples:
|
7
7
|
x86_64-darwin:
|
8
8
|
static:
|
9
|
-
checksum:
|
9
|
+
checksum: 8fad088047d8c73e5c0cf9213c20873ad591881d4f7059b178d8eeb89255f73e
|
10
10
|
filename: appsignal-x86_64-darwin-all-static.tar.gz
|
11
11
|
dynamic:
|
12
|
-
checksum:
|
12
|
+
checksum: 9a26f0dc170d38b068f66aaa016772f9e32e5fea99dc57bb9dfbc5f0a41dec89
|
13
13
|
filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
|
14
14
|
universal-darwin:
|
15
15
|
static:
|
16
|
-
checksum:
|
16
|
+
checksum: 8fad088047d8c73e5c0cf9213c20873ad591881d4f7059b178d8eeb89255f73e
|
17
17
|
filename: appsignal-x86_64-darwin-all-static.tar.gz
|
18
18
|
dynamic:
|
19
|
-
checksum:
|
19
|
+
checksum: 9a26f0dc170d38b068f66aaa016772f9e32e5fea99dc57bb9dfbc5f0a41dec89
|
20
20
|
filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
|
21
21
|
i686-linux:
|
22
22
|
static:
|
23
|
-
checksum:
|
23
|
+
checksum: 0e8c4436684824a325fa1b581f6fad88598c529307b2b5ad0cc2620d22d2782f
|
24
24
|
filename: appsignal-i686-linux-all-static.tar.gz
|
25
25
|
dynamic:
|
26
|
-
checksum:
|
26
|
+
checksum: d0fc35643b36b368a985961ea1c68c3204927f9fed412fde64d81b04081651ff
|
27
27
|
filename: appsignal-i686-linux-all-dynamic.tar.gz
|
28
28
|
x86-linux:
|
29
29
|
static:
|
30
|
-
checksum:
|
30
|
+
checksum: 0e8c4436684824a325fa1b581f6fad88598c529307b2b5ad0cc2620d22d2782f
|
31
31
|
filename: appsignal-i686-linux-all-static.tar.gz
|
32
32
|
dynamic:
|
33
|
-
checksum:
|
33
|
+
checksum: d0fc35643b36b368a985961ea1c68c3204927f9fed412fde64d81b04081651ff
|
34
34
|
filename: appsignal-i686-linux-all-dynamic.tar.gz
|
35
35
|
i686-linux-musl:
|
36
36
|
static:
|
37
|
-
checksum:
|
37
|
+
checksum: 28b69e895da6b2a30402eed29cf8c3bbc4f647d6ce9cc5e0b11b4a771d7a1021
|
38
38
|
filename: appsignal-i686-linux-musl-all-static.tar.gz
|
39
39
|
x86-linux-musl:
|
40
40
|
static:
|
41
|
-
checksum:
|
41
|
+
checksum: 28b69e895da6b2a30402eed29cf8c3bbc4f647d6ce9cc5e0b11b4a771d7a1021
|
42
42
|
filename: appsignal-i686-linux-musl-all-static.tar.gz
|
43
43
|
x86_64-linux:
|
44
44
|
static:
|
45
|
-
checksum:
|
45
|
+
checksum: fb457dc39e005bb8f241e1e260bb9ea0460cf922db5e30f514dda8afa0bd57bc
|
46
46
|
filename: appsignal-x86_64-linux-all-static.tar.gz
|
47
47
|
dynamic:
|
48
|
-
checksum:
|
48
|
+
checksum: 55b26406ab0309905d5ad3aa34d1910fcc473f2a475ed5b3073d160a7ea68852
|
49
49
|
filename: appsignal-x86_64-linux-all-dynamic.tar.gz
|
50
50
|
x86_64-linux-musl:
|
51
51
|
static:
|
52
|
-
checksum:
|
52
|
+
checksum: cf469d6e3ee1dc6ccb9762a996355ecc407b9a906b9c0a0b6742363347ec9494
|
53
53
|
filename: appsignal-x86_64-linux-musl-all-static.tar.gz
|
54
54
|
dynamic:
|
55
|
-
checksum:
|
55
|
+
checksum: '0938eab03f2b00583a9b730743c68d3d350090a0ff96866b960a9c78a486a992'
|
56
56
|
filename: appsignal-x86_64-linux-musl-all-dynamic.tar.gz
|
57
57
|
x86_64-freebsd:
|
58
58
|
static:
|
59
|
-
checksum:
|
59
|
+
checksum: 5c50e4776dbd0defe7d99015650e85d7983222ea27bd7b586b4c92f7b8336eee
|
60
60
|
filename: appsignal-x86_64-freebsd-all-static.tar.gz
|
61
61
|
dynamic:
|
62
|
-
checksum:
|
62
|
+
checksum: 02cd3b26317100290a2cfac014db026a2607723127955da1e4ddd5b76591003a
|
63
63
|
filename: appsignal-x86_64-freebsd-all-dynamic.tar.gz
|
64
64
|
amd64-freebsd:
|
65
65
|
static:
|
66
|
-
checksum:
|
66
|
+
checksum: 5c50e4776dbd0defe7d99015650e85d7983222ea27bd7b586b4c92f7b8336eee
|
67
67
|
filename: appsignal-x86_64-freebsd-all-static.tar.gz
|
68
68
|
dynamic:
|
69
|
-
checksum:
|
69
|
+
checksum: 02cd3b26317100290a2cfac014db026a2607723127955da1e4ddd5b76591003a
|
70
70
|
filename: appsignal-x86_64-freebsd-all-dynamic.tar.gz
|
data/ext/base.rb
CHANGED
@@ -183,3 +183,10 @@ end
|
|
183
183
|
def http_proxy
|
184
184
|
Gem.configuration[:http_proxy] || ENV["http_proxy"] || ENV["HTTP_PROXY"]
|
185
185
|
end
|
186
|
+
|
187
|
+
# Fail the installation on purpose in a specific test environment.
|
188
|
+
def fail_install_on_purpose_in_test!
|
189
|
+
return unless ENV["_TEST_APPSIGNAL_EXTENSION_FAILURE"]
|
190
|
+
|
191
|
+
raise "AppSignal internal test failure"
|
192
|
+
end
|
data/ext/extconf.rb
CHANGED
data/lib/appsignal.rb
CHANGED
@@ -339,6 +339,7 @@ require "appsignal/auth_check"
|
|
339
339
|
require "appsignal/config"
|
340
340
|
require "appsignal/event_formatter"
|
341
341
|
require "appsignal/hooks"
|
342
|
+
require "appsignal/probes"
|
342
343
|
require "appsignal/marker"
|
343
344
|
require "appsignal/minutely"
|
344
345
|
require "appsignal/garbage_collection_profiler"
|
data/lib/appsignal/auth_check.rb
CHANGED
@@ -25,8 +25,10 @@ module Appsignal
|
|
25
25
|
def initialize(config, logger = nil)
|
26
26
|
@config = config
|
27
27
|
if logger # rubocop:disable Style/GuardClause
|
28
|
-
|
29
|
-
"
|
28
|
+
Appsignal::Utils::DeprecationMessage.message \
|
29
|
+
"`Appsignal::AuthCheck.new`'s `logger` argument will be removed " \
|
30
|
+
"in the next major version. Please configure the logger " \
|
31
|
+
"using `Appsignal.logger`."
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
@@ -371,7 +371,7 @@ module Appsignal
|
|
371
371
|
end
|
372
372
|
|
373
373
|
def print_installation_result_report(report)
|
374
|
-
report = report.fetch("
|
374
|
+
report = report.fetch("result", {})
|
375
375
|
puts " Installation result"
|
376
376
|
puts " Status: #{report["status"]}"
|
377
377
|
puts " Message: #{report["message"]}" if report["message"]
|
data/lib/appsignal/config.rb
CHANGED
@@ -121,8 +121,41 @@ module Appsignal
|
|
121
121
|
:initial_config, :file_config, :env_config
|
122
122
|
attr_accessor :logger
|
123
123
|
|
124
|
-
|
124
|
+
# Initialize a new configuration object for AppSignal.
|
125
|
+
#
|
126
|
+
# If this is manually initialized, and not by {Appsignal.start}, it needs
|
127
|
+
# to be assigned to the {Appsignal.config} attribute.
|
128
|
+
#
|
129
|
+
# @example
|
130
|
+
# require "appsignal"
|
131
|
+
# Appsignal.config = Appsignal::Config.new(
|
132
|
+
# app_path,
|
133
|
+
# "production"
|
134
|
+
# )
|
135
|
+
# Appsignal.start
|
136
|
+
#
|
137
|
+
# @param root_path [String] Root path of the app.
|
138
|
+
# @param env [String] The environment to load when AppSignal is started. It
|
139
|
+
# will look for an environment with this name in the `config/appsignal.yml`
|
140
|
+
# config file.
|
141
|
+
# @param initial_config [Hash<String, Object>] The initial configuration to
|
142
|
+
# use. This will be overwritten by the file config and environment
|
143
|
+
# variables config.
|
144
|
+
# @param logger [Logger] The logger to use for the AppSignal gem. This is
|
145
|
+
# used by the configuration class only. Default: {Appsignal.logger}. See
|
146
|
+
# also {Appsignal.start_logger}.
|
147
|
+
# @param config_file [String] Custom config file location. Default
|
148
|
+
# `config/appsignal.yml`.
|
149
|
+
#
|
150
|
+
# @see https://docs.appsignal.com/ruby/configuration/
|
151
|
+
# Configuration documentation
|
152
|
+
# @see https://docs.appsignal.com/ruby/configuration/load-order.html
|
153
|
+
# Configuration load order
|
154
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/integrating-appsignal.html
|
155
|
+
# How to integrate AppSignal manually
|
156
|
+
def initialize(root_path, env, initial_config = {}, logger = Appsignal.logger, config_file = nil)
|
125
157
|
@root_path = root_path
|
158
|
+
@config_file = config_file
|
126
159
|
@logger = logger
|
127
160
|
@valid = false
|
128
161
|
@config_hash = Hash[DEFAULT_CONFIG]
|
@@ -288,7 +321,7 @@ module Appsignal
|
|
288
321
|
" Skipping file config.\n" \
|
289
322
|
"File: #{config_file.inspect}\n" \
|
290
323
|
"#{e.class.name}: #{e}"
|
291
|
-
|
324
|
+
Kernel.warn "appsignal: #{message}"
|
292
325
|
logger.error "#{message}\n#{e.backtrace.join("\n")}"
|
293
326
|
nil
|
294
327
|
end
|
data/lib/appsignal/extension.rb
CHANGED
@@ -10,11 +10,12 @@ begin
|
|
10
10
|
require "appsignal_extension"
|
11
11
|
Appsignal.extension_loaded = true
|
12
12
|
end
|
13
|
-
rescue LoadError =>
|
14
|
-
|
15
|
-
"
|
16
|
-
|
17
|
-
)
|
13
|
+
rescue LoadError => error
|
14
|
+
error_message = "ERROR: AppSignal failed to load extension. " \
|
15
|
+
"Please run `appsignal diagnose` and email us at support@appsignal.com\n" \
|
16
|
+
"#{error.class}: #{error.message}"
|
17
|
+
Appsignal.logger.error(error_message)
|
18
|
+
Kernel.warn error_message
|
18
19
|
Appsignal.extension_loaded = false
|
19
20
|
end
|
20
21
|
|
@@ -179,11 +179,12 @@ module Appsignal
|
|
179
179
|
:appsignal_string
|
180
180
|
|
181
181
|
Appsignal.extension_loaded = true
|
182
|
-
rescue LoadError =>
|
183
|
-
|
184
|
-
"
|
185
|
-
"
|
186
|
-
)
|
182
|
+
rescue LoadError => error
|
183
|
+
error_message = "ERROR: AppSignal failed to load extension. " \
|
184
|
+
"Please run `appsignal diagnose` and email us at support@appsignal.com\n" \
|
185
|
+
"#{error.class}: #{error.message}"
|
186
|
+
Appsignal.logger.error(error_message)
|
187
|
+
Kernel.warn error_message
|
187
188
|
Appsignal.extension_loaded = false
|
188
189
|
end
|
189
190
|
|
data/lib/appsignal/hooks.rb
CHANGED
@@ -69,6 +69,29 @@ module Appsignal
|
|
69
69
|
text.size > 200 ? "#{text[0...197]}..." : text
|
70
70
|
end
|
71
71
|
end
|
72
|
+
|
73
|
+
# Alias Probes constants that have moved to their own module in version
|
74
|
+
# 2.11.0.
|
75
|
+
def self.const_missing(name)
|
76
|
+
case name
|
77
|
+
when :SidekiqProbe
|
78
|
+
callers = caller
|
79
|
+
Appsignal::Utils::DeprecationMessage.message \
|
80
|
+
"The constant Appsignal::Hooks::SidekiqProbe has been deprecated. " \
|
81
|
+
"Please update the constant name to Appsignal::Probes::SidekiqProbe " \
|
82
|
+
"in the following file to remove this message.\n#{callers.first}"
|
83
|
+
Appsignal::Probes::SidekiqProbe
|
84
|
+
when :PumaProbe
|
85
|
+
callers = caller
|
86
|
+
Appsignal::Utils::DeprecationMessage.message \
|
87
|
+
"The constant Appsignal::Hooks::PumaProbe has been deprecated. " \
|
88
|
+
"Please update the constant name to Appsignal::Probes::PumaProbe " \
|
89
|
+
"in the following file to remove this message.\n#{callers.first}"
|
90
|
+
Appsignal::Probes::PumaProbe
|
91
|
+
else
|
92
|
+
super
|
93
|
+
end
|
94
|
+
end
|
72
95
|
end
|
73
96
|
end
|
74
97
|
|
@@ -41,8 +41,6 @@ module Appsignal
|
|
41
41
|
transaction.set_error(exception)
|
42
42
|
raise exception
|
43
43
|
ensure
|
44
|
-
tags = ActiveJobHelpers.tags_for_job(job)
|
45
|
-
|
46
44
|
if transaction
|
47
45
|
transaction.params =
|
48
46
|
Appsignal::Utils::HashSanitizer.sanitize(
|
@@ -50,7 +48,7 @@ module Appsignal
|
|
50
48
|
Appsignal.config[:filter_parameters]
|
51
49
|
)
|
52
50
|
|
53
|
-
transaction_tags =
|
51
|
+
transaction_tags = ActiveJobHelpers.transaction_tags_for(job)
|
54
52
|
transaction_tags["active_job_id"] = job["job_id"]
|
55
53
|
provider_job_id = job["provider_job_id"]
|
56
54
|
if provider_job_id
|
@@ -71,12 +69,15 @@ module Appsignal
|
|
71
69
|
end
|
72
70
|
end
|
73
71
|
|
74
|
-
|
75
|
-
|
76
|
-
|
72
|
+
metrics = ActiveJobHelpers.metrics_for(job)
|
73
|
+
metrics.each do |(metric_name, tags)|
|
74
|
+
if job_status
|
75
|
+
ActiveJobHelpers.increment_counter metric_name, 1,
|
76
|
+
tags.merge(:status => job_status)
|
77
|
+
end
|
78
|
+
ActiveJobHelpers.increment_counter metric_name, 1,
|
79
|
+
tags.merge(:status => :processed)
|
77
80
|
end
|
78
|
-
ActiveJobHelpers.increment_counter "queue_job_count", 1,
|
79
|
-
tags.merge(:status => :processed)
|
80
81
|
end
|
81
82
|
end
|
82
83
|
|
@@ -96,7 +97,29 @@ module Appsignal
|
|
96
97
|
end
|
97
98
|
end
|
98
99
|
|
99
|
-
|
100
|
+
# Returns an array of metrics with tags used to report the job metrics
|
101
|
+
#
|
102
|
+
# If job ONLY has a queue, it will return `queue_job_count` with tags.
|
103
|
+
# If job has a queue AND priority, it will ALSO return
|
104
|
+
# `queue_priority_job_count` with tags.
|
105
|
+
#
|
106
|
+
# @return [Array] Array of metrics with tags to report.
|
107
|
+
def self.metrics_for(job)
|
108
|
+
tags = { :queue => job["queue_name"] }
|
109
|
+
metrics = [["queue_job_count", tags]]
|
110
|
+
|
111
|
+
priority = job["priority"]
|
112
|
+
if priority
|
113
|
+
metrics << [
|
114
|
+
"queue_priority_job_count",
|
115
|
+
tags.merge(:priority => priority)
|
116
|
+
]
|
117
|
+
end
|
118
|
+
|
119
|
+
metrics
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.transaction_tags_for(job)
|
100
123
|
tags = {}
|
101
124
|
queue = job["queue_name"]
|
102
125
|
tags[:queue] = queue if queue
|
data/lib/appsignal/hooks/puma.rb
CHANGED