appsignal 3.4.0 → 3.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +63 -21
  3. data/.rubocop_todo.yml +68 -54
  4. data/.semaphore/semaphore.yml +11 -11
  5. data/CHANGELOG.md +37 -0
  6. data/Rakefile +15 -99
  7. data/appsignal.gemspec +3 -4
  8. data/bin/appsignal +4 -2
  9. data/build_matrix.yml +4 -4
  10. data/ext/._appsignal-agent +0 -0
  11. data/ext/Rakefile +22 -21
  12. data/ext/agent.rb +2 -0
  13. data/ext/base.rb +14 -17
  14. data/ext/extconf.rb +4 -1
  15. data/lib/appsignal/auth_check.rb +3 -3
  16. data/lib/appsignal/capistrano.rb +1 -1
  17. data/lib/appsignal/cli/demo.rb +5 -2
  18. data/lib/appsignal/cli/diagnose/paths.rb +4 -1
  19. data/lib/appsignal/cli/diagnose/utils.rb +7 -3
  20. data/lib/appsignal/cli/diagnose.rb +7 -5
  21. data/lib/appsignal/cli/helpers.rb +1 -4
  22. data/lib/appsignal/cli/install.rb +4 -10
  23. data/lib/appsignal/cli.rb +3 -2
  24. data/lib/appsignal/config.rb +105 -102
  25. data/lib/appsignal/demo.rb +2 -1
  26. data/lib/appsignal/environment.rb +2 -0
  27. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +2 -1
  28. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +13 -13
  29. data/lib/appsignal/event_formatter.rb +5 -4
  30. data/lib/appsignal/extension/jruby.rb +11 -9
  31. data/lib/appsignal/extension.rb +1 -1
  32. data/lib/appsignal/helpers/instrumentation.rb +50 -35
  33. data/lib/appsignal/hooks/action_cable.rb +6 -4
  34. data/lib/appsignal/hooks/action_mailer.rb +2 -0
  35. data/lib/appsignal/hooks/active_job.rb +11 -10
  36. data/lib/appsignal/hooks/active_support_notifications.rb +3 -4
  37. data/lib/appsignal/hooks/data_mapper.rb +1 -1
  38. data/lib/appsignal/hooks/gvl.rb +3 -0
  39. data/lib/appsignal/hooks/http.rb +1 -1
  40. data/lib/appsignal/hooks/mri.rb +2 -0
  41. data/lib/appsignal/hooks/net_http.rb +1 -1
  42. data/lib/appsignal/hooks/que.rb +1 -1
  43. data/lib/appsignal/hooks/rake.rb +1 -1
  44. data/lib/appsignal/hooks/redis.rb +1 -1
  45. data/lib/appsignal/hooks/resque.rb +1 -1
  46. data/lib/appsignal/hooks/shoryuken.rb +2 -4
  47. data/lib/appsignal/hooks/sidekiq.rb +1 -1
  48. data/lib/appsignal/hooks/unicorn.rb +2 -2
  49. data/lib/appsignal/hooks/webmachine.rb +1 -1
  50. data/lib/appsignal/hooks.rb +2 -2
  51. data/lib/appsignal/integrations/active_support_notifications.rb +1 -1
  52. data/lib/appsignal/integrations/capistrano/appsignal.cap +6 -3
  53. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +5 -4
  54. data/lib/appsignal/integrations/delayed_job_plugin.rb +3 -5
  55. data/lib/appsignal/integrations/grape.rb +1 -1
  56. data/lib/appsignal/integrations/hanami.rb +1 -1
  57. data/lib/appsignal/integrations/object.rb +2 -3
  58. data/lib/appsignal/integrations/padrino.rb +2 -4
  59. data/lib/appsignal/integrations/que.rb +6 -6
  60. data/lib/appsignal/integrations/railtie.rb +72 -0
  61. data/lib/appsignal/integrations/sidekiq.rb +9 -11
  62. data/lib/appsignal/integrations/sinatra.rb +1 -3
  63. data/lib/appsignal/integrations/webmachine.rb +4 -6
  64. data/lib/appsignal/logger.rb +31 -6
  65. data/lib/appsignal/marker.rb +4 -5
  66. data/lib/appsignal/minutely.rb +7 -7
  67. data/lib/appsignal/probes/gvl.rb +9 -4
  68. data/lib/appsignal/probes/helpers.rb +4 -6
  69. data/lib/appsignal/probes/mri.rb +7 -5
  70. data/lib/appsignal/probes/sidekiq.rb +3 -0
  71. data/lib/appsignal/probes.rb +2 -0
  72. data/lib/appsignal/rack/generic_instrumentation.rb +1 -5
  73. data/lib/appsignal/rack/sinatra_instrumentation.rb +3 -5
  74. data/lib/appsignal/rack/streaming_listener.rb +11 -13
  75. data/lib/appsignal/span.rb +5 -5
  76. data/lib/appsignal/system.rb +10 -11
  77. data/lib/appsignal/transaction.rb +49 -25
  78. data/lib/appsignal/transmitter.rb +4 -2
  79. data/lib/appsignal/utils/deprecation_message.rb +2 -0
  80. data/lib/appsignal/utils/hash_sanitizer.rb +1 -1
  81. data/lib/appsignal/utils/integration_logger.rb +5 -3
  82. data/lib/appsignal/utils/json.rb +1 -1
  83. data/lib/appsignal/utils/query_params_sanitizer.rb +1 -1
  84. data/lib/appsignal/version.rb +1 -1
  85. data/lib/appsignal.rb +5 -4
  86. data/lib/puma/plugin/appsignal.rb +16 -18
  87. data/script/lint_git +1 -1
  88. data/spec/lib/appsignal/capistrano2_spec.rb +6 -3
  89. data/spec/lib/appsignal/capistrano3_spec.rb +6 -3
  90. data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +1 -3
  91. data/spec/lib/appsignal/cli/diagnose_spec.rb +33 -30
  92. data/spec/lib/appsignal/cli/install_spec.rb +5 -6
  93. data/spec/lib/appsignal/cli_spec.rb +1 -1
  94. data/spec/lib/appsignal/config_spec.rb +43 -37
  95. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +11 -5
  96. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +4 -4
  97. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +1 -4
  98. data/spec/lib/appsignal/event_formatter_spec.rb +11 -9
  99. data/spec/lib/appsignal/hooks/action_cable_spec.rb +5 -2
  100. data/spec/lib/appsignal/hooks/action_mailer_spec.rb +2 -1
  101. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +1 -1
  102. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +1 -1
  103. data/spec/lib/appsignal/hooks/activejob_spec.rb +21 -12
  104. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +1 -0
  105. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +12 -12
  106. data/spec/lib/appsignal/hooks/excon_spec.rb +2 -2
  107. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +3 -1
  108. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +4 -2
  109. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +2 -1
  110. data/spec/lib/appsignal/hooks_spec.rb +5 -4
  111. data/spec/lib/appsignal/integrations/grape_spec.rb +8 -4
  112. data/spec/lib/appsignal/integrations/hanami_spec.rb +16 -8
  113. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +2 -4
  114. data/spec/lib/appsignal/integrations/object_spec.rb +6 -1
  115. data/spec/lib/appsignal/integrations/padrino_spec.rb +4 -2
  116. data/spec/lib/appsignal/integrations/railtie_spec.rb +213 -6
  117. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +54 -41
  118. data/spec/lib/appsignal/logger_spec.rb +20 -4
  119. data/spec/lib/appsignal/marker_spec.rb +2 -2
  120. data/spec/lib/appsignal/minutely_spec.rb +3 -3
  121. data/spec/lib/appsignal/probes/gvl_spec.rb +60 -12
  122. data/spec/lib/appsignal/probes/mri_spec.rb +7 -4
  123. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +2 -1
  124. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +2 -1
  125. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +10 -5
  126. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +7 -5
  127. data/spec/lib/appsignal/transaction_spec.rb +20 -13
  128. data/spec/lib/appsignal/utils/data_spec.rb +10 -1
  129. data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +11 -11
  130. data/spec/lib/appsignal/utils/json_spec.rb +4 -2
  131. data/spec/lib/appsignal_spec.rb +49 -35
  132. data/spec/lib/puma/appsignal_spec.rb +9 -11
  133. data/spec/spec_helper.rb +14 -2
  134. data/spec/support/fixtures/projects/valid/config/appsignal.yml +1 -1
  135. data/spec/support/helpers/config_helpers.rb +2 -1
  136. data/spec/support/helpers/dependency_helper.rb +1 -9
  137. data/spec/support/helpers/std_streams_helper.rb +1 -3
  138. data/spec/support/helpers/wait_for_helper.rb +2 -3
  139. data/spec/support/mocks/appsignal_mock.rb +1 -1
  140. data/spec/support/mocks/fake_gvl_tools.rb +2 -10
  141. data/spec/support/testing.rb +4 -3
  142. metadata +9 -135
