appsignal 2.11.8-java → 3.0.1-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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/.rubocop_todo.yml +1 -1
  4. data/.semaphore/semaphore.yml +88 -111
  5. data/CHANGELOG.md +24 -0
  6. data/appsignal.gemspec +1 -1
  7. data/build_matrix.yml +11 -15
  8. data/lib/appsignal.rb +2 -29
  9. data/lib/appsignal/auth_check.rb +2 -8
  10. data/lib/appsignal/cli.rb +1 -23
  11. data/lib/appsignal/config.rb +1 -25
  12. data/lib/appsignal/event_formatter.rb +0 -25
  13. data/lib/appsignal/helpers/instrumentation.rb +69 -5
  14. data/lib/appsignal/hooks.rb +6 -13
  15. data/lib/appsignal/hooks/action_cable.rb +3 -34
  16. data/lib/appsignal/hooks/active_support_notifications.rb +7 -86
  17. data/lib/appsignal/hooks/celluloid.rb +5 -9
  18. data/lib/appsignal/hooks/net_http.rb +2 -12
  19. data/lib/appsignal/hooks/puma.rb +3 -5
  20. data/lib/appsignal/hooks/que.rb +1 -1
  21. data/lib/appsignal/hooks/rake.rb +2 -24
  22. data/lib/appsignal/hooks/redis.rb +2 -13
  23. data/lib/appsignal/hooks/resque.rb +2 -43
  24. data/lib/appsignal/hooks/sidekiq.rb +6 -143
  25. data/lib/appsignal/hooks/unicorn.rb +3 -24
  26. data/lib/appsignal/hooks/webmachine.rb +1 -7
  27. data/lib/appsignal/integrations/action_cable.rb +34 -0
  28. data/lib/appsignal/integrations/active_support_notifications.rb +77 -0
  29. data/lib/appsignal/integrations/net_http.rb +16 -0
  30. data/lib/appsignal/integrations/object.rb +39 -4
  31. data/lib/appsignal/integrations/padrino.rb +5 -7
  32. data/lib/appsignal/integrations/que.rb +26 -33
  33. data/lib/appsignal/integrations/railtie.rb +1 -4
  34. data/lib/appsignal/integrations/rake.rb +26 -2
  35. data/lib/appsignal/integrations/redis.rb +17 -0
  36. data/lib/appsignal/integrations/resque.rb +39 -10
  37. data/lib/appsignal/integrations/sidekiq.rb +171 -0
  38. data/lib/appsignal/integrations/unicorn.rb +28 -0
  39. data/lib/appsignal/integrations/webmachine.rb +22 -24
  40. data/lib/appsignal/minutely.rb +0 -12
  41. data/lib/appsignal/version.rb +1 -1
  42. data/spec/lib/appsignal/auth_check_spec.rb +1 -24
  43. data/spec/lib/appsignal/cli_spec.rb +1 -1
  44. data/spec/lib/appsignal/config_spec.rb +2 -66
  45. data/spec/lib/appsignal/event_formatter_spec.rb +0 -37
  46. data/spec/lib/appsignal/hooks/celluloid_spec.rb +6 -1
  47. data/spec/lib/appsignal/hooks/rake_spec.rb +1 -2
  48. data/spec/lib/appsignal/hooks/redis_spec.rb +50 -15
  49. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +12 -464
  50. data/spec/lib/appsignal/hooks/unicorn_spec.rb +14 -3
  51. data/spec/lib/appsignal/hooks/webmachine_spec.rb +2 -13
  52. data/spec/lib/appsignal/hooks_spec.rb +6 -22
  53. data/spec/lib/appsignal/integrations/object_spec.rb +91 -8
  54. data/spec/lib/appsignal/integrations/padrino_spec.rb +2 -3
  55. data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -45
  56. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +524 -0
  57. data/spec/lib/appsignal/integrations/webmachine_spec.rb +26 -8
  58. data/spec/lib/appsignal/minutely_spec.rb +0 -19
  59. data/spec/lib/appsignal/transaction_spec.rb +1 -14
  60. data/spec/lib/appsignal/transmitter_spec.rb +1 -1
  61. data/spec/lib/appsignal_spec.rb +162 -116
  62. data/spec/spec_helper.rb +1 -15
  63. metadata +11 -21
  64. data/lib/appsignal/cli/notify_of_deploy.rb +0 -131
  65. data/lib/appsignal/integrations/object_ruby_19.rb +0 -37
  66. data/lib/appsignal/integrations/object_ruby_modern.rb +0 -64
  67. data/lib/appsignal/integrations/resque_active_job.rb +0 -19
  68. data/lib/appsignal/js_exception_transaction.rb +0 -56
  69. data/lib/appsignal/rack/js_exception_catcher.rb +0 -80
  70. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +0 -180
  71. data/spec/lib/appsignal/integrations/object_19_spec.rb +0 -266
  72. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +0 -28
  73. data/spec/lib/appsignal/integrations/resque_spec.rb +0 -28
  74. data/spec/lib/appsignal/js_exception_transaction_spec.rb +0 -128
  75. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +0 -170
