appsignal 3.10.0-java → 3.12.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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +197 -0
  4. data/Gemfile +1 -0
  5. data/Rakefile +1 -1
  6. data/benchmark.rake +99 -42
  7. data/lib/appsignal/cli/demo.rb +0 -1
  8. data/lib/appsignal/cli/diagnose.rb +1 -1
  9. data/lib/appsignal/config.rb +204 -130
  10. data/lib/appsignal/demo.rb +16 -26
  11. data/lib/appsignal/event_formatter/rom/sql_formatter.rb +1 -0
  12. data/lib/appsignal/event_formatter.rb +3 -2
  13. data/lib/appsignal/helpers/instrumentation.rb +331 -19
  14. data/lib/appsignal/hooks/action_cable.rb +21 -16
  15. data/lib/appsignal/hooks/active_job.rb +14 -8
  16. data/lib/appsignal/hooks/delayed_job.rb +1 -1
  17. data/lib/appsignal/hooks/shoryuken.rb +3 -63
  18. data/lib/appsignal/integrations/action_cable.rb +5 -7
  19. data/lib/appsignal/integrations/active_support_notifications.rb +1 -0
  20. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +36 -35
  21. data/lib/appsignal/integrations/data_mapper.rb +1 -0
  22. data/lib/appsignal/integrations/delayed_job_plugin.rb +27 -33
  23. data/lib/appsignal/integrations/dry_monitor.rb +1 -0
  24. data/lib/appsignal/integrations/excon.rb +1 -0
  25. data/lib/appsignal/integrations/grape.rb +7 -0
  26. data/lib/appsignal/integrations/hanami.rb +8 -43
  27. data/lib/appsignal/integrations/http.rb +1 -0
  28. data/lib/appsignal/integrations/net_http.rb +1 -0
  29. data/lib/appsignal/integrations/object.rb +6 -0
  30. data/lib/appsignal/integrations/padrino.rb +8 -73
  31. data/lib/appsignal/integrations/que.rb +13 -20
  32. data/lib/appsignal/integrations/railtie.rb +36 -14
  33. data/lib/appsignal/integrations/rake.rb +1 -5
  34. data/lib/appsignal/integrations/redis.rb +1 -0
  35. data/lib/appsignal/integrations/redis_client.rb +1 -0
  36. data/lib/appsignal/integrations/resque.rb +2 -5
  37. data/lib/appsignal/integrations/shoryuken.rb +75 -0
  38. data/lib/appsignal/integrations/sidekiq.rb +7 -15
  39. data/lib/appsignal/integrations/sinatra.rb +8 -19
  40. data/lib/appsignal/integrations/unicorn.rb +1 -0
  41. data/lib/appsignal/integrations/webmachine.rb +2 -5
  42. data/lib/appsignal/loaders/grape.rb +13 -0
  43. data/lib/appsignal/loaders/hanami.rb +40 -0
  44. data/lib/appsignal/loaders/padrino.rb +68 -0
  45. data/lib/appsignal/loaders/sinatra.rb +24 -0
  46. data/lib/appsignal/loaders.rb +92 -0
  47. data/lib/appsignal/logger.rb +7 -3
  48. data/lib/appsignal/probes/helpers.rb +1 -0
  49. data/lib/appsignal/probes/mri.rb +1 -0
  50. data/lib/appsignal/probes/sidekiq.rb +1 -0
  51. data/lib/appsignal/probes.rb +3 -0
  52. data/lib/appsignal/rack/abstract_middleware.rb +20 -13
  53. data/lib/appsignal/rack/event_handler.rb +44 -13
  54. data/lib/appsignal/rack/generic_instrumentation.rb +1 -0
  55. data/lib/appsignal/rack/grape_middleware.rb +2 -1
  56. data/lib/appsignal/rack/streaming_listener.rb +1 -0
  57. data/lib/appsignal/rack.rb +35 -0
  58. data/lib/appsignal/span.rb +1 -0
  59. data/lib/appsignal/transaction.rb +308 -101
  60. data/lib/appsignal/utils/data.rb +0 -1
  61. data/lib/appsignal/utils/hash_sanitizer.rb +0 -1
  62. data/lib/appsignal/utils/integration_logger.rb +0 -13
  63. data/lib/appsignal/utils/integration_memory_logger.rb +0 -13
  64. data/lib/appsignal/utils/json.rb +0 -1
  65. data/lib/appsignal/utils/query_params_sanitizer.rb +0 -1
  66. data/lib/appsignal/utils/stdout_and_logger_message.rb +0 -1
  67. data/lib/appsignal/utils.rb +6 -0
  68. data/lib/appsignal/version.rb +1 -1
  69. data/lib/appsignal.rb +169 -14
  70. data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
  71. data/spec/lib/appsignal/cli/demo_spec.rb +0 -1
  72. data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +1 -1
  73. data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1
  74. data/spec/lib/appsignal/config_spec.rb +291 -44
  75. data/spec/lib/appsignal/demo_spec.rb +1 -2
  76. data/spec/lib/appsignal/environment_spec.rb +4 -2
  77. data/spec/lib/appsignal/hooks/action_cable_spec.rb +43 -74
  78. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +3 -6
  79. data/spec/lib/appsignal/hooks/activejob_spec.rb +12 -3
  80. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +2 -443
  81. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +4 -7
  82. data/spec/lib/appsignal/hooks/excon_spec.rb +3 -6
  83. data/spec/lib/appsignal/hooks/gvl_spec.rb +2 -2
  84. data/spec/lib/appsignal/hooks/http_spec.rb +1 -3
  85. data/spec/lib/appsignal/hooks/net_http_spec.rb +1 -1
  86. data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -8
  87. data/spec/lib/appsignal/hooks/redis_spec.rb +3 -6
  88. data/spec/lib/appsignal/hooks/resque_spec.rb +1 -1
  89. data/spec/lib/appsignal/hooks/sequel_spec.rb +3 -5
  90. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -171
  91. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +1 -1
  92. data/spec/lib/appsignal/hooks/webmachine_spec.rb +1 -1
  93. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +459 -0
  94. data/spec/lib/appsignal/integrations/grape_spec.rb +36 -0
  95. data/spec/lib/appsignal/integrations/hanami_spec.rb +9 -178
  96. data/spec/lib/appsignal/integrations/http_spec.rb +1 -5
  97. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +4 -2
  98. data/spec/lib/appsignal/integrations/net_http_spec.rb +1 -1
  99. data/spec/lib/appsignal/integrations/object_spec.rb +1 -3
  100. data/spec/lib/appsignal/integrations/padrino_spec.rb +8 -330
  101. data/spec/lib/appsignal/integrations/que_spec.rb +3 -4
  102. data/spec/lib/appsignal/integrations/railtie_spec.rb +275 -191
  103. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +167 -0
  104. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +15 -13
  105. data/spec/lib/appsignal/integrations/sinatra_spec.rb +9 -104
  106. data/spec/lib/appsignal/integrations/webmachine_spec.rb +13 -1
  107. data/spec/lib/appsignal/loaders/grape_spec.rb +12 -0
  108. data/spec/lib/appsignal/loaders/hanami_spec.rb +95 -0
  109. data/spec/lib/appsignal/loaders/padrino_spec.rb +277 -0
  110. data/spec/lib/appsignal/loaders/sinatra_spec.rb +47 -0
  111. data/spec/lib/appsignal/loaders_spec.rb +137 -0
  112. data/spec/lib/appsignal/probes/sidekiq_spec.rb +1 -1
  113. data/spec/lib/appsignal/probes_spec.rb +6 -5
  114. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +51 -5
  115. data/spec/lib/appsignal/rack/event_handler_spec.rb +114 -10
  116. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +1 -1
  117. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +2 -35
  118. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +1 -1
  119. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +4 -2
  120. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +3 -3
  121. data/spec/lib/appsignal/rack_spec.rb +63 -0
  122. data/spec/lib/appsignal/span_spec.rb +1 -3
  123. data/spec/lib/appsignal/transaction_spec.rb +1640 -1075
  124. data/spec/lib/appsignal/utils/integration_logger_spec.rb +12 -16
  125. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -10
  126. data/spec/lib/appsignal_spec.rb +601 -36
  127. data/spec/lib/puma/appsignal_spec.rb +0 -3
  128. data/spec/spec_helper.rb +5 -4
  129. data/spec/support/helpers/config_helpers.rb +2 -1
  130. data/spec/support/helpers/loader_helper.rb +21 -0
  131. data/spec/support/helpers/transaction_helpers.rb +44 -20
  132. data/spec/support/matchers/transaction.rb +15 -1
  133. data/spec/support/stubs/appsignal/loaders/loader_stub.rb +7 -0
  134. data/spec/support/testing.rb +47 -1
  135. metadata +19 -2
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
+ # @api private
5
6
  module ActiveSupportNotificationsIntegration
