appsignal 4.1.3 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +121 -0
- data/build_matrix.yml +12 -0
- data/lib/appsignal/cli/diagnose.rb +11 -5
- data/lib/appsignal/cli/install.rb +46 -12
- data/lib/appsignal/config.rb +58 -4
- data/lib/appsignal/extension/jruby.rb +3 -2
- data/lib/appsignal/helpers/instrumentation.rb +12 -3
- data/lib/appsignal/loaders/hanami.rb +8 -1
- data/lib/appsignal/logger.rb +8 -3
- data/lib/appsignal/rack/hanami_middleware.rb +14 -1
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +114 -5
- data/resources/appsignal.rb.erb +22 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83c3f6a3607f3e28d1b95b790b1eec081673e596db8ed02a868bc31eb54fe884
|
4
|
+
data.tar.gz: a2f57f3c3604fb05953949114cf2e3a315c0ab61af40c0d50ee59a2a0c23a87a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 108fd4431a1fd08f619ff084b8304dddd25bfc1cadf218265bdc12f7dc3e7609a551daa2b6e1a9c433dcdca5a51bccf5c916be12700bdd880b03aca422d03ca0
|
7
|
+
data.tar.gz: 1243f5f9894c7c7750bbd991a4e9dc7b6b8c5d80f4fd68e77798cccb97b41dc7efd7039e4e3176178f9fda0804c67643f2770098d34ff8c4105f8005320a6799
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,126 @@
|
|
1
1
|
# AppSignal for Ruby gem Changelog
|
2
2
|
|
3
|
+
## 4.2.0
|
4
|
+
|
5
|
+
_Published on 2024-11-13._
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
- Add `config/appsignal.rb` config file support. When a `config/appsignal.rb` file is present in the app, the Ruby gem will automatically load it when `Appsignal.start` is called.
|
10
|
+
|
11
|
+
The `config/appsignal.rb` config file is a replacement for the `config/appsignal.yml` config file. When both files are present, only the `config/appsignal.rb` config file is loaded when the configuration file is automatically loaded by AppSignal when the configuration file is automatically loaded by AppSignal.
|
12
|
+
|
13
|
+
Example `config/appsignal.rb` config file:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
# config/appsignal.rb
|
17
|
+
Appsignal.configure do |config|
|
18
|
+
config.name = "My app name"
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
To configure different option values for environments in the `config/appsignal.rb` config file, use if-statements:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
# config/appsignal.rb
|
26
|
+
Appsignal.configure do |config|
|
27
|
+
config.name = "My app name"
|
28
|
+
if config.env == "production"
|
29
|
+
config.ignore_actions << "My production action"
|
30
|
+
end
|
31
|
+
if config.env == "staging"
|
32
|
+
config.ignore_actions << "My staging action"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
(minor [f81248bc](https://github.com/appsignal/appsignal-ruby/commit/f81248bc9c557197a0dd123c6d5958f21c11af9d), [48d16c7a](https://github.com/appsignal/appsignal-ruby/commit/48d16c7ab4dbc35ac3d56ecf042ca165d609bb64))
|
38
|
+
- Add the `config/appsignal.rb` Ruby config file method to installer, `appsignal install`. (patch [0d2e2bde](https://github.com/appsignal/appsignal-ruby/commit/0d2e2bde5da510f0d339673cdcdb9f79030acf59))
|
39
|
+
- Add `Appsignal.set_empty_params!` helper method. This helper method can be used to unset parameters on a transaction and to prevent the Appsignal instrumentation from adding parameters to a transaction.
|
40
|
+
|
41
|
+
Example usage:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
class PaymentsController < ApplicationController
|
45
|
+
def create
|
46
|
+
Appsignal.set_empty_params!
|
47
|
+
|
48
|
+
# Do things with sensitive parameters
|
49
|
+
end
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
When `Appsignal.add_params` is called afterward, the "empty parameters" state is cleared and any AppSignal instrumentation (if called afterward) will also add parameters again.
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
# Example: Unset parameters when set
|
57
|
+
Appsignal.add_params("abc" => "def")
|
58
|
+
# Parameters: { "abc" => "def" }
|
59
|
+
Appsignal.set_empty_params!
|
60
|
+
# Parameters: {}
|
61
|
+
|
62
|
+
# Example: When AppSignal instrumentation sets parameters:
|
63
|
+
Appsignal.set_empty_params!
|
64
|
+
# Parameters: {}
|
65
|
+
# Pseudo example code:
|
66
|
+
Appsignal::Instrumentation::SomeLibrary.new.add_params("xyz" => "...")
|
67
|
+
# Parameters: {}
|
68
|
+
|
69
|
+
# Example: Set parameters after them being unset previously
|
70
|
+
Appsignal.set_empty_params!
|
71
|
+
# Parameters: {}
|
72
|
+
Appsignal.add_params("abc" => "def")
|
73
|
+
# Parameters: { "abc" => "def" }
|
74
|
+
```
|
75
|
+
|
76
|
+
(patch [20a8050e](https://github.com/appsignal/appsignal-ruby/commit/20a8050e63605f08e9377dda84b3a422810dd49a), [23627cd7](https://github.com/appsignal/appsignal-ruby/commit/23627cd7e7c2b2939c43701228e77aa14eae5c68))
|
77
|
+
- Add `Appsignal.configure` context `env?` helper method. Check if the loaded environment matches the given environment using the `.env?(:env_name)` helper.
|
78
|
+
|
79
|
+
Example:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
Appsignal.configure do |config|
|
83
|
+
# Symbols work as the argument
|
84
|
+
if config.env?(:production)
|
85
|
+
config.ignore_actions << "My production action"
|
86
|
+
end
|
87
|
+
|
88
|
+
# Strings also work as the argument
|
89
|
+
if config.env?("staging")
|
90
|
+
config.ignore_actions << "My staging action"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
(patch [8b234cae](https://github.com/appsignal/appsignal-ruby/commit/8b234caee4c29f9550c4dc77d02ebd21f8dbfa30))
|
96
|
+
- Allow for default attributes to be given when initialising a `Logger` instance:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
order_logger = Appsignal::Logger.new("app", attributes: { order_id: 123 })
|
100
|
+
```
|
101
|
+
|
102
|
+
All log lines reported by this logger will contain the given attribute. Attributes given when reporting the log line will be merged with the default attributes for the logger, with those in the log line taking priority.
|
103
|
+
|
104
|
+
(patch [27e05af6](https://github.com/appsignal/appsignal-ruby/commit/27e05af6cb1e1ebca1fd6e8038da290f42db2bdb), [8be7c791](https://github.com/appsignal/appsignal-ruby/commit/8be7c7912eea4d3df74f1ca8808b7d6e8802f550))
|
105
|
+
|
106
|
+
### Changed
|
107
|
+
|
108
|
+
- Read the Hanami Action name without metaprogramming in Hanami 2.2 and newer. This makes our instrumentation more stable whenever something changes in future Hanami releases. (patch [c6848504](https://github.com/appsignal/appsignal-ruby/commit/c68485043feee13a49400f57c9a77d48f670f0f2))
|
109
|
+
- Ignore these Hanami errors by default:
|
110
|
+
|
111
|
+
- Hanami::Router::NotAllowedError (for example: sending a GET request to POST endpoint)
|
112
|
+
- Hanami::Router::NotFoundError
|
113
|
+
|
114
|
+
They are usually errors you don't want to be notified about, so we ignore them by default now.
|
115
|
+
|
116
|
+
Customize the `ignore_errors` config option to continue receiving these errors.
|
117
|
+
|
118
|
+
(patch [f1500987](https://github.com/appsignal/appsignal-ruby/commit/f1500987b7b73ab2873202ea7301f2cfb19acdc7))
|
119
|
+
|
120
|
+
### Fixed
|
121
|
+
|
122
|
+
- Fix request parameter reporting for Hanami 2.2. (patch [ca22ed54](https://github.com/appsignal/appsignal-ruby/commit/ca22ed54de513773c5ee387f28ad98ee8f301627))
|
123
|
+
|
3
124
|
## 4.1.3
|
4
125
|
|
5
126
|
_Published on 2024-11-07._
|
data/build_matrix.yml
CHANGED
@@ -85,6 +85,7 @@ matrix:
|
|
85
85
|
- "rails-7.0"
|
86
86
|
- "rails-7.1"
|
87
87
|
- "rails-7.2"
|
88
|
+
- "rails-8.0"
|
88
89
|
|
89
90
|
ruby:
|
90
91
|
- ruby: "3.3.4"
|
@@ -120,6 +121,12 @@ matrix:
|
|
120
121
|
- "3.2.5"
|
121
122
|
- "3.1.6"
|
122
123
|
- "3.0.7"
|
124
|
+
- gem: "hanami-2.2"
|
125
|
+
only:
|
126
|
+
ruby:
|
127
|
+
- "3.3.4"
|
128
|
+
- "3.2.5"
|
129
|
+
- "3.1.6"
|
123
130
|
- gem: "http5"
|
124
131
|
- gem: "padrino"
|
125
132
|
- gem: "psych-3"
|
@@ -179,6 +186,11 @@ matrix:
|
|
179
186
|
- "3.2.5"
|
180
187
|
- "3.1.6"
|
181
188
|
- "jruby-9.4.7.0"
|
189
|
+
- gem: "rails-8.0"
|
190
|
+
only:
|
191
|
+
ruby:
|
192
|
+
- "3.3.4"
|
193
|
+
- "3.2.5"
|
182
194
|
- gem: "sequel"
|
183
195
|
- gem: "sinatra"
|
184
196
|
- gem: "webmachine2"
|
@@ -188,15 +188,16 @@ module Appsignal
|
|
188
188
|
end
|
189
189
|
|
190
190
|
def configure_appsignal(options)
|
191
|
+
env_option = options.fetch(:environment, nil)
|
191
192
|
# Try and load the Rails app, if any.
|
192
193
|
# This will configure AppSignal through the config file or an
|
193
194
|
# initializer.
|
194
|
-
require_rails_app_if_present
|
195
|
+
require_rails_app_if_present(env_option)
|
195
196
|
|
196
|
-
#
|
197
|
-
Appsignal.
|
198
|
-
Appsignal.config.write_to_environment
|
197
|
+
# No config loaded yet, try loading as normal
|
198
|
+
Appsignal._load_config!(env_option) unless Appsignal.config
|
199
199
|
Appsignal._start_logger
|
200
|
+
Appsignal.config.write_to_environment
|
200
201
|
Appsignal.internal_logger.info("Starting AppSignal diagnose")
|
201
202
|
end
|
202
203
|
|
@@ -631,9 +632,12 @@ module Appsignal
|
|
631
632
|
puts "\n"
|
632
633
|
end
|
633
634
|
|
634
|
-
def require_rails_app_if_present
|
635
|
+
def require_rails_app_if_present(env_option)
|
635
636
|
return unless rails_present?
|
636
637
|
|
638
|
+
# Set the environment given as an option to the diagnose CLI so the
|
639
|
+
# Rails app uses it when loaded.
|
640
|
+
ENV["_APPSIGNAL_CONFIG_FILE_ENV"] = env_option
|
637
641
|
# Mark app as Rails app
|
638
642
|
data[:app][:rails] = true
|
639
643
|
# Manually require the railtie, because it wasn't loaded when the CLI
|
@@ -649,6 +653,8 @@ module Appsignal
|
|
649
653
|
puts error.backtrace
|
650
654
|
data[:app][:load_error] =
|
651
655
|
"#{error.class}: #{error.message}\n#{error.backtrace.join("\n")}"
|
656
|
+
ensure
|
657
|
+
ENV.delete("_APPSIGNAL_CONFIG_FILE_ENV")
|
652
658
|
end
|
653
659
|
|
654
660
|
def rails_present?
|
@@ -229,35 +229,49 @@ module Appsignal
|
|
229
229
|
done_notice
|
230
230
|
end
|
231
231
|
|
232
|
-
def configure(config, environments, name_overwritten)
|
232
|
+
def configure(config, environments, name_overwritten) # rubocop:disable Metrics/AbcSize
|
233
233
|
install_for_capistrano
|
234
234
|
|
235
235
|
ENV["APPSIGNAL_APP_ENV"] = "development"
|
236
236
|
|
237
237
|
puts "How do you want to configure AppSignal?"
|
238
|
-
puts " (1) a config file"
|
239
|
-
puts " (2)
|
238
|
+
puts " (1) a Ruby config file"
|
239
|
+
puts " (2) a YAML config file (legacy)"
|
240
|
+
puts " (3) environment variables"
|
240
241
|
puts
|
241
242
|
puts " See our docs for information on the different configuration methods: "
|
242
243
|
puts " https://docs.appsignal.com/ruby/configuration.html"
|
243
244
|
puts
|
244
|
-
loop do
|
245
|
-
print " Choose (1
|
245
|
+
loop do # rubocop:disable Metrics/BlockLength
|
246
|
+
print " Choose (1-3): "
|
246
247
|
case ask_for_input
|
247
248
|
when "1"
|
248
249
|
puts
|
249
|
-
print "Writing config file"
|
250
|
+
print "Writing Ruby config file"
|
250
251
|
periods
|
251
252
|
puts
|
252
|
-
|
253
|
-
write_config_file(
|
253
|
+
write_ruby_config_file(
|
254
254
|
:push_api_key => config[:push_api_key],
|
255
255
|
:app_name => config[:name],
|
256
256
|
:environments => environments
|
257
257
|
)
|
258
|
+
puts colorize " Config file written to config/appsignal.rb", :green
|
258
259
|
puts
|
259
260
|
break
|
260
261
|
when "2"
|
262
|
+
puts
|
263
|
+
print "Writing YAML config file"
|
264
|
+
periods
|
265
|
+
puts
|
266
|
+
write_yaml_config_file(
|
267
|
+
:push_api_key => config[:push_api_key],
|
268
|
+
:app_name => config[:name],
|
269
|
+
:environments => environments
|
270
|
+
)
|
271
|
+
puts colorize " Config file written to config/appsignal.yml", :green
|
272
|
+
puts
|
273
|
+
break
|
274
|
+
when "3"
|
261
275
|
ENV["APPSIGNAL_ACTIVE"] = "true"
|
262
276
|
ENV["APPSIGNAL_PUSH_API_KEY"] = config[:push_api_key]
|
263
277
|
ENV["APPSIGNAL_APP_NAME"] = config[:name]
|
@@ -325,17 +339,37 @@ module Appsignal
|
|
325
339
|
).map { |o| File.basename(o, ".rb") }.sort - EXCLUDED_ENVIRONMENTS
|
326
340
|
end
|
327
341
|
|
328
|
-
def
|
329
|
-
|
342
|
+
def write_ruby_config_file(data)
|
343
|
+
template = File.join(
|
344
|
+
File.dirname(__FILE__),
|
345
|
+
"../../../resources/appsignal.rb.erb"
|
346
|
+
)
|
347
|
+
write_config_file(
|
348
|
+
template,
|
349
|
+
File.join(Dir.pwd, "config/appsignal.rb"),
|
350
|
+
data
|
351
|
+
)
|
352
|
+
end
|
353
|
+
|
354
|
+
def write_yaml_config_file(data)
|
355
|
+
template = File.join(
|
330
356
|
File.dirname(__FILE__),
|
331
357
|
"../../../resources/appsignal.yml.erb"
|
332
358
|
)
|
333
|
-
|
359
|
+
write_config_file(
|
360
|
+
template,
|
361
|
+
File.join(Dir.pwd, "config/appsignal.yml"),
|
362
|
+
data
|
363
|
+
)
|
364
|
+
end
|
365
|
+
|
366
|
+
def write_config_file(template_path, path, data)
|
367
|
+
file_contents = File.read(template_path)
|
334
368
|
template = ERB.new(file_contents, :trim_mode => "-")
|
335
369
|
config = template.result(OpenStruct.new(data).instance_eval { binding })
|
336
370
|
|
337
371
|
FileUtils.mkdir_p(File.join(Dir.pwd, "config"))
|
338
|
-
File.write(
|
372
|
+
File.write(path, config)
|
339
373
|
end
|
340
374
|
|
341
375
|
def new_config
|
data/lib/appsignal/config.rb
CHANGED
@@ -35,6 +35,7 @@ module Appsignal
|
|
35
35
|
def self.determine_env(initial_env = nil)
|
36
36
|
[
|
37
37
|
initial_env,
|
38
|
+
ENV.fetch("_APPSIGNAL_CONFIG_FILE_ENV", nil), # PRIVATE ENV var used by the diagnose CLI
|
38
39
|
ENV.fetch("APPSIGNAL_APP_ENV", nil),
|
39
40
|
ENV.fetch("RAILS_ENV", nil),
|
40
41
|
ENV.fetch("RACK_ENV", nil)
|
@@ -53,6 +54,9 @@ module Appsignal
|
|
53
54
|
# Determine which root path AppSignal should initialize with.
|
54
55
|
# @api private
|
55
56
|
def self.determine_root_path
|
57
|
+
app_path_env_var = ENV.fetch("APPSIGNAL_APP_PATH", nil)
|
58
|
+
return app_path_env_var if app_path_env_var
|
59
|
+
|
56
60
|
loader_defaults.reverse.each do |loader_defaults|
|
57
61
|
root_path = loader_defaults[:root_path]
|
58
62
|
return root_path if root_path
|
@@ -61,6 +65,26 @@ module Appsignal
|
|
61
65
|
Dir.pwd
|
62
66
|
end
|
63
67
|
|
68
|
+
# @api private
|
69
|
+
class Context
|
70
|
+
DSL_FILENAME = "config/appsignal.rb"
|
71
|
+
|
72
|
+
attr_reader :env, :root_path
|
73
|
+
|
74
|
+
def initialize(env: nil, root_path: nil)
|
75
|
+
@env = env
|
76
|
+
@root_path = root_path
|
77
|
+
end
|
78
|
+
|
79
|
+
def dsl_config_file
|
80
|
+
File.join(root_path, DSL_FILENAME)
|
81
|
+
end
|
82
|
+
|
83
|
+
def dsl_config_file?
|
84
|
+
File.exist?(dsl_config_file)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
64
88
|
# @api private
|
65
89
|
DEFAULT_CONFIG = {
|
66
90
|
:activejob_report_errors => "all",
|
@@ -213,8 +237,10 @@ module Appsignal
|
|
213
237
|
# How to integrate AppSignal manually
|
214
238
|
def initialize(
|
215
239
|
root_path,
|
216
|
-
env
|
240
|
+
env,
|
241
|
+
load_yaml_file: true
|
217
242
|
)
|
243
|
+
@load_yaml_file = load_yaml_file
|
218
244
|
@root_path = root_path.to_s
|
219
245
|
@config_file_error = false
|
220
246
|
@config_file = config_file
|
@@ -269,8 +295,20 @@ module Appsignal
|
|
269
295
|
@initial_config[:env] = @env
|
270
296
|
|
271
297
|
# Load the config file if it exists
|
272
|
-
@
|
273
|
-
|
298
|
+
if @load_yaml_file
|
299
|
+
@file_config = load_from_disk || {}
|
300
|
+
merge(file_config)
|
301
|
+
elsif yml_config_file?
|
302
|
+
# When in a `config/appsignal.rb` file and it detects a
|
303
|
+
# `config/appsignal.yml` file.
|
304
|
+
# Only logged and printed on `Appsignal.start`.
|
305
|
+
message = "Both a Ruby and YAML configuration file are found. " \
|
306
|
+
"The `config/appsignal.yml` file is ignored when the " \
|
307
|
+
"config is loaded from `config/appsignal.rb`. Move all config to " \
|
308
|
+
"the `config/appsignal.rb` file and remove the " \
|
309
|
+
"`config/appsignal.yml` file."
|
310
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning(message)
|
311
|
+
end
|
274
312
|
|
275
313
|
# Load config from environment variables
|
276
314
|
@env_config = load_from_environment
|
@@ -435,6 +473,13 @@ module Appsignal
|
|
435
473
|
config_hash.transform_values(&:freeze)
|
436
474
|
end
|
437
475
|
|
476
|
+
# @api private
|
477
|
+
def yml_config_file?
|
478
|
+
return false unless config_file
|
479
|
+
|
480
|
+
File.exist?(config_file)
|
481
|
+
end
|
482
|
+
|
438
483
|
private
|
439
484
|
|
440
485
|
def logger
|
@@ -458,7 +503,7 @@ module Appsignal
|
|
458
503
|
end
|
459
504
|
|
460
505
|
def load_from_disk
|
461
|
-
return
|
506
|
+
return unless yml_config_file?
|
462
507
|
|
463
508
|
read_options = YAML::VERSION >= "4.0.0" ? { :aliases => true } : {}
|
464
509
|
configurations = YAML.load(ERB.new(File.read(config_file)).result, **read_options)
|
@@ -564,6 +609,15 @@ module Appsignal
|
|
564
609
|
@config.env
|
565
610
|
end
|
566
611
|
|
612
|
+
# Returns true if the given environment name matches the loaded
|
613
|
+
# environment name.
|
614
|
+
#
|
615
|
+
# @param given_env [String, Symbol]
|
616
|
+
# @return [TrueClass, FalseClass]
|
617
|
+
def env?(given_env)
|
618
|
+
env == given_env.to_s
|
619
|
+
end
|
620
|
+
|
567
621
|
def activate_if_environment(*envs)
|
568
622
|
self.active = envs.map(&:to_s).include?(env)
|
569
623
|
end
|
@@ -80,7 +80,7 @@ module Appsignal
|
|
80
80
|
|
81
81
|
# Logging methods
|
82
82
|
attach_function :appsignal_log,
|
83
|
-
[:appsignal_string, :int32, :appsignal_string, :pointer],
|
83
|
+
[:appsignal_string, :int32, :int32, :appsignal_string, :pointer],
|
84
84
|
:void
|
85
85
|
|
86
86
|
# Transaction methods
|
@@ -273,10 +273,11 @@ module Appsignal
|
|
273
273
|
make_ruby_string state if state[:len] > 0
|
274
274
|
end
|
275
275
|
|
276
|
-
def log(group, level, message, attributes)
|
276
|
+
def log(group, level, format, message, attributes)
|
277
277
|
appsignal_log(
|
278
278
|
make_appsignal_string(group),
|
279
279
|
level,
|
280
|
+
format,
|
280
281
|
make_appsignal_string(message),
|
281
282
|
attributes.pointer
|
282
283
|
)
|
@@ -556,11 +556,20 @@ module Appsignal
|
|
556
556
|
|
557
557
|
# Mark the parameters sample data to be set as an empty value.
|
558
558
|
#
|
559
|
-
#
|
560
|
-
#
|
559
|
+
# Use this helper to unset request parameters / background job arguments
|
560
|
+
# and not report any for this transaction.
|
561
|
+
#
|
562
|
+
# If parameters would normally be added by AppSignal instrumentations of
|
563
|
+
# libraries, these parameters will not be added to the Transaction.
|
564
|
+
#
|
565
|
+
# Calling {#add_params} after this helper will add new parameters to the
|
566
|
+
# transaction.
|
567
|
+
#
|
568
|
+
# @since 4.2.0
|
561
569
|
# @return [void]
|
562
570
|
#
|
563
|
-
# @see
|
571
|
+
# @see Transaction#set_empty_params!
|
572
|
+
# @see Transaction#set_params_if_nil
|
564
573
|
def set_empty_params!
|
565
574
|
return unless active?
|
566
575
|
return unless Appsignal::Transaction.current?
|
@@ -9,7 +9,11 @@ module Appsignal
|
|
9
9
|
hanami_app_config = ::Hanami.app.config
|
10
10
|
register_config_defaults(
|
11
11
|
:root_path => hanami_app_config.root.to_s,
|
12
|
-
:env => hanami_app_config.env
|
12
|
+
:env => hanami_app_config.env,
|
13
|
+
:ignore_errors => [
|
14
|
+
"Hanami::Router::NotAllowedError",
|
15
|
+
"Hanami::Router::NotFoundError"
|
16
|
+
]
|
13
17
|
)
|
14
18
|
end
|
15
19
|
|
@@ -23,9 +27,12 @@ module Appsignal
|
|
23
27
|
)
|
24
28
|
hanami_app_config.middleware.use(Appsignal::Rack::HanamiMiddleware)
|
25
29
|
|
30
|
+
return unless Gem::Version.new(Hanami::VERSION) < Gem::Version.new("2.2.0")
|
31
|
+
|
26
32
|
::Hanami::Action.prepend Appsignal::Loaders::HanamiLoader::HanamiIntegration
|
27
33
|
end
|
28
34
|
|
35
|
+
# Legacy instrumentation to set the action name in Hanami apps older than Hanami 2.2
|
29
36
|
module HanamiIntegration
|
30
37
|
def call(env)
|
31
38
|
super
|
data/lib/appsignal/logger.rb
CHANGED
@@ -25,15 +25,18 @@ module Appsignal
|
|
25
25
|
# Create a new logger instance
|
26
26
|
#
|
27
27
|
# @param group Name of the group for this logger.
|
28
|
-
# @param level
|
28
|
+
# @param level Minimum log level to report. Log lines below this level will be ignored.
|
29
|
+
# @param format Format to use to parse log line attributes.
|
30
|
+
# @param attributes Default attributes for all log lines.
|
29
31
|
# @return [void]
|
30
|
-
def initialize(group, level: INFO, format: PLAINTEXT)
|
32
|
+
def initialize(group, level: INFO, format: PLAINTEXT, attributes: {})
|
31
33
|
raise TypeError, "group must be a string" unless group.is_a? String
|
32
34
|
|
33
35
|
@group = group
|
34
36
|
@level = level
|
35
37
|
@format = format
|
36
38
|
@mutex = Mutex.new
|
39
|
+
@default_attributes = attributes
|
37
40
|
end
|
38
41
|
|
39
42
|
# We support the various methods in the Ruby
|
@@ -156,8 +159,10 @@ module Appsignal
|
|
156
159
|
|
157
160
|
private
|
158
161
|
|
162
|
+
attr_reader :default_attributes
|
163
|
+
|
159
164
|
def add_with_attributes(severity, message, group, attributes)
|
160
|
-
Thread.current[:appsignal_logger_attributes] = attributes
|
165
|
+
Thread.current[:appsignal_logger_attributes] = default_attributes.merge(attributes)
|
161
166
|
add(severity, message, group)
|
162
167
|
ensure
|
163
168
|
Thread.current[:appsignal_logger_attributes] = nil
|
@@ -12,12 +12,25 @@ module Appsignal
|
|
12
12
|
|
13
13
|
private
|
14
14
|
|
15
|
+
HANAMI_ACTION_INSTANCE = "hanami.action_instance"
|
16
|
+
ROUTER_PARAMS = "router.params"
|
17
|
+
|
15
18
|
def add_transaction_metadata_after(transaction, request)
|
19
|
+
action_name = fetch_hanami_action(request.env)
|
20
|
+
transaction.set_action_if_nil(action_name) if action_name
|
16
21
|
transaction.add_params { params_for(request) }
|
17
22
|
end
|
18
23
|
|
19
24
|
def params_for(request)
|
20
|
-
|
25
|
+
request.env.fetch(ROUTER_PARAMS, nil)
|
26
|
+
end
|
27
|
+
|
28
|
+
def fetch_hanami_action(env)
|
29
|
+
# This env key is available in Hanami 2.2+
|
30
|
+
action_instance = env.fetch(HANAMI_ACTION_INSTANCE, nil)
|
31
|
+
return unless action_instance
|
32
|
+
|
33
|
+
action_instance.class.name
|
21
34
|
end
|
22
35
|
end
|
23
36
|
end
|
data/lib/appsignal/version.rb
CHANGED
data/lib/appsignal.rb
CHANGED
@@ -103,6 +103,13 @@ module Appsignal
|
|
103
103
|
return
|
104
104
|
end
|
105
105
|
|
106
|
+
if config_file_context?
|
107
|
+
internal_logger.warn(
|
108
|
+
"Ignoring call to Appsignal.start in config file context."
|
109
|
+
)
|
110
|
+
return
|
111
|
+
end
|
112
|
+
|
106
113
|
unless extension_loaded?
|
107
114
|
internal_logger.info("Not starting AppSignal, extension is not loaded")
|
108
115
|
return
|
@@ -110,9 +117,7 @@ module Appsignal
|
|
110
117
|
|
111
118
|
internal_logger.debug("Loading AppSignal gem")
|
112
119
|
|
113
|
-
|
114
|
-
@config.validate
|
115
|
-
|
120
|
+
_load_config!
|
116
121
|
_start_logger
|
117
122
|
|
118
123
|
if config.valid?
|
@@ -142,6 +147,41 @@ module Appsignal
|
|
142
147
|
end
|
143
148
|
end
|
144
149
|
|
150
|
+
# PRIVATE METHOD. DO NOT USE.
|
151
|
+
#
|
152
|
+
# @param env_var [String, NilClass] Used by diagnose CLI to pass through
|
153
|
+
# the environment CLI option value.
|
154
|
+
# @api private
|
155
|
+
def _load_config!(env_param = nil)
|
156
|
+
context = Appsignal::Config::Context.new(
|
157
|
+
:env => Config.determine_env(env_param),
|
158
|
+
:root_path => Config.determine_root_path
|
159
|
+
)
|
160
|
+
# If there's a config/appsignal.rb file
|
161
|
+
if context.dsl_config_file?
|
162
|
+
if config
|
163
|
+
# When calling `Appsignal.configure` from an app, not the
|
164
|
+
# `config/appsignal.rb` file, with also a Ruby config file present.
|
165
|
+
message = "The `Appsignal.configure` helper is called from within an " \
|
166
|
+
"app while a `#{context.dsl_config_file}` file is present. " \
|
167
|
+
"The `config/appsignal.rb` file is ignored when the " \
|
168
|
+
"config is loaded with `Appsignal.configure` from within an app. " \
|
169
|
+
"We recommend moving all config to the `config/appsignal.rb` file " \
|
170
|
+
"or the `Appsignal.configure` helper in the app."
|
171
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning(message)
|
172
|
+
else
|
173
|
+
# Load it when no config is present
|
174
|
+
load_dsl_config_file(context.dsl_config_file, env_param)
|
175
|
+
end
|
176
|
+
else
|
177
|
+
# Load config if no config file was found and no config is present yet
|
178
|
+
# This will load the config/appsignal.yml file automatically
|
179
|
+
@config ||= Config.new(context.root_path, context.env)
|
180
|
+
end
|
181
|
+
# Validate the config, if present
|
182
|
+
config&.validate
|
183
|
+
end
|
184
|
+
|
145
185
|
# Stop AppSignal's agent.
|
146
186
|
#
|
147
187
|
# Stops the AppSignal agent. Call this before the end of your program to
|
@@ -222,7 +262,7 @@ module Appsignal
|
|
222
262
|
# # Or for the environment given as an argument
|
223
263
|
# Appsignal.configure(:production)
|
224
264
|
#
|
225
|
-
# @param
|
265
|
+
# @param env_param [String, Symbol] The environment to load.
|
226
266
|
# @param root_path [String] The path to look the `config/appsignal.yml` config file in.
|
227
267
|
# Defaults to the current working directory.
|
228
268
|
# @yield [Config] Gives the {Config} instance to the block.
|
@@ -244,10 +284,28 @@ module Appsignal
|
|
244
284
|
else
|
245
285
|
@config = Config.new(
|
246
286
|
root_path_param || Config.determine_root_path,
|
247
|
-
Config.determine_env(env_param)
|
287
|
+
Config.determine_env(env_param),
|
288
|
+
# If in the context of an `config/appsignal.rb` config file, do not
|
289
|
+
# load the `config/appsignal.yml` file.
|
290
|
+
# The `.rb` file is a replacement for the `.yml` file so it shouldn't
|
291
|
+
# load both.
|
292
|
+
:load_yaml_file => !config_file_context?
|
248
293
|
)
|
249
294
|
end
|
250
295
|
|
296
|
+
# When calling `Appsignal.configure` from a Rails initializer and a YAML
|
297
|
+
# file is present. We will not load the YAML file in the future.
|
298
|
+
if !config_file_context? && config.yml_config_file?
|
299
|
+
message = "The `Appsignal.configure` helper is called while a " \
|
300
|
+
"`config/appsignal.yml` file is present. In future versions the " \
|
301
|
+
"`config/appsignal.yml` file will be ignored when loading the " \
|
302
|
+
"config. We recommend moving all config to the " \
|
303
|
+
"`config/appsignal.rb` file, or the `Appsignal.configure` helper " \
|
304
|
+
"in Rails initializer file, and remove the " \
|
305
|
+
"`config/appsignal.yml` file."
|
306
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning(message)
|
307
|
+
end
|
308
|
+
|
251
309
|
config_dsl = Appsignal::Config::ConfigDSL.new(config)
|
252
310
|
return unless block_given?
|
253
311
|
|
@@ -397,6 +455,11 @@ module Appsignal
|
|
397
455
|
config&.active? && extension_loaded?
|
398
456
|
end
|
399
457
|
|
458
|
+
# @api private
|
459
|
+
def dsl_config_file_loaded?
|
460
|
+
defined?(@dsl_config_file_loaded) ? true : false
|
461
|
+
end
|
462
|
+
|
400
463
|
private
|
401
464
|
|
402
465
|
def params_match_loaded_config?(env_param, root_path_param)
|
@@ -408,6 +471,52 @@ module Appsignal
|
|
408
471
|
(root_path_param.nil? || config.root_path == root_path_param)
|
409
472
|
end
|
410
473
|
|
474
|
+
# Load the `config/appsignal.rb` config file, if present.
|
475
|
+
#
|
476
|
+
# If the config file has already been loaded once and it's trying to be
|
477
|
+
# loaded more than once, which should never happen, it will not do
|
478
|
+
# anything.
|
479
|
+
def load_dsl_config_file(path, env_param = nil)
|
480
|
+
return if defined?(@dsl_config_file_loaded)
|
481
|
+
|
482
|
+
begin
|
483
|
+
ENV["_APPSIGNAL_CONFIG_FILE_CONTEXT"] = "true"
|
484
|
+
ENV["_APPSIGNAL_CONFIG_FILE_ENV"] = env_param if env_param
|
485
|
+
@dsl_config_file_loaded = true
|
486
|
+
require path
|
487
|
+
rescue => error
|
488
|
+
@config_file_error = error
|
489
|
+
message = "Not starting AppSignal because an error occurred while " \
|
490
|
+
"loading the AppSignal config file.\n" \
|
491
|
+
"File: #{path.inspect}\n" \
|
492
|
+
"#{error.class.name}: #{error}"
|
493
|
+
Kernel.warn "appsignal ERROR: #{message}"
|
494
|
+
internal_logger.error "#{message}\n#{error.backtrace.join("\n")}"
|
495
|
+
ensure
|
496
|
+
unless Appsignal.config
|
497
|
+
# Ensure _a config object_ is present, even if something went wrong
|
498
|
+
# loading it or the file is empty. In this config file context, see
|
499
|
+
# the context env vars, it will intentionally not load the YAML file.
|
500
|
+
Appsignal.configure
|
501
|
+
|
502
|
+
# Disable if no config was loaded from the file but it is present
|
503
|
+
config[:active] = false
|
504
|
+
end
|
505
|
+
|
506
|
+
# Disable on config file error
|
507
|
+
config[:active] = false if defined?(@config_file_error)
|
508
|
+
|
509
|
+
ENV.delete("_APPSIGNAL_CONFIG_FILE_CONTEXT")
|
510
|
+
ENV.delete("_APPSIGNAL_CONFIG_FILE_ENV")
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
# Returns true if we're currently in the `config/appsignal.rb` file
|
515
|
+
# context.
|
516
|
+
def config_file_context?
|
517
|
+
ENV.fetch("_APPSIGNAL_CONFIG_FILE_CONTEXT", nil) == "true"
|
518
|
+
end
|
519
|
+
|
411
520
|
def start_internal_stdout_logger
|
412
521
|
@internal_logger = Appsignal::Utils::IntegrationLogger.new($stdout)
|
413
522
|
internal_logger.formatter = log_formatter("appsignal")
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# AppSignal Ruby gem configuration
|
2
|
+
# Visit our documentation for a list of all available configuration options.
|
3
|
+
# https://docs.appsignal.com/ruby/configuration/options.html
|
4
|
+
Appsignal.configure do |config|
|
5
|
+
config.activate_if_environment(<%= environments.map(&:inspect).join(", ") %>)
|
6
|
+
config.name = <%= app_name.inspect %>
|
7
|
+
# The application's Push API key
|
8
|
+
# We recommend removing this line and setting this option with the
|
9
|
+
# APPSIGNAL_PUSH_API_KEY environment variable instead.
|
10
|
+
# https://docs.appsignal.com/ruby/configuration/options.html#option-push_api_key
|
11
|
+
config.push_api_key = "<%= push_api_key %>"
|
12
|
+
|
13
|
+
# Configure actions that should not be monitored by AppSignal.
|
14
|
+
# For more information see our docs:
|
15
|
+
# https://docs.appsignal.com/ruby/configuration/ignore-actions.html
|
16
|
+
# config.ignore_actions << "ApplicationController#isup"
|
17
|
+
|
18
|
+
# Configure errors that should not be recorded by AppSignal.
|
19
|
+
# For more information see our docs:
|
20
|
+
# https://docs.appsignal.com/ruby/configuration/ignore-errors.html
|
21
|
+
# config.ignore_errors << "MyCustomError"
|
22
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appsignal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2024-11-
|
13
|
+
date: 2024-11-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: logger
|
@@ -284,6 +284,7 @@ files:
|
|
284
284
|
- lib/appsignal/version.rb
|
285
285
|
- lib/puma/plugin/appsignal.rb
|
286
286
|
- lib/sequel/extensions/appsignal_integration.rb
|
287
|
+
- resources/appsignal.rb.erb
|
287
288
|
- resources/appsignal.yml.erb
|
288
289
|
- resources/cacert.pem
|
289
290
|
homepage: https://github.com/appsignal/appsignal-ruby
|