@@ -12,30 +12,9 @@ module Appsignal
12
12
  end
13
13
 
14
14
  def install
15
- # Make sure that appsignal is started and the last transaction
16
- # in a worker gets flushed.
17
- #
18
- # We'd love to be able to hook this into Unicorn in a less
19
- # intrusive way, but this is the best we can do given the
20
- # options we have.
21
-
22
- ::Unicorn::HttpServer.class_eval do
23
- alias worker_loop_without_appsignal worker_loop
24
-
25
- def worker_loop(worker)
26
- Appsignal.forked
27
- worker_loop_without_appsignal(worker)
28
- end
29
- end
30
-
31
- ::Unicorn::Worker.class_eval do
32
- alias close_without_appsignal close
33
-
34
- def close
35
- Appsignal.stop("unicorn")
36
- close_without_appsignal
37
- end
38
- end
15
+ require "appsignal/integrations/unicorn"
16
+ ::Unicorn::HttpServer.send(:prepend, Appsignal::Integrations::UnicornIntegration::Server)
17
+ ::Unicorn::Worker.send(:prepend, Appsignal::Integrations::UnicornIntegration::Worker)
39
18
  end
40
19
  end
41
20
  end
@@ -12,13 +12,7 @@ module Appsignal
12
12
 
13
13
  def install
14
14
  require "appsignal/integrations/webmachine"
15
- ::Webmachine::Decision::FSM.class_eval do
16
- include Appsignal::Integrations::WebmachinePlugin::FSM
17
- alias run_without_appsignal run
18
- alias run run_with_appsignal
19
- alias handle_exceptions_without_appsignal handle_exceptions
20
- alias handle_exceptions handle_exceptions_with_appsignal
21
- end
15
+ ::Webmachine::Decision::FSM.send(:prepend, Appsignal::Integrations::WebmachineIntegration)
22
16
  end
23
17
  end
