appsignal 4.8.6-java → 4.9.0-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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +49 -0
  3. data/appsignal.gemspec +2 -2
  4. data/build_matrix.yml +25 -0
  5. data/ext/base.rb +3 -7
  6. data/ext/extconf.rb +1 -1
  7. data/lib/appsignal/check_in/event.rb +5 -4
  8. data/lib/appsignal/cli/diagnose.rb +1 -1
  9. data/lib/appsignal/cli/helpers.rb +2 -2
  10. data/lib/appsignal/cli/install.rb +3 -3
  11. data/lib/appsignal/config.rb +44 -1
  12. data/lib/appsignal/environment.rb +1 -0
  13. data/lib/appsignal/extension/jruby.rb +6 -5
  14. data/lib/appsignal/extension.rb +1 -1
  15. data/lib/appsignal/helpers/instrumentation.rb +12 -12
  16. data/lib/appsignal/hooks/action_cable.rb +2 -2
  17. data/lib/appsignal/hooks/active_job.rb +42 -3
  18. data/lib/appsignal/hooks/delayed_job.rb +2 -1
  19. data/lib/appsignal/hooks/excon.rb +1 -1
  20. data/lib/appsignal/hooks/faraday.rb +21 -0
  21. data/lib/appsignal/hooks/http.rb +9 -0
  22. data/lib/appsignal/hooks/mongo_ruby_driver.rb +2 -1
  23. data/lib/appsignal/hooks/que.rb +7 -1
  24. data/lib/appsignal/hooks/resque.rb +5 -1
  25. data/lib/appsignal/hooks/shoryuken.rb +15 -1
  26. data/lib/appsignal/hooks/sidekiq.rb +14 -1
  27. data/lib/appsignal/hooks.rb +1 -0
  28. data/lib/appsignal/integrations/action_cable.rb +1 -1
  29. data/lib/appsignal/integrations/active_support_notifications.rb +19 -6
  30. data/lib/appsignal/integrations/delayed_job_plugin.rb +38 -1
  31. data/lib/appsignal/integrations/excon.rb +8 -0
  32. data/lib/appsignal/integrations/faraday.rb +51 -0
  33. data/lib/appsignal/integrations/http.rb +9 -0
  34. data/lib/appsignal/integrations/mongo_ruby_driver.rb +4 -2
  35. data/lib/appsignal/integrations/net_http.rb +7 -0
  36. data/lib/appsignal/integrations/object.rb +3 -3
  37. data/lib/appsignal/integrations/que.rb +68 -1
  38. data/lib/appsignal/integrations/rake.rb +1 -1
  39. data/lib/appsignal/integrations/resque.rb +20 -1
  40. data/lib/appsignal/integrations/shoryuken.rb +33 -1
  41. data/lib/appsignal/integrations/sidekiq.rb +73 -36
  42. data/lib/appsignal/integrations/webmachine.rb +1 -1
  43. data/lib/appsignal/logger.rb +4 -1
  44. data/lib/appsignal/rack/abstract_middleware.rb +1 -1
  45. data/lib/appsignal/rack/body_wrapper.rb +5 -5
  46. data/lib/appsignal/rack/hanami_middleware.rb +1 -0
  47. data/lib/appsignal/sample_data.rb +1 -0
  48. data/lib/appsignal/transaction.rb +59 -11
  49. data/lib/appsignal/utils/query_params_sanitizer.rb +2 -0
  50. data/lib/appsignal/version.rb +1 -1
  51. data/lib/appsignal.rb +2 -2
  52. data/lib/puma/plugin/appsignal.rb +1 -1
  53. data/sig/appsignal.rbi +41 -1
  54. data/sig/appsignal.rbs +30 -0
  55. metadata +7 -6
  56. data/lib/appsignal/event_formatter/faraday/request_formatter.rb +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 483ce7fcc2f48049cf17dea30a242c5792084ff637535293a058247a03c12d2a
4
- data.tar.gz: '07290f125fa787fb511c9d5db76625cbb2a791d3b69b6f11916bf7f6c9ce907f'
3
+ metadata.gz: e9b7f5c960d357b0fa8a1213b9d30871271f932e7b850fef010ea2667269dcf0
4
+ data.tar.gz: b4810279e337a0d0dfd0283de2051c85619f4bd5338ac1105027370bed2c0977
5
5
  SHA512:
6
- metadata.gz: 25fdd04fbe1d251e22f2ba4dd45d83e82935826a7dc141340a86b9f877135424a7963c2d8ce4895b941e0d53f12ad1546b973b816f5e77514267b557538a53ab
7
- data.tar.gz: 1d44c692006eede99c48325d0f9a4b1476d0adfcf3c39ad5af3fe6f88f3145bf196562d44ab1b4254e91fd70c691c764d43dd37fde41a323969abf3222a74842
6
+ metadata.gz: 4f9111ea68c1fe1828523a2e2dbc0d41de2f2d9423cd4f5cd60b68020ab1ad03d058c93f42c9f3db7e432c50c3f91c0e3f449dba41e8b03ce1b21b03ef8cec9d
7
+ data.tar.gz: d45f3e280eba6286eafd5b8ca4eebe9336443d717810abdd3b2f30737a0062df87476c5bf295a54197f23f51e3555c09d81f88c2a356f5a4e010f6f48c8d94a1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # AppSignal for Ruby gem Changelog
2
2
 
3
+ ## 4.9.0
4
+
5
+ _Published on 2026-07-16._
6
+
7
+ ### Added
8
+
9
+ - Improve Faraday support. AppSignal now instruments Faraday requests automatically, without double-instrumenting the underlying HTTP client. Turn it off with the `instrument_faraday` option. (minor [c3354af3](https://github.com/appsignal/appsignal-ruby/commit/c3354af3f2497a984aa0110c9460d92ae3b5676f), [24aa25da](https://github.com/appsignal/appsignal-ruby/commit/24aa25da63a6b7abf74f3c29ce0d27ccbda38422))
10
+ - Add config options to turn individual integrations off. Set
11
+ `instrument_sidekiq`, `instrument_shoryuken`, `instrument_que`,
12
+ `instrument_resque`, `instrument_delayed_job`, `instrument_active_job`,
13
+ `instrument_excon` or `instrument_mongo` to `false` to disable that
14
+ integration entirely. This turns off both the instrumentation of the jobs or
15
+ requests and the enqueue instrumentation for that integration. They all
16
+ default to `true`. Each can also be set through its environment variable, such
17
+ as `APPSIGNAL_INSTRUMENT_SIDEKIQ`.
18
+
19
+ (minor [d899994e](https://github.com/appsignal/appsignal-ruby/commit/d899994e23e32d6afac6ab457b905399a8ea68e3))
20
+ - Instrument background job enqueues. Enqueuing a job now records an enqueue
21
+ event on the active transaction, so enqueues made from within a web request or
22
+ another job show up in the event timeline. This is recorded for Sidekiq
23
+ (`enqueue.sidekiq`), Que (`enqueue.que`, plus `bulk_enqueue.que` for bulk
24
+ enqueues on Que 2), Resque (`enqueue.resque`), Shoryuken (`enqueue.shoryuken`)
25
+ and Delayed Job (`enqueue.delayed_job`). Each event is titled after the job
26
+ being enqueued.
27
+
28
+ For Active Job, the `enqueue.active_job` event is now recorded by AppSignal's
29
+ own instrumentation rather than by Rails' native `enqueue.active_job`
30
+ notification. The native notification is suppressed so the enqueue is recorded
31
+ once, and the event is now titled after the job being enqueued.
32
+
33
+ These enqueue events can be turned off with the
34
+ `enable_job_enqueue_instrumentation` config option. Set it to `false` to stop
35
+ recording enqueue events across all integrations, without affecting the
36
+ instrumentation of the jobs themselves. It defaults to `true` and can also be
37
+ set through the `APPSIGNAL_ENABLE_JOB_ENQUEUE_INSTRUMENTATION` environment
38
+ variable.
39
+
40
+ (minor [caa8fbc7](https://github.com/appsignal/appsignal-ruby/commit/caa8fbc766f67e945836e6f78bc61ce98d8e0288))
41
+ - Report the `grape` gem version in the environment metadata. For more information, see [our environment metadata docs](https://docs.appsignal.com/application/environment-metadata). (patch [6e91223c](https://github.com/appsignal/appsignal-ruby/commit/6e91223c777a3da8dc2b5c68c3b446fb61db8b5b))
42
+
43
+ ### Fixed
44
+
45
+ - Instrument HTTP.rb chained requests on http 6. Requests made through a chained
46
+ client -- `HTTP.follow.get(...)`, `HTTP.headers(...).get(...)`, and so on -- go
47
+ through `HTTP::Session` rather than `HTTP::Client`, and were not being recorded.
48
+ They now produce a `request.http_rb` event like any other request.
49
+
50
+ (patch [9de9522a](https://github.com/appsignal/appsignal-ruby/commit/9de9522af442cb8b51be5b59702558002fbb5169))
51
+
3
52
  ## 4.8.6
4
53
 
5
54
  _Published on 2026-06-23._
data/appsignal.gemspec CHANGED
@@ -21,7 +21,7 @@ IGNORED_PATHS = [
21
21
  ".rubocop_todo.yml"
22
22
  ].freeze
23
23
 
24
- Gem::Specification.new do |gem| # rubocop:disable Metrics/BlockLength
24
+ Gem::Specification.new do |gem|
25
25
  gem.authors = [
26
26
  "Robert Beekman",
27
27
  "Thijs Cadier",
@@ -63,7 +63,7 @@ Gem::Specification.new do |gem| # rubocop:disable Metrics/BlockLength
63
63
  gem.add_development_dependency "pry"
64
64
  gem.add_development_dependency "rake", ">= 12"
65
65
  gem.add_development_dependency "rspec", "~> 3.8"
66
- gem.add_development_dependency "rubocop", "1.64.1"
66
+ gem.add_development_dependency "rubocop", "~> 1.87.0"
67
67
  gem.add_development_dependency("sord") unless RUBY_PLATFORM == "java"
68
68
  gem.add_development_dependency "timecop"
69
69
  gem.add_development_dependency "webmock"
data/build_matrix.yml CHANGED
@@ -141,6 +141,7 @@ matrix:
141
141
  - "3.4.1"
142
142
  - "3.3.4"
143
143
  - "jruby-9.4.7.0"
144
+ - gem: "delayed_job"
144
145
  - gem: "dry-monitor"
145
146
  only:
146
147
  ruby:
@@ -150,6 +151,16 @@ matrix:
150
151
  - "3.2.5"
151
152
  - "3.1.6"
152
153
  - "3.0.7"
154
+ - gem: "faraday-1"
155
+ - gem: "faraday-2"
156
+ only:
157
+ ruby:
158
+ - "4.0.0"
159
+ - "3.4.1"
160
+ - "3.3.4"
161
+ - "3.2.5"
162
+ - "3.1.6"
163
+ - "3.0.7"
153
164
  - gem: "grape"
154
165
  - gem: "hanami-2.0"
155
166
  only:
@@ -182,6 +193,7 @@ matrix:
182
193
  - "3.4.1"
183
194
  - "3.3.4"
184
195
  - "3.2.5"
196
+ - gem: "mongo"
185
197
  - gem: "ownership"
186
198
  - gem: "padrino"
187
199
  exclude:
@@ -278,6 +290,19 @@ matrix:
278
290
  - "3.1.6"
279
291
  - "3.0.7"
280
292
  - gem: "sequel"
293
+ - gem: "shoryuken-6"
294
+ only:
295
+ ruby:
296
+ - "3.1.6"
297
+ - "3.0.7"
298
+ - "2.7.8"
299
+ - gem: "shoryuken-7"
300
+ only:
301
+ ruby:
302
+ - "4.0.0"
303
+ - "3.4.1"
304
+ - "3.3.4"
305
+ - "3.2.5"
281
306
  - gem: "sinatra"
282
307
  - gem: "webmachine2"
283
308
  - gem: "redis-4"
data/ext/base.rb CHANGED
@@ -100,15 +100,11 @@ def installation_succeeded?
100
100
  end
101
101
 
102
102
  def check_architecture
103
- if APPSIGNAL_AGENT_CONFIG["triples"].key?(TARGET_TRIPLE)
104
- true
105
- else
106
- abort_installation(
103
+ APPSIGNAL_AGENT_CONFIG["triples"].key?(TARGET_TRIPLE) || abort_installation(
107
104
  "AppSignal currently does not support your system architecture (#{TARGET_TRIPLE})." \
108
105
  "Please let us know at support@appsignal.com, we aim to support everything " \
109
106
  "our customers run."
110
107
  )
111
- end
112
108
  end
113
109
 
114
110
  def download_archive(type)
@@ -140,9 +136,9 @@ def download_archive(type)
140
136
  :proxy => proxy }
141
137
  ]
142
138
  if URI.respond_to?(:open) # rubocop:disable Style/GuardClause
143
- return URI.open(*args)
139
+ return URI.open(*args) # rubocop:disable Security/Open
144
140
  else
145
- return open(*args)
141
+ return open(*args) # rubocop:disable Security/Open
146
142
  end
147
143
  rescue => error
148
144
  backtrace = error.backtrace.join("\n")
data/ext/extconf.rb CHANGED
@@ -77,7 +77,7 @@ def link_libraries
77
77
  end
78
78
  end
79
79
 
80
- def have_required_function(library, func) # rubocop:disable Naming/PredicateName
80
+ def have_required_function(library, func) # rubocop:disable Naming/PredicatePrefix
81
81
  if have_func(func)
82
82
  report["build"]["dependencies"][library] = "linked"
83
83
  return
@@ -4,6 +4,9 @@ module Appsignal
4
4
  module CheckIn
5
5
  # @!visibility private
6
6
  class Event
7
+ CRON_KINDS = %w[start finish].freeze
8
+ private_constant :CRON_KINDS
9
+
7
10
  class << self
8
11
  def new(check_in_type:, identifier:, digest: nil, kind: nil)
9
12
  {
@@ -67,7 +70,7 @@ module Appsignal
67
70
  end
68
71
  end
69
72
 
70
- def deduplicate_cron!(events) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
73
+ def deduplicate_cron!(events)
71
74
  # Remove redundant cron check-in events from the given list of events.
72
75
  # This is done by removing redundant *pairs* of events -- that is,
73
76
  # for each identifier, only send one complete pair of start and
@@ -111,9 +114,7 @@ module Appsignal
111
114
  # Do not remove events that are not cron check-in events or that
112
115
  # have an unknown kind.
113
116
  return false unless
114
- event[:check_in_type] == "cron" && (
115
- event[:kind] == "start" ||
116
- event[:kind] == "finish")
117
+ event[:check_in_type] == "cron" && CRON_KINDS.include?(event[:kind])
117
118
 
118
119
  # Remove any event that is part of a complete digest pair, except
119
120
  # for the one digest that should be kept.
@@ -350,7 +350,7 @@ module Appsignal
350
350
  path = File.expand_path("../../../ext/install.report", __dir__)
351
351
  raw_report = File.read(path)
352
352
  JSON.parse(raw_report)
353
- rescue StandardError, JSON::ParserError => e # rubocop:disable Lint/ShadowedException
353
+ rescue StandardError => e
354
354
  {
355
355
  "parsing_error" => {
356
356
  "error" => "#{e.class}: #{e}",
@@ -5,8 +5,6 @@ require "appsignal/utils/rails_helper"
5
5
  module Appsignal
6
6
  class CLI
7
7
  module Helpers
8
- private
9
-
10
8
  COLOR_CODES = {
11
9
  :red => 31,
12
10
  :green => 32,
@@ -16,6 +14,8 @@ module Appsignal
16
14
  :default => 0
17
15
  }.freeze
18
16
 
17
+ private
18
+
19
19
  def coloring=(value)
20
20
  @coloring = value
21
21
  end
@@ -12,7 +12,7 @@ module Appsignal
12
12
  EXCLUDED_ENVIRONMENTS = ["test"].freeze
13
13
 
14
14
  class << self
15
- def run(push_api_key, options) # rubocop:disable Metrics/AbcSize
15
+ def run(push_api_key, options)
16
16
  self.coloring = options.delete(:color) { true }
17
17
  $stdout.sync = true
18
18
 
@@ -228,7 +228,7 @@ module Appsignal
228
228
  done_notice
229
229
  end
230
230
 
231
- def configure(config, environments, name_overwritten) # rubocop:disable Metrics/AbcSize
231
+ def configure(config, environments, name_overwritten)
232
232
  install_for_capistrano
233
233
 
234
234
  ENV["APPSIGNAL_APP_ENV"] = "development"
@@ -241,7 +241,7 @@ module Appsignal
241
241
  puts " See our docs for information on the different configuration methods: "
242
242
  puts " https://docs.appsignal.com/ruby/configuration.html"
243
243
  puts
244
- loop do # rubocop:disable Metrics/BlockLength
244
+ loop do
245
245
  print " Choose (1-3): "
246
246
  case ask_for_input
247
247
  when "1"
@@ -96,6 +96,7 @@ module Appsignal
96
96
  :enable_at_exit_hook => "on_error",
97
97
  :enable_at_exit_reporter => true,
98
98
  :enable_host_metrics => true,
99
+ :enable_job_enqueue_instrumentation => true,
99
100
  :enable_minutely_probes => true,
100
101
  :enable_statsd => true,
101
102
  :enable_nginx_metrics => false,
@@ -113,12 +114,21 @@ module Appsignal
113
114
  :ignore_errors => [],
114
115
  :ignore_logs => [],
115
116
  :ignore_namespaces => [],
117
+ :instrument_active_job => true,
116
118
  :instrument_code_ownership => true,
119
+ :instrument_delayed_job => true,
120
+ :instrument_excon => true,
121
+ :instrument_faraday => true,
117
122
  :instrument_http_rb => true,
123
+ :instrument_mongo => true,
118
124
  :instrument_net_http => true,
119
125
  :instrument_ownership => true,
126
+ :instrument_que => true,
120
127
  :instrument_redis => true,
128
+ :instrument_resque => true,
121
129
  :instrument_sequel => true,
130
+ :instrument_shoryuken => true,
131
+ :instrument_sidekiq => true,
122
132
  :log => "file",
123
133
  :logging_endpoint => "https://appsignal-endpoint.net",
124
134
  :ownership_set_namespace => false,
@@ -180,6 +190,8 @@ module Appsignal
180
190
  :enable_allocation_tracking => "APPSIGNAL_ENABLE_ALLOCATION_TRACKING",
181
191
  :enable_at_exit_reporter => "APPSIGNAL_ENABLE_AT_EXIT_REPORTER",
182
192
  :enable_host_metrics => "APPSIGNAL_ENABLE_HOST_METRICS",
193
+ :enable_job_enqueue_instrumentation =>
194
+ "APPSIGNAL_ENABLE_JOB_ENQUEUE_INSTRUMENTATION",
183
195
  :enable_minutely_probes => "APPSIGNAL_ENABLE_MINUTELY_PROBES",
184
196
  :enable_statsd => "APPSIGNAL_ENABLE_STATSD",
185
197
  :enable_nginx_metrics => "APPSIGNAL_ENABLE_NGINX_METRICS",
@@ -191,12 +203,21 @@ module Appsignal
191
203
  :enable_rake_performance_instrumentation =>
192
204
  "APPSIGNAL_ENABLE_RAKE_PERFORMANCE_INSTRUMENTATION",
193
205
  :files_world_accessible => "APPSIGNAL_FILES_WORLD_ACCESSIBLE",
206
+ :instrument_active_job => "APPSIGNAL_INSTRUMENT_ACTIVE_JOB",
194
207
  :instrument_code_ownership => "APPSIGNAL_INSTRUMENT_CODE_OWNERSHIP",
208
+ :instrument_delayed_job => "APPSIGNAL_INSTRUMENT_DELAYED_JOB",
209
+ :instrument_excon => "APPSIGNAL_INSTRUMENT_EXCON",
210
+ :instrument_faraday => "APPSIGNAL_INSTRUMENT_FARADAY",
195
211
  :instrument_http_rb => "APPSIGNAL_INSTRUMENT_HTTP_RB",
212
+ :instrument_mongo => "APPSIGNAL_INSTRUMENT_MONGO",
196
213
  :instrument_net_http => "APPSIGNAL_INSTRUMENT_NET_HTTP",
197
214
  :instrument_ownership => "APPSIGNAL_INSTRUMENT_OWNERSHIP",
215
+ :instrument_que => "APPSIGNAL_INSTRUMENT_QUE",
198
216
  :instrument_redis => "APPSIGNAL_INSTRUMENT_REDIS",
217
+ :instrument_resque => "APPSIGNAL_INSTRUMENT_RESQUE",
199
218
  :instrument_sequel => "APPSIGNAL_INSTRUMENT_SEQUEL",
219
+ :instrument_shoryuken => "APPSIGNAL_INSTRUMENT_SHORYUKEN",
220
+ :instrument_sidekiq => "APPSIGNAL_INSTRUMENT_SIDEKIQ",
200
221
  :ownership_set_namespace => "APPSIGNAL_OWNERSHIP_SET_NAMESPACE",
201
222
  :running_in_container => "APPSIGNAL_RUNNING_IN_CONTAINER",
202
223
  :send_environment_metadata => "APPSIGNAL_SEND_ENVIRONMENT_METADATA",
@@ -432,7 +453,7 @@ module Appsignal
432
453
  end
433
454
 
434
455
  # @!visibility private
435
- def write_to_environment # rubocop:disable Metrics/AbcSize
456
+ def write_to_environment
436
457
  ENV["_APPSIGNAL_ACTIVE"] = active?.to_s
437
458
  ENV["_APPSIGNAL_AGENT_PATH"] = File.expand_path("../../ext", __dir__).to_s
438
459
  ENV["_APPSIGNAL_APP_NAME"] = config_hash[:name]
@@ -591,7 +612,9 @@ module Appsignal
591
612
  return unless yml_config_file?
592
613
 
593
614
  read_options = YAML::VERSION >= "4.0.0" ? { :aliases => true } : {}
615
+ # rubocop:disable Security/YAMLLoad
594
616
  configurations = YAML.load(ERB.new(File.read(yml_config_file)).result, **read_options)
617
+ # rubocop:enable Security/YAMLLoad
595
618
  config_for_this_env = configurations[env]
596
619
  if config_for_this_env
597
620
  config_for_this_env.transform_keys(&:to_sym)
@@ -824,6 +847,8 @@ module Appsignal
824
847
  # @return [Boolean] Configure whether the at_exit reporter is enabled
825
848
  # @!attribute [rw] enable_host_metrics
826
849
  # @return [Boolean] Configure whether host metrics collection is enabled
850
+ # @!attribute [rw] enable_job_enqueue_instrumentation
851
+ # @return [Boolean] Configure whether to record an event when a background job is enqueued
827
852
  # @!attribute [rw] enable_minutely_probes
828
853
  # @return [Boolean] Configure whether minutely probes are enabled
829
854
  # @!attribute [rw] enable_statsd
@@ -842,16 +867,34 @@ module Appsignal
842
867
  # @return [Boolean] Configure whether Rake performance instrumentation is enabled
843
868
  # @!attribute [rw] files_world_accessible
844
869
  # @return [Boolean] Configure whether files created by AppSignal should be world accessible
870
+ # @!attribute [rw] instrument_active_job
871
+ # @return [Boolean] Configure whether to instrument Active Job
872
+ # @!attribute [rw] instrument_delayed_job
873
+ # @return [Boolean] Configure whether to instrument Delayed Job
874
+ # @!attribute [rw] instrument_excon
875
+ # @return [Boolean] Configure whether to instrument requests made with the Excon gem
876
+ # @!attribute [rw] instrument_faraday
877
+ # @return [Boolean] Configure whether to instrument requests made with the Faraday gem
845
878
  # @!attribute [rw] instrument_http_rb
846
879
  # @return [Boolean] Configure whether to instrument requests made with the http.rb gem
880
+ # @!attribute [rw] instrument_mongo
881
+ # @return [Boolean] Configure whether to instrument MongoDB queries
847
882
  # @!attribute [rw] instrument_net_http
848
883
  # @return [Boolean] Configure whether to instrument requests made with Net::HTTP
849
884
  # @!attribute [rw] instrument_ownership
850
885
  # @return [Boolean] Configure whether to instrument the Ownership gem
886
+ # @!attribute [rw] instrument_que
887
+ # @return [Boolean] Configure whether to instrument Que
851
888
  # @!attribute [rw] instrument_redis
852
889
  # @return [Boolean] Configure whether to instrument Redis queries
890
+ # @!attribute [rw] instrument_resque
891
+ # @return [Boolean] Configure whether to instrument Resque
853
892
  # @!attribute [rw] instrument_sequel
854
893
  # @return [Boolean] Configure whether to instrument Sequel queries
894
+ # @!attribute [rw] instrument_shoryuken
895
+ # @return [Boolean] Configure whether to instrument Shoryuken
896
+ # @!attribute [rw] instrument_sidekiq
897
+ # @return [Boolean] Configure whether to instrument Sidekiq
855
898
  # @!attribute [rw] ownership_set_namespace
856
899
  # @return [Boolean] Configure whether the Ownership gem instrumentation should set namespace
857
900
  # @!attribute [rw] running_in_container
@@ -87,6 +87,7 @@ module Appsignal
87
87
  elasticsearch
88
88
  excon
89
89
  faraday
90
+ grape
90
91
  gvltools
91
92
  hanami
92
93
  hiredis
@@ -398,14 +398,14 @@ module Appsignal
398
398
  )
399
399
  end
400
400
 
401
- def set_action(action_name) # rubocop:disable Naming/AccessorMethodName
401
+ def set_action(action_name)
402
402
  Extension.appsignal_set_transaction_action(
403
403
  pointer,
404
404
  make_appsignal_string(action_name)
405
405
  )
406
406
  end
407
407
 
408
- def set_namespace(namespace) # rubocop:disable Naming/AccessorMethodName
408
+ def set_namespace(namespace)
409
409
  Extension.appsignal_set_transaction_namespace(
410
410
  pointer,
411
411
  make_appsignal_string(namespace)
@@ -420,7 +420,7 @@ module Appsignal
420
420
  )
421
421
  end
422
422
 
423
- def set_queue_start(time) # rubocop:disable Naming/AccessorMethodName
423
+ def set_queue_start(time)
424
424
  Extension.appsignal_set_transaction_queue_start(pointer, time)
425
425
  end
426
426
 
@@ -496,7 +496,7 @@ module Appsignal
496
496
  )
497
497
  end
498
498
 
499
- def set_name(name) # rubocop:disable Naming/AccessorMethodName
499
+ def set_name(name)
500
500
  Extension.appsignal_set_span_name(
501
501
  pointer,
502
502
  make_appsignal_string(name)
@@ -547,6 +547,7 @@ module Appsignal
547
547
 
548
548
  class Data
549
549
  include StringHelpers
550
+
550
551
  attr_reader :pointer
551
552
 
552
553
  def initialize(pointer)
@@ -588,7 +589,7 @@ module Appsignal
588
589
  )
589
590
  end
590
591
 
591
- def set_nil(key) # rubocop:disable Naming/AccessorMethodName
592
+ def set_nil(key)
592
593
  Extension.appsignal_data_map_set_null(
593
594
  pointer,
594
595
  make_appsignal_string(key)
@@ -84,7 +84,7 @@ module Appsignal
84
84
  #
85
85
  # This class inherits from the {Data} class so that it passes type checks.
86
86
  class MockData < Data
87
- def initialize(*_args)
87
+ def initialize(*_args) # rubocop:disable Lint/MissingSuper
88
88
  # JRuby extension requirement, as it sends a pointer to the Data object
89
89
  # when creating it
90
90
  end
@@ -138,7 +138,7 @@ module Appsignal
138
138
 
139
139
  begin
140
140
  yield if block_given?
141
- rescue Exception => error # rubocop:disable Lint/RescueException
141
+ rescue Exception => error
142
142
  transaction.set_error(error)
143
143
  raise error
144
144
  ensure
@@ -242,7 +242,7 @@ module Appsignal
242
242
 
243
243
  transaction.complete
244
244
  end
245
- alias :send_exception :send_error
245
+ alias send_exception send_error
246
246
 
247
247
  # Set an error on the current transaction.
248
248
  #
@@ -305,8 +305,8 @@ module Appsignal
305
305
  transaction.set_error(exception)
306
306
  yield transaction if block_given?
307
307
  end
308
- alias :set_exception :set_error
309
- alias :add_exception :set_error
308
+ alias set_exception set_error
309
+ alias add_exception set_error
310
310
 
311
311
  # Report an error to AppSignal.
312
312
  #
@@ -377,7 +377,7 @@ module Appsignal
377
377
 
378
378
  transaction.complete unless has_parent_transaction
379
379
  end
380
- alias :report_exception :report_error
380
+ alias report_exception report_error
381
381
 
382
382
  # Set a custom action name for the current transaction.
383
383
  #
@@ -497,7 +497,7 @@ module Appsignal
497
497
  transaction = Appsignal::Transaction.current
498
498
  transaction.add_custom_data(data)
499
499
  end
500
- alias :set_custom_data :add_custom_data
500
+ alias set_custom_data add_custom_data
501
501
 
502
502
  # Add tags to the current transaction.
503
503
  #
@@ -542,9 +542,9 @@ module Appsignal
542
542
  transaction = Appsignal::Transaction.current
543
543
  transaction.add_tags(tags)
544
544
  end
545
- alias :tag_request :add_tags
546
- alias :tag_job :add_tags
547
- alias :set_tags :add_tags
545
+ alias tag_request add_tags
546
+ alias tag_job add_tags
547
+ alias set_tags add_tags
548
548
 
549
549
  # Add parameters to the current transaction.
550
550
  #
@@ -600,7 +600,7 @@ module Appsignal
600
600
  transaction = Appsignal::Transaction.current
601
601
  transaction.add_params(params, &block)
602
602
  end
603
- alias :set_params :add_params
603
+ alias set_params add_params
604
604
 
605
605
  # Mark the parameters sample data to be set as an empty value.
606
606
  #
@@ -666,7 +666,7 @@ module Appsignal
666
666
  transaction = Appsignal::Transaction.current
667
667
  transaction.add_session_data(session_data, &block)
668
668
  end
669
- alias :set_session_data :add_session_data
669
+ alias set_session_data add_session_data
670
670
 
671
671
  # Add request headers to the current transaction.
672
672
  #
@@ -708,7 +708,7 @@ module Appsignal
708
708
  transaction = Appsignal::Transaction.current
709
709
  transaction.add_headers(headers, &block)
710
710
  end
711
- alias :set_headers :add_headers
711
+ alias set_headers add_headers
712
712
 
713
713
  # Add breadcrumbs to the transaction.
714
714
  #
@@ -43,7 +43,7 @@ module Appsignal
43
43
  Appsignal.instrument "subscribed.action_cable" do
44
44
  inner.call
45
45
  end
46
- rescue Exception => exception # rubocop:disable Lint/RescueException
46
+ rescue Exception => exception
47
47
  transaction.set_error(exception)
48
48
  raise exception
49
49
  ensure
@@ -79,7 +79,7 @@ module Appsignal
79
79
  Appsignal.instrument "unsubscribed.action_cable" do
80
80
  inner.call
81
81
  end
82
- rescue Exception => exception # rubocop:disable Lint/RescueException
82
+ rescue Exception => exception
83
83
  transaction.set_error(exception)
84
84
  raise exception
85
85
  ensure
@@ -22,13 +22,16 @@ module Appsignal
22
22
  end
23
23
 
24
24
  def dependencies_present?
25
- self.class.dependencies_present?
25
+ self.class.dependencies_present? && Appsignal.config &&
26
+ Appsignal.config[:instrument_active_job]
26
27
  end
27
28
 
28
29
  def install
29
30
  ActiveSupport.on_load(:active_job) do
30
31
  ::ActiveJob::Base
31
32
  .extend ::Appsignal::Hooks::ActiveJobHook::ActiveJobClassInstrumentation
33
+ ::ActiveJob::Base
34
+ .prepend ::Appsignal::Hooks::ActiveJobHook::ActiveJobEnqueueInstrumentation
32
35
 
33
36
  next unless Appsignal::Hooks::ActiveJobHook.version_7_1_or_higher?
34
37
 
@@ -41,8 +44,44 @@ module Appsignal
41
44
  end
42
45
  end
43
46
 
47
+ # Records an `enqueue.active_job` event when a job is enqueued, so the
48
+ # enqueue shows up on the active transaction's timeline (e.g. when
49
+ # enqueuing from within a web request or another job).
50
+ #
51
+ # Wrapping `enqueue` ourselves -- rather than relying on Rails' native
52
+ # `enqueue.active_job` notification, which the AppSignal notifications
53
+ # path now suppresses -- gives us a single event we own. Like all
54
+ # AppSignal events, this only records when there's an active transaction;
55
+ # an enqueue with no transaction is a transparent pass-through.
56
+ #
57
+ # @!visibility private
58
+ module ActiveJobEnqueueInstrumentation
59
+ def enqueue(*, **)
60
+ # Skip recording the event when enqueue events are suppressed. That is
61
+ # the case when enqueue instrumentation is disabled, and it keeps this
62
+ # integration consistent with the standalone adapters (Sidekiq, ...),
63
+ # which already gate their own enqueue event on this check.
64
+ if Appsignal::Transaction.current? &&
65
+ Appsignal::Transaction.current.job_enqueue_events_suppressed?
66
+ return super
67
+ end
68
+
69
+ Appsignal.instrument("enqueue.active_job", "enqueue #{self.class.name} job") do
70
+ # Active Job enqueues through an adapter (Sidekiq, Resque, ...) that
71
+ # has its own enqueue instrumentation. Suppress it so the enqueue is
72
+ # recorded once, as this event, rather than as nested Active Job +
73
+ # adapter events.
74
+ if Appsignal::Transaction.current?
75
+ Appsignal::Transaction.current.suppress_job_enqueue_events { super }
76
+ else
77
+ super
78
+ end
79
+ end
80
+ end
81
+ end
82
+
44
83
  module ActiveJobClassInstrumentation
45
- def execute(job) # rubocop:disable Metrics/CyclomaticComplexity
84
+ def execute(job)
46
85
  enqueued_at = job["enqueued_at"]
47
86
  queue_start = Time.parse(enqueued_at) if enqueued_at
48
87
  queue_time =
@@ -75,7 +114,7 @@ module Appsignal
75
114
  transaction.set_action(ActiveJobHelpers.action_name(job))
76
115
 
77
116
  super
78
- rescue Exception => exception # rubocop:disable Lint/RescueException
117
+ rescue Exception => exception
79
118
  job_status = :failed
80
119
  transaction_set_error(transaction, exception)
81
120
  raise exception
@@ -7,7 +7,8 @@ module Appsignal
7
7
  register :delayed_job
8
8
 
9
9
  def dependencies_present?
10
- defined?(::Delayed::Plugin)
10
+ defined?(::Delayed::Plugin) && Appsignal.config &&
11
+ Appsignal.config[:instrument_delayed_job]
11
12
  end
12
13
 
13
14
  def install
@@ -7,7 +7,7 @@ module Appsignal
7
7
  register :excon
8
8
 
9
9
  def dependencies_present?
10
- Appsignal.config && defined?(::Excon)
10
+ Appsignal.config && defined?(::Excon) && Appsignal.config[:instrument_excon]
11
11
  end
12
12
 
13
13
  def install