@@ -57,14 +57,14 @@ module Appsignal
57
57
  # re-raised by this method.
58
58
  # @return [Object] the value of the given block is returned.
59
59
  # @since 0.10.0
60
- def monitor_transaction(name, env = {})
60
+ def monitor_transaction(name, env = {}, &block)
61
61
  # Always verify input, even when Appsignal is not active.
62
62
  # This makes it more likely invalid arguments get flagged in test/dev
63
63
  # environments.
64
- if name.start_with?("perform_job".freeze)
64
+ if name.start_with?("perform_job")
65
65
  namespace = Appsignal::Transaction::BACKGROUND_JOB
66
66
  request = Appsignal::Transaction::GenericRequest.new(env)
67
- elsif name.start_with?("process_action".freeze)
67
+ elsif name.start_with?("process_action")
68
68
  namespace = Appsignal::Transaction::HTTP_REQUEST
69
69
  request = ::Rack::Request.new(env)
70
70
  else
@@ -82,9 +82,7 @@ module Appsignal
82
82
  request
83
83
  )
84
84
  begin
85
- Appsignal.instrument(name) do
86
- yield
87
- end
85
+ Appsignal.instrument(name, &block)
88
86
  rescue Exception => error # rubocop:disable Lint/RescueException
89
87
  transaction.set_error(error)