24
18
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appsignal
4
+ module Integrations
5
+ module ActionCableIntegration
6
+ def perform_action(*args, &block)
7
+ # The request is only the original websocket request
8
+ env = connection.env
9
+ request = ActionDispatch::Request.new(env)
10
+ env[Appsignal::Hooks::ActionCableHook::REQUEST_ID] ||=
11
+ request.request_id || SecureRandom.uuid
12
+
13
+ transaction = Appsignal::Transaction.create(
14
+ env[Appsignal::Hooks::ActionCableHook::REQUEST_ID],
15
+ Appsignal::Transaction::ACTION_CABLE,
16
+ request
17
+ )
18
+
19
+ begin
20
+ super
21
+ rescue Exception => exception # rubocop:disable Lint/RescueException
22
+ transaction.set_error(exception)
23
+ raise exception
24
+ ensure
25
+ transaction.params = args.first
26
+ transaction.set_action_if_nil("#{self.class}##{args.first["action"]}")
27
+ transaction.set_metadata("path", request.path)
28
+ transaction.set_metadata("method", "websocket")
29
+ Appsignal::Transaction.complete_current!
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appsignal
4
+ module Integrations
5
+ module ActiveSupportNotificationsIntegration
6
+ BANG = "!".freeze
7
+
8
+ module InstrumentIntegration
9
+ def instrument(name, payload = {}, &block)
10
+ # Events that start with a bang are internal to Rails
11
+ instrument_this = name[0] != ActiveSupportNotificationsIntegration::BANG
12
+
13
+ Appsignal::Transaction.current.start_event if instrument_this
14
+
15
+ super
16
+ ensure
17
+ if instrument_this
18
+ title, body, body_format = Appsignal::EventFormatter.format(name, payload)
19
+ Appsignal::Transaction.current.finish_event(
20
+ name.to_s,
21
+ title,
22
+ body,
23
+ body_format
24
+ )
25
+ end
26
+ end
27
+ end
28
+
29
+ module StartFinishIntegration
30
+ def start(name, payload = {})
31
+ # Events that start with a bang are internal to Rails
32
+ instrument_this = name[0] != ActiveSupportNotificationsIntegration::BANG
33
+
34
+ Appsignal::Transaction.current.start_event if instrument_this
35
+
36
+ super
37
+ end
38
+
39
+ def finish(name, payload = {})
40
+ # Events that start with a bang are internal to Rails
41
+ instrument_this = name[0] != ActiveSupportNotificationsIntegration::BANG
42
+
43
+ if instrument_this
44
+ title, body, body_format = Appsignal::EventFormatter.format(name, payload)
45
+ Appsignal::Transaction.current.finish_event(
46
+ name.to_s,
47
+ title,
48
+ body,
49
+ body_format
50
+ )
51
+ end
52
+
53
+ super
54
+ end
55
+ end
56
+
57
+ module FinishStateIntegration
58
+ def finish_with_state(listeners_state, name, payload = {})
59
+ # Events that start with a bang are internal to Rails
60
+ instrument_this = name[0] != ActiveSupportNotificationsIntegration::BANG
61
+
62
+ if instrument_this
63
+ title, body, body_format = Appsignal::EventFormatter.format(name, payload)
64
+ Appsignal::Transaction.current.finish_event(
65
+ name.to_s,
66
+ title,
67
+ body,
68
+ body_format
69
+ )
70
+ end
71
+
72
+ super
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appsignal
4
+ module Integrations
5
+ module NetHttpIntegration
6
+ def request(request, body = nil, &block)
7
+ Appsignal.instrument(
8
+ "request.net_http",
9
+ "#{request.method} #{use_ssl? ? "https" : "http"}://#{request["host"] || address}"
10
+ ) do
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -4,8 +4,43 @@ if defined?(Appsignal)
4
4
  Appsignal::Environment.report_enabled("object_instrumentation")
5
5
  end
6
6
 
7
- if RUBY_VERSION < "2.0"
8
- require "appsignal/integrations/object_ruby_19"
9
- else
10
- require "appsignal/integrations/object_ruby_modern"
7
+ class Object
8
+ def self.appsignal_instrument_class_method(method_name, options = {})
9
+ singleton_class.send \
10
+ :alias_method, "appsignal_uninstrumented_#{method_name}", method_name
11
+ singleton_class.send(:define_method, method_name) do |*args, &block|
12
+ name = options.fetch(:name) do
13
+ "#{method_name}.class_method.#{appsignal_reverse_class_name}.other"
14
+ end
15
+ Appsignal.instrument name do
16
+ send "appsignal_uninstrumented_#{method_name}", *args, &block
17
+ end
18
+ end
19
+
20
+ if singleton_class.respond_to?(:ruby2_keywords, true) # rubocop:disable Style/GuardClause
21
+ singleton_class.send(:ruby2_keywords, method_name)
22
+ end
23
+ end
24
+
25
+ def self.appsignal_instrument_method(method_name, options = {})
26
+ alias_method "appsignal_uninstrumented_#{method_name}", method_name
27
+ define_method method_name do |*args, &block|
28
+ name = options.fetch(:name) do
29
+ "#{method_name}.#{appsignal_reverse_class_name}.other"
30
+ end
31
+ Appsignal.instrument name do
32
+ send "appsignal_uninstrumented_#{method_name}", *args, &block
33
+ end
34
+ end
35
+ ruby2_keywords method_name if respond_to?(:ruby2_keywords, true)
36
+ end
37
+
38
+ def self.appsignal_reverse_class_name
39
+ return "AnonymousClass" unless name
40
+ name.split("::").reverse.join(".")
41
+ end
42
+
43
+ def appsignal_reverse_class_name
44
+ self.class.appsignal_reverse_class_name
45
+ end
11
46
  end