6
7
  BANG = "!"
7
8
 
@@ -1,47 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- # @todo Move to sub-namespace
5
- # @api private
6
- class Capistrano
7
- def self.tasks(config)
8
- config.load do # rubocop:disable Metrics/BlockLength
9
- after "deploy", "appsignal:deploy"
10
- after "deploy:migrations", "appsignal:deploy"
4
+ module Integrations
5
+ # @api private
6
+ class Capistrano
7
+ def self.tasks(config)
8
+ config.load do # rubocop:disable Metrics/BlockLength
9
+ after "deploy", "appsignal:deploy"
10
+ after "deploy:migrations", "appsignal:deploy"
11
11
 
12
- namespace :appsignal do
13
- task :deploy do
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))
17
- revision = fetch(:appsignal_revision, fetch(:current_revision))
12
+ namespace :appsignal do
13
+ task :deploy do
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))
17
+ revision = fetch(:appsignal_revision, fetch(:current_revision))
18
18
 
19
- appsignal_config = Appsignal::Config.new(
20
- ENV.fetch("PWD", nil),
21
- env,
22
- {},
23
- Appsignal::Utils::IntegrationLogger.new(StringIO.new)
24
- ).tap do |c|
25
- fetch(:appsignal_config, {}).each do |key, value|
26
- c[key] = value
19
+ appsignal_config = Appsignal::Config.new(
20
+ ENV.fetch("PWD", nil),
21
+ env,
22
+ {},
23
+ Appsignal::Utils::IntegrationLogger.new(StringIO.new)
24
+ ).tap do |c|
25
+ fetch(:appsignal_config, {}).each do |key, value|
26
+ c[key] = value
27
+ end
28
+ c.validate
27
29
  end