90
88
  raise error
@@ -211,21 +209,21 @@ module Appsignal
211
209
  call_location = caller(1..1).first
212
210
  deprecation_message \
213
211
  "The tags argument for `Appsignal.send_error` is deprecated. " \
214
- "Please use the block method to set tags instead.\n\n" \
215
- " Appsignal.send_error(error) do |transaction|\n" \
216
- " transaction.set_tags(#{tags})\n" \
217
- " end\n\n" \
218
- "Appsignal.send_error called on location: #{call_location}"
212
+ "Please use the block method to set tags instead.\n\n" \
213
+ " Appsignal.send_error(error) do |transaction|\n" \
214
+ " transaction.set_tags(#{tags})\n" \
215
+ " end\n\n" \
216
+ "Appsignal.send_error called on location: #{call_location}"
219
217
  end
220
218
  if namespace
221
219
  call_location = caller(1..1).first
222
220
  deprecation_message \
223
221
  "The namespace argument for `Appsignal.send_error` is deprecated. " \
224
- "Please use the block method to set the namespace instead.\n\n" \
225
- " Appsignal.send_error(error) do |transaction|\n" \
226
- " transaction.set_namespace(#{namespace.inspect})\n" \
227
- " end\n\n" \
228
- "Appsignal.send_error called on location: #{call_location}"
222
+ "Please use the block method to set the namespace instead.\n\n" \
223
+ " Appsignal.send_error(error) do |transaction|\n" \
224
+ " transaction.set_namespace(#{namespace.inspect})\n" \
225
+ " end\n\n" \
226
+ "Appsignal.send_error called on location: #{call_location}"
229
227
  end
230
228
  return unless active?
231
229
 
@@ -304,21 +302,21 @@ module Appsignal
304
302
  call_location = caller(1..1).first
305
303
  deprecation_message \
306
304
  "The tags argument for `Appsignal.set_error` is deprecated. " \
307
- "Please use the block method to set tags instead.\n\n" \
308
- " Appsignal.set_error(error) do |transaction|\n" \
309
- " transaction.set_tags(#{tags})\n" \
310
- " end\n\n" \
311
- "Appsignal.set_error called on location: #{call_location}"
305
+ "Please use the block method to set tags instead.\n\n" \
306
+ " Appsignal.set_error(error) do |transaction|\n" \
307
+ " transaction.set_tags(#{tags})\n" \
308
+ " end\n\n" \
309
+ "Appsignal.set_error called on location: #{call_location}"
312
310
  end
313
311
  if namespace
314
312
  call_location = caller(1..1).first
315
313
  deprecation_message \
316
314
  "The namespace argument for `Appsignal.set_error` is deprecated. " \
317
- "Please use the block method to set the namespace instead.\n\n" \
318
- " Appsignal.set_error(error) do |transaction|\n" \
319
- " transaction.set_namespace(#{namespace.inspect})\n" \
320
- " end\n\n" \
321
- "Appsignal.set_error called on location: #{call_location}"
315
+ "Please use the block method to set the namespace instead.\n\n" \
316
+ " Appsignal.set_error(error) do |transaction|\n" \
317
+ " transaction.set_namespace(#{namespace.inspect})\n" \
318
+ " end\n\n" \
319
+ "Appsignal.set_error called on location: #{call_location}"
322
320
  end
323
321
  unless exception.is_a?(Exception)
324
322
  logger.error "Appsignal.set_error: Cannot set error. The given " \
@@ -360,8 +358,9 @@ module Appsignal
360
358
  # @since 2.2.0