@@ -19,13 +19,9 @@ module Appsignal
19
19
  end
20
20
  end
21
21
 
22
- module Padrino::Routing::InstanceMethods
23
- alias route_without_appsignal route!
24
-
22
+ module Appsignal::Integrations::PadrinoIntegration
25
23
  def route!(base = settings, pass_block = nil)
26
- if !Appsignal.active? || env["sinatra.static_file"]
27
- return route_without_appsignal(base, pass_block)
28
- end
24
+ return super if !Appsignal.active? || env["sinatra.static_file"]
29
25
 
30
26
  transaction = Appsignal::Transaction.create(
31
27
  SecureRandom.uuid,
@@ -34,7 +30,7 @@ module Padrino::Routing::InstanceMethods
34
30
  )
35
31
  begin
36
32
  Appsignal.instrument("process_action.padrino") do
37
- route_without_appsignal(base, pass_block)
33
+ super
38
34
  end
39
35
  rescue Exception => error # rubocop:disable Lint/RescueException
40
36
  transaction.set_error(error)
@@ -78,6 +74,8 @@ module Padrino::Routing::InstanceMethods
78
74
  end
79
75
  end
80
76
 
77
+ Padrino::Application.send(:prepend, Appsignal::Integrations::PadrinoIntegration)
78
+
81
79
  Padrino.after_load do
82
80
  Appsignal::Integrations::PadrinoPlugin.init
83
81
  end
@@ -3,42 +3,35 @@
3
3
  module Appsignal
4
4
  module Integrations
5
5
  module QuePlugin
6
- def self.included(base)
7
- base.class_eval do
8
- def _run_with_appsignal(*)
9
- local_attrs = respond_to?(:que_attrs) ? que_attrs : attrs
10
- env = {
11
- :metadata => {
12
- :id => local_attrs[:job_id] || local_attrs[:id],
13
- :queue => local_attrs[:queue],
14
- :run_at => local_attrs[:run_at].to_s,
15
- :priority => local_attrs[:priority],
16
- :attempts => local_attrs[:error_count].to_i
17
- },
18
- :params => local_attrs[:args]
19
- }
6
+ 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
+ }
20
18
 
21
- request = Appsignal::Transaction::GenericRequest.new(env)
19
+ request = Appsignal::Transaction::GenericRequest.new(env)
22
20
 
23
- transaction = Appsignal::Transaction.create(
24
- SecureRandom.uuid,
25
- Appsignal::Transaction::BACKGROUND_JOB,
26
- request
27
- )
21
+ transaction = Appsignal::Transaction.create(
22
+ SecureRandom.uuid,
23
+ Appsignal::Transaction::BACKGROUND_JOB,
24
+ request
25
+ )
28
26
 
29
- begin
30
- Appsignal.instrument("perform_job.que") { _run_without_appsignal }
31
- rescue Exception => error # rubocop:disable Lint/RescueException
32
- transaction.set_error(error)
33
- raise error
34
- ensure
35
- transaction.set_action_if_nil "#{local_attrs[:job_class]}#run"
36
- Appsignal::Transaction.complete_current!
37
- end
38
- end
39
-
40
- alias_method :_run_without_appsignal, :_run
41
- alias_method :_run, :_run_with_appsignal
27
+ begin
28
+ Appsignal.instrument("perform_job.que") { super }
29
+ rescue Exception => error # rubocop:disable Lint/RescueException
30
+ transaction.set_error(error)
31
+ raise error
32
+ ensure
33
+ transaction.set_action_if_nil "#{local_attrs[:job_class]}#run"
34
+ Appsignal::Transaction.complete_current!
42
35
  end