28
- c.validate
29
- end
30
30
 
31
- if appsignal_config&.active?
32
- marker_data = {
33
- :revision => revision,
34
- :user => user
35
- }
31
+ if appsignal_config&.active?
32
+ marker_data = {
33
+ :revision => revision,
34
+ :user => user
35
+ }
36
36
 
37
- marker = Marker.new(marker_data, appsignal_config)
38
- if config.dry_run
39
- puts "Dry run: AppSignal deploy marker not actually sent."
37
+ marker = Marker.new(marker_data, appsignal_config)
38
+ if config.dry_run
39
+ puts "Dry run: AppSignal deploy marker not actually sent."
40
+ else
41
+ marker.transmit
42
+ end
40
43
  else
41
- marker.transmit
44
+ puts "Not notifying of deploy, config is not active for environment: #{env}"
42
45
  end
43
- else
44
- puts "Not notifying of deploy, config is not active for environment: #{env}"
45
46
  end
46
47
  end
47
48
  end
@@ -51,5 +52,5 @@ module Appsignal
51
52
  end
52
53
 
53
54
  if ::Capistrano::Configuration.instance
54
- Appsignal::Capistrano.tasks(::Capistrano::Configuration.instance)
55
+ Appsignal::Integrations::Capistrano.tasks(::Capistrano::Configuration.instance)
55
56
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  class Hooks
5
+ # @api private
5
6
  module DataMapperLogListener