361
359
  def set_action(action)
362
360
  return if !active? ||
363
- !Appsignal::Transaction.current? ||
364
- action.nil?
361
+ !Appsignal::Transaction.current? ||
362
+ action.nil?
363
+
365
364
  Appsignal::Transaction.current.set_action(action)
366
365
  end
367
366
 
@@ -399,8 +398,9 @@ module Appsignal
399
398
  # @since 2.2.0
400
399
  def set_namespace(namespace)
401
400
  return if !active? ||
402
- !Appsignal::Transaction.current? ||
403
- namespace.nil?
401
+ !Appsignal::Transaction.current? ||
402
+ namespace.nil?
403
+
404
404
  Appsignal::Transaction.current.set_namespace(namespace)
405
405
  end
406
406
 
@@ -454,9 +454,24 @@ module Appsignal
454
454
  # Only the last 20 added breadcrumbs will be saved.
455
455
  #
456
456
  # @example
457
- # Appsignal.add_breadcrumb("Navigation", "http://blablabla.com", "", { :response => 200 }, Time.now.utc)
458
- # Appsignal.add_breadcrumb("Network", "[GET] http://blablabla.com", "", { :response => 500 })
459
- # Appsignal.add_breadcrumb("UI", "closed modal(change_password)", "User closed modal without actions")
457
+ # Appsignal.add_breadcrumb(
458
+ # "Navigation",
459
+ # "http://blablabla.com",
460
+ # "",
461
+ # { :response => 200 },
462
+ # Time.now.utc
463
+ # )
464
+ # Appsignal.add_breadcrumb(
465
+ # "Network",
466
+ # "[GET] http://blablabla.com",
467
+ # "",
468
+ # { :response => 500 }
469
+ # )
470
+ # Appsignal.add_breadcrumb(
471
+ # "UI",
472
+ # "closed modal(change_password)",
473
+ # "User closed modal without actions"
474
+ # )
460
475
  #
461
476
  # @param category [String] category of breadcrumb
462
477
  # e.g. "UI", "Network", "Navigation", "Console".
@@ -583,10 +598,10 @@ module Appsignal
583
598
  # @return [Object] Returns the return value of the block.
584
599
  # @since 0.8.7
585
600
  def without_instrumentation
586
- Appsignal::Transaction.current.pause! if Appsignal::Transaction.current
601
+ Appsignal::Transaction.current&.pause!
587
602
  yield
588
603
  ensure
589
- Appsignal::Transaction.current.resume! if Appsignal::Transaction.current
604
+ Appsignal::Transaction.current&.resume!
590
605
  end
591
606
  end
592
607
  end
@@ -6,7 +6,7 @@ module Appsignal
6
6
  class ActionCableHook < Appsignal::Hooks::Hook
7
7
  register :action_cable
8
8
 
9
- REQUEST_ID = "_appsignal_action_cable.request_id".freeze
9
+ REQUEST_ID = "_appsignal_action_cable.request_id"
10
10
 
11
11
  def dependencies_present?
12
12
  defined?(::ActiveSupport::Notifications::Instrumenter) &&
@@ -15,7 +15,7 @@ module Appsignal
15
15
 
16
16
  def install
17
17
  require "appsignal/integrations/action_cable"
18
- ActionCable::Channel::Base.send(:prepend, Appsignal::Integrations::ActionCableIntegration)
18
+ ActionCable::Channel::Base.prepend Appsignal::Integrations::ActionCableIntegration
19
19
 
20
20
  install_callbacks
21
21
  end
@@ -23,7 +23,8 @@ module Appsignal
23
23
  private
24
24
 
25
25
  def install_callbacks
26
- ActionCable::Channel::Base.set_callback :subscribe, :around, :prepend => true do |channel, inner|
26
+ ActionCable::Channel::Base.set_callback :subscribe, :around,
27
+ :prepend => true do |channel, inner|
27
28
  # The request is only the original websocket request
28
29
  connection = channel.connection
29
30
  # #env is not available on the Rails ConnectionStub class used in the
@@ -55,7 +56,8 @@ module Appsignal
55
56
  end
56
57
  end
57
58
 
58
- ActionCable::Channel::Base.set_callback :unsubscribe, :around, :prepend => true do |channel, inner|
59
+ ActionCable::Channel::Base.set_callback :unsubscribe, :around,
60
+ :prepend => true do |channel, inner|
59
61
  # The request is only the original websocket request
60
62
  connection = channel.connection
61
63
  # #env is not available on the Rails ConnectionStub class used in the
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Appsignal
2
4
  class Hooks