43
36
  end
44
37
  end
@@ -31,10 +31,7 @@ module Appsignal
31
31
  )
32
32
 
33
33
  if Appsignal.config[:enable_frontend_error_catching]
34
- app.middleware.insert_before(
35
- Appsignal::Rack::RailsInstrumentation,
36
- Appsignal::Rack::JSExceptionCatcher
37
- )
34
+ app.middleware.insert_before(Appsignal::Rack::RailsInstrumentation)
38
35
  end
39
36
 
40
37
  Appsignal.start
@@ -1,4 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Since version 1.0 requiring this file is not necessary anymore to get
4
- # Rake integration, it's just here for backward compatibility.
3
+ module Appsignal
4
+ module Integrations
5
+ module RakeIntegration
6
+ def execute(*args)
7
+ super
8
+ rescue Exception => error # rubocop:disable Lint/RescueException
9
+ # Format given arguments and cast to hash if possible
10
+ params, _ = args
11
+ params = params.to_hash if params.respond_to?(:to_hash)
12
+
13
+ transaction = Appsignal::Transaction.create(
14
+ SecureRandom.uuid,
15
+ Appsignal::Transaction::BACKGROUND_JOB,
16
+ Appsignal::Transaction::GenericRequest.new(
17
+ :params => params
18
+ )
19
+ )
20
+ transaction.set_action(name)
21
+ transaction.set_error(error)
22
+ transaction.complete
23
+ Appsignal.stop("rake")
24
+ raise error
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appsignal
4
+ module Integrations
5
+ module RedisIntegration
6
+ def process(commands, &block)
7
+ sanitized_commands = commands.map do |command, *args|
8
+ "#{command}#{" ?" * args.size}"
9
+ end.join("\n")
10
+
11
+ Appsignal.instrument "query.redis", id, sanitized_commands do
12
+ super
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -3,16 +3,45 @@
3
3
  module Appsignal
4
4
  module Integrations
5
5
  # @api private
6
- module ResquePlugin
7
- def self.extended(_)
8
- callers = caller
9
- Appsignal::Utils::DeprecationMessage.message \
10
- "The AppSignal ResquePlugin is deprecated and does " \
11
- "nothing on extend. In this version of the AppSignal Ruby gem " \
12
- "the integration with Resque is automatic on all Resque workers. " \
13
- "Please remove the following line from this file to remove this " \
14
- "message: extend Appsignal::Integrations::ResquePlugin\n" \
15
- "#{callers.first}"
6
+ module ResqueIntegration
7
+ def perform
8
+ transaction = Appsignal::Transaction.create(
9
+ SecureRandom.uuid,
10
+ Appsignal::Transaction::BACKGROUND_JOB,
11
+ Appsignal::Transaction::GenericRequest.new({})
12
+ )
13
+
14
+ Appsignal.instrument "perform.resque" do
15
+ super
16
+ end
17
+ rescue Exception => exception # rubocop:disable Lint/RescueException
18
+ transaction.set_error(exception)
19
+ raise exception
20
+ ensure
21
+ if transaction
22
+ transaction.set_action_if_nil("#{payload["class"]}#perform")
23
+ args =
24
+ Appsignal::Utils::HashSanitizer.sanitize(
25
+ ResqueHelpers.arguments(payload),
26
+ Appsignal.config[:filter_parameters]
27
+ )
28
+ transaction.params = args if args
29
+ transaction.set_tags("queue" => queue)
30
+
31
+ Appsignal::Transaction.complete_current!
32
+ end
33
+ Appsignal.stop("resque")
34
+ end
35
+ end
36
+
37
+ class ResqueHelpers
38
+ def self.arguments(payload)
39
+ case payload["class"]
40
+ when "ActiveJob::QueueAdapters::ResqueAdapter::JobWrapper"
41
+ nil # Set in the ActiveJob integration
42
+ else
43
+ payload["args"]
44
+ end
16
45
  end
17
46
  end
18
47
  end