6
7
  SQL_CLASSES = [
7
8
  "DataObjects::SqlServer::Connection",
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- class Hooks
4
+ module Integrations
5
5
  # @api private
6
6
  class DelayedJobPlugin < ::Delayed::Plugin
7
7
  extend Appsignal::Hooks::Helpers
@@ -17,52 +17,46 @@ module Appsignal
17
17
  end
18
18
 
19
19
  def self.invoke_with_instrumentation(job, block)
20
- payload = job.payload_object
20
+ transaction =
21
+ Appsignal::Transaction.create(Appsignal::Transaction::BACKGROUND_JOB)
21
22
 
23
+ Appsignal.instrument("perform_job.delayed_job") do
24
+ block.call(job)
25
+ end
26
+ rescue Exception => error # rubocop:disable Lint/RescueException
27
+ transaction.set_error(error)
28
+ raise
29
+ ensure
30
+ payload = job.payload_object
22
31
  if payload.respond_to? :job_data
23
32
  # ActiveJob
24
33
  job_data = payload.job_data
25
- args = job_data.fetch("arguments", {})
26
- class_name = job_data["job_class"]
27
- method_name = "perform"
34
+ transaction.set_action_if_nil("#{job_data["job_class"]}#perform")
35
+ transaction.set_params_if_nil(job_data.fetch("arguments", {}))
28
36
  else
29
37
  # Delayed Job
30
- args = extract_value(payload, :args, {})
31
- class_name, method_name = class_and_method_name_from_object_or_hash(payload, job.name)
38
+ transaction.set_action_if_nil(action_name_from_payload(payload, job.name))
39
+ transaction.set_params_if_nil(extract_value(payload, :args, {}))
32
40
  end
33
41
 
34
- params = Appsignal::Utils::HashSanitizer.sanitize(
35
- args,
36
- Appsignal.config[:filter_parameters]
42
+ transaction.set_tags(
43
+ :id => extract_value(job, :id, nil, true),
44
+ :queue => extract_value(job, :queue),
45
+ :priority => extract_value(job, :priority, 0),
46
+ :attempts => extract_value(job, :attempts, 0)
37
47
  )
38
48
 
39
- Appsignal.monitor_transaction(
40
- "perform_job.delayed_job",
41
- :class => class_name,
42
- :method => method_name,
43
- :metadata => {
44
- :id => extract_value(job, :id, nil, true),
45
- :queue => extract_value(job, :queue),
46
- :priority => extract_value(job, :priority, 0),
47
- :attempts => extract_value(job, :attempts, 0)
48
- },
49
- :params => params,
50
- :queue_start => extract_value(job, :run_at)
51
- ) do
52
- block.call(job)
53
- end
49
+ transaction.set_queue_start(extract_value(job, :run_at)&.to_i&.* 1_000)
50
+
51
+ Appsignal::Transaction.complete_current!
54
52
  end
55
53
 
56
- def self.class_and_method_name_from_object_or_hash(payload, default_name)
54
+ def self.action_name_from_payload(payload, default_name)
57
55
  # Attempt to find appsignal_name override
58
56
  class_and_method_name = extract_value(payload, :appsignal_name, nil)
59
- return class_and_method_name.split("#") if class_and_method_name.is_a?(String)
60
-
61
- pound_split = default_name.split("#")
62
- return pound_split if pound_split.length == 2
63
-
64
- dot_split = default_name.split(".")
65
- return default_name if dot_split.length == 2
57
+ return class_and_method_name if class_and_method_name.is_a?(String)
58
+ return default_name if default_name.split("#").length == 2
59
+ return default_name if default_name.split(".").length == 2
66
60
 
67
61
  "#{default_name}#perform"
68
62
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
+ # @api private
5
6
  module DryMonitorIntegration
6
7
  def instrument(event_id, payload = {}, &block)
7
8
  Appsignal::Transaction.current.start_event
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
+ # @api private
5
6
  module ExconIntegration
6
7
  def self.instrument(name, data, &block)
7
8
  namespace, *event = name.split(".")
@@ -3,6 +3,13 @@
3
3
  require "appsignal"
4
4
  require "appsignal/rack/grape_middleware"
5
5
 
6
+ Appsignal::Utils::StdoutAndLoggerMessage.warning(
7
+ "The 'require \"appsignal/integrations/grape\"' file require integration " \
8
+ "method is deprecated. " \
9
+ "Please follow the Grape setup guide in our docs for the new method: " \
10
+ "https://docs.appsignal.com/ruby/integrations/grape.html"
11
+ )
12
+
6
13
  Appsignal.internal_logger.debug("Loading Grape integration")
7
14
 
8
15
  module Appsignal
@@ -1,48 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "appsignal"
4
- require "appsignal/rack/hanami_middleware"
5
4
 
6
- module Appsignal
7
- module Integrations
8
- # @api private
9
- module HanamiPlugin
10
- def self.init
11
- Appsignal.internal_logger.debug("Loading Hanami integration")
5
+ Appsignal::Utils::StdoutAndLoggerMessage.warning(
6
+ "The 'require \"appsignal/integrations/hanami\"' file require integration " \
7
+ "method is deprecated. " \
8
+ "Please follow the Hanami setup guide in our docs for the new method: " \
9
+ "https://docs.appsignal.com/ruby/integrations/hanami.html"
10
+ )
12
11
 
13
- hanami_app_config = ::Hanami.app.config
14
-
15
- unless Appsignal.active?
16
- Appsignal.config = Appsignal::Config.new(
17
- hanami_app_config.root || Dir.pwd,
18
- hanami_app_config.env
19
- )
20
- Appsignal.start
21
- end
22
-
23
- return unless Appsignal.active?
24
-
25
- hanami_app_config.middleware.use(
26
- ::Rack::Events,
27
- [Appsignal::Rack::EventHandler.new]
28
- )
29
- hanami_app_config.middleware.use(Appsignal::Rack::HanamiMiddleware)
30
-
31
- ::Hanami::Action.prepend Appsignal::Integrations::HanamiIntegration
32
- end
33
- end
34
-
35
- # @api private
36
- module HanamiIntegration
37
- def call(env)
38
- super
39
- ensure
40
- transaction = env[::Appsignal::Rack::APPSIGNAL_TRANSACTION]
41
-
42
- transaction&.set_action_if_nil(self.class.name)
43
- end
44
- end
45
- end
46
- end
47
-
48
- Appsignal::Integrations::HanamiPlugin.init unless Appsignal.testing?
12
+ Appsignal.load(:hanami)
13
+ Appsignal.start
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
+ # @api private
5
6
  module HttpIntegration
6
7
  def request(verb, uri, opts = {})
7
8
  parsed_request_uri = uri.is_a?(URI) ? uri : URI.parse(uri.to_s)
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
+ # @api private
5
6
  module NetHttpIntegration
6
7
  def request(request, body = nil, &block)
7
8
  Appsignal.instrument(
@@ -3,6 +3,8 @@
3
3
  Appsignal::Environment.report_enabled("object_instrumentation") if defined?(Appsignal)
4
4
 
5
5
  class Object
6
+ # @see https://docs.appsignal.com/ruby/instrumentation/method-instrumentation.html
7
+ # Method instrumentation documentation.
6
8
  def self.appsignal_instrument_class_method(method_name, options = {})
7
9
  singleton_class.send \
8
10
  :alias_method, "appsignal_uninstrumented_#{method_name}", method_name
@@ -20,6 +22,8 @@ class Object
20
22
  end
21
23
  end
22
24
 
25
+ # @see https://docs.appsignal.com/ruby/instrumentation/method-instrumentation.html
26
+ # Method instrumentation documentation.
23
27
  def self.appsignal_instrument_method(method_name, options = {})
24
28
  alias_method "appsignal_uninstrumented_#{method_name}", method_name
25
29
  define_method method_name do |*args, &block|
@@ -33,12 +37,14 @@ class Object
33
37
  ruby2_keywords method_name if respond_to?(:ruby2_keywords, true)
34
38
  end
35
39
 
40
+ # @api private
36
41
  def self.appsignal_reverse_class_name
37
42
  return "AnonymousClass" unless name
38
43
 
39
44
  name.split("::").reverse.join(".")
40
45
  end
41
46
 
47
+ # @api private
42
48
  def appsignal_reverse_class_name
43
49
  self.class.appsignal_reverse_class_name
44
50
  end
@@ -1,78 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "appsignal"
4
- require "appsignal/rack/sinatra_instrumentation"
5
4
 
6
- module Appsignal
7
- module Integrations
8
- # @api private
9
- module PadrinoPlugin
10
- def self.init
11
- Padrino::Application.prepend Appsignal::Integrations::PadrinoIntegration
5
+ Appsignal::Utils::StdoutAndLoggerMessage.warning(
6
+ "The 'require \"appsignal/integrations/padrino\"' file require integration " \
7
+ "method is deprecated. " \
8
+ "Please follow the Padrino setup guide in our docs for the new method: " \
9
+ "https://docs.appsignal.com/ruby/integrations/padrino.html"
10
+ )
12
11
 
13
- Padrino.before_load do
14
- Appsignal.internal_logger.debug("Loading Padrino (#{Padrino::VERSION}) integration")
15
-
16
- unless Appsignal.active?
17
- root = Padrino.mounted_root
18
- Appsignal.config = Appsignal::Config.new(root, Padrino.env)
19
- Appsignal.start
20
- end
21
-
22
- next unless Appsignal.active?
23
-
24
- Padrino.use ::Rack::Events, [Appsignal::Rack::EventHandler.new]
25
- Padrino.use Appsignal::Rack::SinatraBaseInstrumentation,
26
- :instrument_event_name => "process_action.padrino"
27
- end
28
- end
29
- end
30
- end
31
- end
32
-
33
- module Appsignal
34
- module Integrations
35
- # @api private
36
- module PadrinoIntegration
37
- def route!(base = settings, pass_block = nil)
38
- return super if !Appsignal.active? || env["sinatra.static_file"]
39
-
40
- begin
41
- super
42
- ensure
43
- transaction = Appsignal::Transaction.current
44
- transaction.set_action_if_nil(get_payload_action(request))
45
- end
46
- end
47
-
48
- private
49
-
50
- def get_payload_action(request)
51
- # Short-circuit is there's no request object to obtain information from
52
- return settings.name.to_s unless request
53
-
54
- # Newer versions expose the action / controller on the request class.
55
- # Newer versions also still expose a route_obj so we must prioritize the
56
- # action/fullpath methods.
57
- # The `request.action` and `request.controller` values are `nil` when a
58
- # endpoint is not found, `""` if not specified by the user.
59
- controller_name = request.controller if request.respond_to?(:controller)
60
- action_name = request.action if request.respond_to?(:action)
61
- action_name ||= ""
62
-
63
- return "#{settings.name}:#{controller_name}##{action_name}" unless action_name.empty?
64
-
65
- # Older versions of Padrino work with a route object
66
- if request.respond_to?(:route_obj) && request.route_obj
67
- return "#{settings.name}:#{request.route_obj.original_path}"
68
- end
69
-
70
- # Fall back to the application name if we haven't found an action name in
71
- # any previous methods.
72
- "#{settings.name}#unknown"
73
- end
74
- end
75
- end
76
- end
77
-
78
- Appsignal::Integrations::PadrinoPlugin.init
12
+ Appsignal.load(:padrino)
13
+ Appsignal.start
@@ -2,27 +2,11 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
+ # @api private
5
6
  module QuePlugin
6
7
  def _run(*)
7
- local_attrs = respond_to?(:que_attrs) ? que_attrs : attrs
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
15
- },
16
- :params => local_attrs[:args]
17
- }
18
-
19
- request = Appsignal::Transaction::GenericRequest.new(env)
20
-
21
- transaction = Appsignal::Transaction.create(
22
- SecureRandom.uuid,
23
- Appsignal::Transaction::BACKGROUND_JOB,
24
- request
25
- )
8
+ transaction =
9
+ Appsignal::Transaction.create(Appsignal::Transaction::BACKGROUND_JOB)
26
10
 
27
11
  begin
28
12
  Appsignal.instrument("perform_job.que") { super }
@@ -30,7 +14,16 @@ module Appsignal
30
14
  transaction.set_error(error)
31
15
  raise error
32
16
  ensure
33
- transaction.set_action_if_nil "#{local_attrs[:job_class]}#run"
17
+ local_attrs = respond_to?(:que_attrs) ? que_attrs : attrs
18
+ transaction.set_action_if_nil("#{local_attrs[:job_class]}#run")
19
+ transaction.set_params_if_nil(local_attrs[:args])
20
+ transaction.set_tags(
21
+ "id" => local_attrs[:job_id] || local_attrs[:id],
22
+ "queue" => local_attrs[:queue],
23
+ "run_at" => local_attrs[:run_at].to_s,
24
+ "priority" => local_attrs[:priority],
25
+ "attempts" => local_attrs[:error_count].to_i
26
+ )
34
27
  Appsignal::Transaction.complete_current!
35
28
  end
36
29
  end
@@ -9,23 +9,49 @@ module Appsignal
9
9
  module Integrations
10
10
  # @api private
11
11
  class Railtie < ::Rails::Railtie
12
+ config.appsignal = ActiveSupport::OrderedOptions.new
13
+ config.appsignal.start_at = :on_load
14
+
15
+ # Run after the Rails framework is loaded
12
16
  initializer "appsignal.configure_rails_initialization" do |app|
13
- Appsignal::Integrations::Railtie.initialize_appsignal(app)
17
+ Appsignal::Integrations::Railtie.on_load(app)
18
+ end
19
+
20
+ # Run after the Rails app's initializers are run
21
+ config.after_initialize do |app|
22
+ Appsignal::Integrations::Railtie.after_initialize(app)
14
23
  end
15
24
 
16
25
  console do
17
26
  Appsignal::Probes.stop
18
27
  end
19
28
 
20
- def self.initialize_appsignal(app)
21
- # Load config
22
- Appsignal.config = Appsignal::Config.new(
23
- Rails.root,
24
- Rails.env,
25
- :name => Appsignal::Utils::RailsHelper.detected_rails_app_name,
26
- :log_path => Rails.root.join("log")
27
- )
29
+ def self.on_load(app)
30
+ Appsignal::Integrations::Railtie.add_instrumentation_middleware(app)
31
+
32
+ return unless app.config.appsignal.start_at == :on_load
33
+
34
+ Appsignal::Integrations::Railtie.start
35
+ end
36
+
37
+ def self.after_initialize(app)
38
+ Appsignal::Integrations::Railtie.start if app.config.appsignal.start_at == :after_initialize
39
+ end
28
40
 
41
+ def self.start
42
+ unless Appsignal.config
43
+ Appsignal._config = Appsignal::Config.new(
44
+ Rails.root,
45
+ Rails.env,
46
+ :name => Appsignal::Utils::RailsHelper.detected_rails_app_name,
47
+ :log_path => Rails.root.join("log")
48
+ )
49
+ end
50
+ Appsignal.start
51
+ initialize_error_reporter
52
+ end
53
+
54
+ def self.add_instrumentation_middleware(app)
29
55
  app.middleware.insert(
30
56
  0,
31
57
  ::Rack::Events,
@@ -35,10 +61,6 @@ module Appsignal
35
61
  ActionDispatch::DebugExceptions,
36
62
  Appsignal::Rack::RailsInstrumentation
37
63
  )
38
-
39
- Appsignal.start
40
-
41
- initialize_error_reporter
42
64
  end
43
65
 
44
66
  def self.initialize_error_reporter
@@ -69,7 +91,7 @@ module Appsignal
69
91
  transaction.set_metadata("path", path)
70
92
  transaction.set_metadata("method", method)
71
93
  transaction.set_params_if_nil(params)
72
- transaction.set_sample_data("custom_data", custom_data) if custom_data
94
+ transaction.set_custom_data(custom_data) if custom_data
73
95
 
74
96
  tags[:severity] = severity
75
97
  tags[:source] = source.to_s if source
@@ -33,11 +33,7 @@ module Appsignal
33
33
  private
34
34
 
35
35
  def _appsignal_create_transaction
36
- Appsignal::Transaction.create(
37
- SecureRandom.uuid,
38
- Appsignal::Transaction::BACKGROUND_JOB,
39
- Appsignal::Transaction::GenericRequest.new({})
40
- )
36
+ Appsignal::Transaction.create(Appsignal::Transaction::BACKGROUND_JOB)
41
37
  end
42
38
  end
43
39
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
+ # @api private
5
6
  module RedisIntegration
6
7
  def write(command)
7
8
  sanitized_command =
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
+ # @api private
5
6
  module RedisClientIntegration
6
7
  def write(command)
7
8
  sanitized_command =
@@ -5,11 +5,7 @@ module Appsignal
5
5
  # @api private
6
6
  module ResqueIntegration
7
7
  def perform
8
- transaction = Appsignal::Transaction.create(
9
- SecureRandom.uuid,
10
- Appsignal::Transaction::BACKGROUND_JOB,
11
- Appsignal::Transaction::GenericRequest.new({})
12
- )
8
+ transaction = Appsignal::Transaction.create(Appsignal::Transaction::BACKGROUND_JOB)
13
9
 
14
10
  Appsignal.instrument "perform.resque" do
15
11
  super
@@ -34,6 +30,7 @@ module Appsignal
34
30
  end
35
31
  end
36
32
 
33
+ # @api private
37
34
  class ResqueHelpers
38
35
  def self.arguments(payload)
39
36
  case payload["class"]