3
5
  class ActionMailerHook < Appsignal::Hooks::Hook
@@ -37,12 +37,6 @@ module Appsignal
37
37
  )
38
38
  end
39
39
 
40
- super
41
- rescue Exception => exception # rubocop:disable Lint/RescueException
42
- job_status = :failed
43
- transaction.set_error(exception)
44
- raise exception
45
- ensure
46
40
  if transaction
47
41
  transaction.params =
48
42
  Appsignal::Utils::HashSanitizer.sanitize(
@@ -53,12 +47,19 @@ module Appsignal
53
47
  transaction_tags = ActiveJobHelpers.transaction_tags_for(job)
54
48
  transaction_tags["active_job_id"] = job["job_id"]
55
49
  provider_job_id = job["provider_job_id"]
56
- if provider_job_id
57
- transaction_tags[:provider_job_id] = provider_job_id
58
- end
50
+ transaction_tags[:provider_job_id] = provider_job_id if provider_job_id
59
51
  transaction.set_tags(transaction_tags)
60
52
 
61
- transaction.set_action_if_nil(ActiveJobHelpers.action_name(job))
53
+ transaction.set_action(ActiveJobHelpers.action_name(job))
54
+ end
55
+
56
+ super
57
+ rescue Exception => exception # rubocop:disable Lint/RescueException
58
+ job_status = :failed
59
+ transaction.set_error(exception)
60
+ raise exception
61
+ ensure
62
+ if transaction
62
63
  enqueued_at = job["enqueued_at"]
63
64
  if enqueued_at # Present in Rails 6 and up
64
65
  transaction.set_queue_start((Time.parse(enqueued_at).to_f * 1_000).to_i)
@@ -30,10 +30,9 @@ module Appsignal
30
30
  install_module(parent_integration_module::InstrumentIntegration)
31
31
  end
32
32
 
33
- # rubocop:disable Style/GuardClause
34
- if instrumenter.method_defined?(:finish_with_state)
35
- install_module(parent_integration_module::FinishStateIntegration)
36
- end
33
+ return unless instrumenter.method_defined?(:finish_with_state)
34
+
35
+ install_module(parent_integration_module::FinishStateIntegration)
37
36
  end
38
37
 
39
38
  def install_module(mod)
@@ -13,7 +13,7 @@ module Appsignal
13
13
 
14
14
  def install
15
15
  require "appsignal/integrations/data_mapper"
16
- ::DataObjects::Connection.send(:include, Appsignal::Hooks::DataMapperLogListener)
16
+ ::DataObjects::Connection.include Appsignal::Hooks::DataMapperLogListener
17
17
  end
18
18
  end
19
19
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Appsignal
2
4
  class Hooks
3
5
  # @api private
@@ -6,6 +8,7 @@ module Appsignal
6
8
 
7
9
  def dependencies_present?
8
10
  return false if Appsignal::System.jruby?
11
+
9
12
  require "gvltools"
10
13
  Appsignal.config && Appsignal::Probes::GvlProbe.dependencies_present?
11
14
  rescue LoadError
@@ -12,7 +12,7 @@ module Appsignal
12
12
 
13
13
  def install
14
14
  require "appsignal/integrations/http"
15
- HTTP::Client.send(:prepend, Appsignal::Integrations::HttpIntegration)
15
+ HTTP::Client.prepend Appsignal::Integrations::HttpIntegration
16
16
 
17
17
  Appsignal::Environment.report_enabled("http_rb")
18
18
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Appsignal
2
4
  class Hooks
3
5
  # @api private
@@ -14,7 +14,7 @@ module Appsignal
14
14
 
15
15
  def install
16
16
  require "appsignal/integrations/net_http"
17
- Net::HTTP.send(:prepend, Appsignal::Integrations::NetHttpIntegration)
17
+ Net::HTTP.prepend Appsignal::Integrations::NetHttpIntegration
18
18
 
19
19
  Appsignal::Environment.report_enabled("net_http")
20
20
  end
@@ -12,7 +12,7 @@ module Appsignal
12
12
 
13
13
  def install
14
14
  require "appsignal/integrations/que"
15
- ::Que::Job.send(:prepend, Appsignal::Integrations::QuePlugin)
15
+ ::Que::Job.prepend Appsignal::Integrations::QuePlugin
16
16
 
17
17
  ::Que.error_notifier = proc do |error, _job|
18
18
  Appsignal::Transaction.current.set_error(error)
@@ -12,7 +12,7 @@ module Appsignal
12
12
 
13
13
  def install
14
14
  require "appsignal/integrations/rake"
15
- ::Rake::Task.send(:prepend, Appsignal::Integrations::RakeIntegration)
15
+ ::Rake::Task.prepend Appsignal::Integrations::RakeIntegration
16
16
  end
17
17
  end
18
18
  end
@@ -14,7 +14,7 @@ module Appsignal
14
14
 
15
15
  def install
16
16
  require "appsignal/integrations/redis"
17
- ::Redis::Client.send(:prepend, Appsignal::Integrations::RedisIntegration)
17
+ ::Redis::Client.prepend Appsignal::Integrations::RedisIntegration
18
18
 
19
19
  Appsignal::Environment.report_enabled("redis")
20
20
  end
@@ -12,7 +12,7 @@ module Appsignal
12
12
 
13
13
  def install
14
14
  require "appsignal/integrations/resque"
15
- Resque::Job.send(:prepend, Appsignal::Integrations::ResqueIntegration)
15
+ Resque::Job.prepend Appsignal::Integrations::ResqueIntegration
16
16
  end
17
17
  end
18
18
  end
@@ -4,7 +4,7 @@ module Appsignal
4
4
  class Hooks
5
5
  # @api private
6
6
  class ShoryukenMiddleware
7
- def call(worker_instance, queue, sqs_msg, body)
7
+ def call(worker_instance, queue, sqs_msg, body, &block)
8
8
  batch = sqs_msg.is_a?(Array)
9
9
  attributes =
10
10
  if batch
@@ -61,9 +61,7 @@ module Appsignal
61
61
  options[:queue_start] = Time.at(attributes["SentTimestamp"].to_i / 1000)
62
62
  end
63
63
 
64
- Appsignal.monitor_transaction("perform_job.shoryuken", options) do
65
- yield
66
- end
64
+ Appsignal.monitor_transaction("perform_job.shoryuken", options, &block)
67
65
  end
68
66
  end
69
67
 
@@ -14,7 +14,7 @@ module Appsignal
14
14
  Appsignal::Minutely.probes.register :sidekiq, Appsignal::Probes::SidekiqProbe
15
15
 
16
16
  ::Sidekiq.configure_server do |config|
17
- config.error_handlers << \
17
+ config.error_handlers <<
18
18
  Appsignal::Integrations::SidekiqErrorHandler.new
19
19
 
20
20
  config.server_middleware do |chain|
@@ -13,8 +13,8 @@ module Appsignal
13
13
 
14
14
  def install
15
15
  require "appsignal/integrations/unicorn"
16
- ::Unicorn::HttpServer.send(:prepend, Appsignal::Integrations::UnicornIntegration::Server)
17
- ::Unicorn::Worker.send(:prepend, Appsignal::Integrations::UnicornIntegration::Worker)
16
+ ::Unicorn::HttpServer.prepend Appsignal::Integrations::UnicornIntegration::Server
17
+ ::Unicorn::Worker.prepend Appsignal::Integrations::UnicornIntegration::Worker
18
18
  end
19
19
  end
20
20
  end
@@ -12,7 +12,7 @@ module Appsignal
12
12
 
13
13
  def install
14
14
  require "appsignal/integrations/webmachine"
15
- ::Webmachine::Decision::FSM.send(:prepend, Appsignal::Integrations::WebmachineIntegration)
15
+ ::Webmachine::Decision::FSM.prepend Appsignal::Integrations::WebmachineIntegration
16
16
  end
17
17
  end
18
18
  end
@@ -78,8 +78,8 @@ module Appsignal
78
78
  callers = caller
79
79
  Appsignal::Utils::DeprecationMessage.message \
80
80
  "The constant Appsignal::Hooks::SidekiqPlugin has been deprecated. " \
81
- "Please update the constant name to Appsignal::Integrations::SidekiqMiddleware " \
82
- "in the following file to remove this message.\n#{callers.first}"
81
+ "Please update the constant name to Appsignal::Integrations::SidekiqMiddleware " \
82
+ "in the following file to remove this message.\n#{callers.first}"
83
83
  Appsignal::Integrations::SidekiqMiddleware
84
84
  else
85
85
  super
@@ -3,7 +3,7 @@
3
3
  module Appsignal
4
4
  module Integrations
5
5
  module ActiveSupportNotificationsIntegration
6
- BANG = "!".freeze
6
+ BANG = "!"
7
7
 
8
8
  module InstrumentIntegration
9
9
  def instrument(name, payload = {}, &block)
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  namespace :appsignal do
2
4
  task :deploy do
3
- appsignal_env = fetch(:appsignal_env, fetch(:stage, fetch(:rails_env, fetch(:rack_env, "production"))))
4
- user = fetch(:appsignal_user, ENV["USER"] || ENV["USERNAME"])
5
+ appsignal_env = fetch(:appsignal_env,
6
+ fetch(:stage, fetch(:rails_env, fetch(:rack_env, "production"))))
7
+ user = fetch(:appsignal_user, ENV["USER"] || ENV.fetch("USERNAME", nil))
5
8
  revision = fetch(:appsignal_revision, fetch(:current_revision))
6
9
 
7
10
  appsignal_config = Appsignal::Config.new(
@@ -16,7 +19,7 @@ namespace :appsignal do
16
19
  c.validate
17
20
  end
18
21
 
19
- if appsignal_config && appsignal_config.active?
22
+ if appsignal_config&.active?
20
23
  marker_data = {
21
24
  :revision => revision,
22
25
  :user => user
@@ -11,12 +11,13 @@ module Appsignal
11
11
 
12
12
  namespace :appsignal do
13
13
  task :deploy do
14
- env = fetch(:appsignal_env, fetch(:stage, fetch(:rails_env, fetch(:rack_env, "production"))))
15
- user = fetch(:appsignal_user, ENV["USER"] || ENV["USERNAME"])
14
+ env = fetch(:appsignal_env,
15
+ fetch(:stage, fetch(:rails_env, fetch(:rack_env, "production"))))
16
+ user = fetch(:appsignal_user, ENV["USER"] || ENV.fetch("USERNAME", nil))
16
17
  revision = fetch(:appsignal_revision, fetch(:current_revision))
17
18
 
18
19
  appsignal_config = Appsignal::Config.new(
19
- ENV["PWD"],
20
+ ENV.fetch("PWD", nil),
20
21
  env,
21
22
  {},
22
23
  Appsignal::Utils::IntegrationLogger.new(StringIO.new)
@@ -27,7 +28,7 @@ module Appsignal
27
28
  c.validate
28
29
  end
29
30
 
30
- if appsignal_config && appsignal_config.active?
31
+ if appsignal_config&.active?
31
32
  marker_data = {
32
33
  :revision => revision,
33
34
  :user => user
@@ -41,8 +41,8 @@ module Appsignal
41
41
  :class => class_name,
42
42
  :method => method_name,
43
43
  :metadata => {
44
- :id => extract_value(job, :id, nil, true),
45
- :queue => extract_value(job, :queue),
44
+ :id => extract_value(job, :id, nil, true),
45
+ :queue => extract_value(job, :queue),
46
46
  :priority => extract_value(job, :priority, 0),
47
47
  :attempts => extract_value(job, :attempts, 0)
48
48
  },
@@ -80,9 +80,7 @@ module Appsignal
80
80
  end
81
81
 
82
82
  # Attempt to read value from object
83
- if value.nil? && object_or_hash.respond_to?(field)
84
- value = object_or_hash.send(field)
85
- end
83
+ value = object_or_hash.send(field) if value.nil? && object_or_hash.respond_to?(field)
86
84
 
87
85
  # Set default value if nothing was found
88
86
  value = default_value if value.nil?
@@ -31,7 +31,7 @@ module Appsignal
31
31
  path = request.path # Path without namespaces
32
32
  endpoint = env["api.endpoint"]
33
33
 
34
- if endpoint && endpoint.options
34
+ if endpoint&.options
35
35
  options = endpoint.options
36
36
  request_method = options[:method].first.to_s.upcase
37
37
  klass = options[:for]
@@ -17,7 +17,7 @@ module Appsignal
17
17
  Appsignal.start_logger
18
18
  Appsignal.start
19
19
 
20
- ::Hanami::Action.send(:prepend, Appsignal::Integrations::HanamiIntegration) if Appsignal.active?
20
+ ::Hanami::Action.prepend Appsignal::Integrations::HanamiIntegration if Appsignal.active?
21
21
  end
22
22
  end
23
23
  end
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if defined?(Appsignal)
4
- Appsignal::Environment.report_enabled("object_instrumentation")
5
- end
3
+ Appsignal::Environment.report_enabled("object_instrumentation") if defined?(Appsignal)
6
4
 
7
5
  class Object
8
6
  def self.appsignal_instrument_class_method(method_name, options = {})
@@ -37,6 +35,7 @@ class Object
37
35
 
38
36
  def self.appsignal_reverse_class_name
39
37
  return "AnonymousClass" unless name
38
+
40
39
  name.split("::").reverse.join(".")
41
40
  end
42
41
 
@@ -59,9 +59,7 @@ module Appsignal::Integrations::PadrinoIntegration
59
59
  action_name = request.action if request.respond_to?(:action)
60
60
  action_name ||= ""
61
61
 
62
- unless action_name.empty?
63
- return "#{settings.name}:#{controller_name}##{action_name}"
64
- end
62
+ return "#{settings.name}:#{controller_name}##{action_name}" unless action_name.empty?
65
63
 
66
64
  # Older versions of Padrino work with a route object
67
65
  if request.respond_to?(:route_obj) && request.route_obj
@@ -74,7 +72,7 @@ module Appsignal::Integrations::PadrinoIntegration
74
72
  end
75
73
  end
76
74
 
77
- Padrino::Application.send(:prepend, Appsignal::Integrations::PadrinoIntegration)
75
+ Padrino::Application.prepend Appsignal::Integrations::PadrinoIntegration
78
76
 
79
77
  Padrino.after_load do
80
78
  Appsignal::Integrations::PadrinoPlugin.init
@@ -6,12 +6,12 @@ module Appsignal
6
6
  def _run(*)
7
7
  local_attrs = respond_to?(:que_attrs) ? que_attrs : attrs
8
8
  env = {
9
- :metadata => {
10
- :id => local_attrs[:job_id] || local_attrs[:id],
11
- :queue => local_attrs[:queue],
12
- :run_at => local_attrs[:run_at].to_s,
13
- :priority => local_attrs[:priority],
14
- :attempts => local_attrs[:error_count].to_i
9
+ :metadata => {
10
+ :id => local_attrs[:job_id] || local_attrs[:id],
11
+ :queue => local_attrs[:queue],
12
+ :run_at => local_attrs[:run_at].to_s,
13
+ :priority => local_attrs[:priority],
14
+ :attempts => local_attrs[:error_count].to_i
15
15
  },
16
16
  :params => local_attrs[:args]
17
17
  }
@@ -31,6 +31,78 @@ module Appsignal
31
31
  )
32
32
 
33
33
  Appsignal.start
34
+
35
+ if Appsignal.config[:enable_rails_error_reporter] && Rails.respond_to?(:error) # rubocop:disable Style/GuardClause
36
+ Rails.error.subscribe(Appsignal::Integrations::RailsErrorReporterSubscriber)
37
+ end
38
+ end
39
+ end
40
+
41
+ # Report errors reported by the Rails error reporter.
42
+ #
43
+ # We only report that are not reraised by the error reporter, using
44
+ # `Rails.error.handle`.
45
+ # @api private
46
+ class RailsErrorReporterSubscriber
47
+ class << self
48
+ def report(error, handled:, severity:, context: {}, source: nil)
49
+ # Ignore not handled errors. They are reraised by the error reporter
50
+ # and are caught and recorded by our Rails middleware.
51
+ return unless handled
52
+
53
+ Appsignal.send_error(error) do |transaction|
54
+ namespace, action_name, tags = context_for(context.dup)
55
+ transaction.set_namespace(namespace) if namespace
56
+ transaction.set_action(action_name) if action_name
57
+
58
+ tags[:severity] = severity
59
+ tags[:source] = source.to_s if source
60
+ transaction.set_tags(tags)
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def context_for(context)
67
+ tags = {}
68
+
69
+ appsignal_context = context.delete(:appsignal)
70
+ # Fetch the namespace and action name based on the Rails execution
71
+ # context.
72
+ controller = context.delete(:controller)
73
+ if controller
74
+ namespace = Appsignal::Transaction::HTTP_REQUEST
75
+ action_name = "#{controller.class.name}##{controller.action_name}"
76
+ end
77
+ # ActiveJob transaction naming relies on the current AppSignal
78
+ # transaction namespace and action name copying done after this.
79
+ context.delete(:job)
80
+
81
+ # Copy the transaction action name, namespace and other data from
82
+ # the currently active transaction, if not already set.
83
+ if Appsignal::Transaction.current?
84
+ current_transaction = Appsignal::Transaction.current
85
+ namespace = current_transaction.namespace
86
+
87
+ transaction_action = current_transaction.action
88
+ action_name = current_transaction.action if transaction_action
89
+
90
+ current_tags = current_transaction.tags
91
+ tags.merge!(current_tags) if current_tags
92
+ end
93
+
94
+ # Use the user override set in the context
95
+ if appsignal_context
96
+ context_namespace = appsignal_context[:namespace]
97
+ namespace = context_namespace if context_namespace
98
+
99
+ context_action_name = appsignal_context[:action]
100
+ action_name = context_action_name if context_action_name
101
+ end
102
+ tags.merge!(context)
103
+
104
+ [namespace, action_name, tags]
105
+ end
34
106
  end
35
107
  end
36
108
  end