appsignal 2.11.1-java → 3.0.0.beta.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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -1
  3. data/.semaphore/semaphore.yml +197 -23
  4. data/CHANGELOG.md +25 -0
  5. data/README.md +9 -0
  6. data/Rakefile +9 -6
  7. data/build_matrix.yml +13 -4
  8. data/ext/agent.yml +17 -17
  9. data/ext/base.rb +12 -9
  10. data/gemfiles/no_dependencies.gemfile +7 -0
  11. data/gemfiles/resque-2.gemfile +0 -1
  12. data/gemfiles/webmachine.gemfile +1 -0
  13. data/lib/appsignal.rb +1 -27
  14. data/lib/appsignal/auth_check.rb +2 -8
  15. data/lib/appsignal/cli.rb +1 -23
  16. data/lib/appsignal/cli/diagnose/utils.rb +8 -11
  17. data/lib/appsignal/cli/install.rb +5 -8
  18. data/lib/appsignal/config.rb +0 -24
  19. data/lib/appsignal/event_formatter.rb +0 -25
  20. data/lib/appsignal/helpers/instrumentation.rb +32 -0
  21. data/lib/appsignal/hooks.rb +0 -23
  22. data/lib/appsignal/hooks/action_cable.rb +3 -34
  23. data/lib/appsignal/hooks/active_support_notifications.rb +7 -86
  24. data/lib/appsignal/hooks/celluloid.rb +5 -9
  25. data/lib/appsignal/hooks/net_http.rb +2 -12
  26. data/lib/appsignal/hooks/puma.rb +3 -5
  27. data/lib/appsignal/hooks/que.rb +1 -1
  28. data/lib/appsignal/hooks/rake.rb +2 -24
  29. data/lib/appsignal/hooks/redis.rb +2 -13
  30. data/lib/appsignal/hooks/resque.rb +2 -43
  31. data/lib/appsignal/hooks/shoryuken.rb +43 -4
  32. data/lib/appsignal/hooks/unicorn.rb +3 -24
  33. data/lib/appsignal/hooks/webmachine.rb +1 -7
  34. data/lib/appsignal/integrations/action_cable.rb +34 -0
  35. data/lib/appsignal/integrations/active_support_notifications.rb +77 -0
  36. data/lib/appsignal/integrations/net_http.rb +16 -0
  37. data/lib/appsignal/integrations/object.rb +44 -17
  38. data/lib/appsignal/integrations/padrino.rb +5 -7
  39. data/lib/appsignal/integrations/que.rb +26 -33
  40. data/lib/appsignal/integrations/railtie.rb +1 -4
  41. data/lib/appsignal/integrations/rake.rb +26 -2
  42. data/lib/appsignal/integrations/redis.rb +17 -0
  43. data/lib/appsignal/integrations/resque.rb +39 -10
  44. data/lib/appsignal/integrations/unicorn.rb +28 -0
  45. data/lib/appsignal/integrations/webmachine.rb +22 -24
  46. data/lib/appsignal/minutely.rb +0 -12
  47. data/lib/appsignal/system.rb +4 -0
  48. data/lib/appsignal/transaction.rb +30 -2
  49. data/lib/appsignal/version.rb +1 -1
  50. data/spec/lib/appsignal/auth_check_spec.rb +1 -24
  51. data/spec/lib/appsignal/cli_spec.rb +1 -1
  52. data/spec/lib/appsignal/config_spec.rb +0 -66
  53. data/spec/lib/appsignal/event_formatter_spec.rb +0 -37
  54. data/spec/lib/appsignal/hooks/celluloid_spec.rb +6 -1
  55. data/spec/lib/appsignal/hooks/rake_spec.rb +1 -2
  56. data/spec/lib/appsignal/hooks/redis_spec.rb +50 -15
  57. data/spec/lib/appsignal/hooks/resque_spec.rb +10 -2
  58. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +151 -104
  59. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +4 -2
  60. data/spec/lib/appsignal/hooks/unicorn_spec.rb +14 -3
  61. data/spec/lib/appsignal/hooks/webmachine_spec.rb +2 -13
  62. data/spec/lib/appsignal/hooks_spec.rb +0 -57
  63. data/spec/lib/appsignal/integrations/object_spec.rb +25 -10
  64. data/spec/lib/appsignal/integrations/padrino_spec.rb +2 -3
  65. data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -45
  66. data/spec/lib/appsignal/integrations/webmachine_spec.rb +26 -8
  67. data/spec/lib/appsignal/minutely_spec.rb +0 -19
  68. data/spec/lib/appsignal/transaction_spec.rb +56 -14
  69. data/spec/lib/appsignal/transmitter_spec.rb +1 -1
  70. data/spec/lib/appsignal_spec.rb +30 -69
  71. data/spec/spec_helper.rb +1 -15
  72. metadata +13 -22
  73. data/lib/appsignal/cli/notify_of_deploy.rb +0 -131
  74. data/lib/appsignal/integrations/resque_active_job.rb +0 -19
  75. data/lib/appsignal/js_exception_transaction.rb +0 -56
  76. data/lib/appsignal/rack/js_exception_catcher.rb +0 -80
  77. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +0 -180
  78. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +0 -28
  79. data/spec/lib/appsignal/integrations/resque_spec.rb +0 -28
  80. data/spec/lib/appsignal/js_exception_transaction_spec.rb +0 -128
  81. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +0 -170
@@ -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
@@ -5,27 +5,54 @@ if defined?(Appsignal)
5
5
  end
6
6
 
7
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
8
+ if Appsignal::System.ruby_2_7_or_newer?
9
+ def self.appsignal_instrument_class_method(method_name, options = {})
10
+ singleton_class.send \
11
+ :alias_method, "appsignal_uninstrumented_#{method_name}", method_name
12
+ singleton_class.send(:define_method, method_name) do |*args, **kwargs, &block|
13
+ name = options.fetch(:name) do
14
+ "#{method_name}.class_method.#{appsignal_reverse_class_name}.other"
15
+ end
16
+ Appsignal.instrument name do
17
+ send "appsignal_uninstrumented_#{method_name}", *args, **kwargs, &block
18
+ end
17
19
  end
18
20
  end
19
- end
20
21
 
21
- def self.appsignal_instrument_method(method_name, options = {})
22
- alias_method "appsignal_uninstrumented_#{method_name}", method_name
23
- define_method method_name do |*args, &block|
24
- name = options.fetch(:name) do
25
- "#{method_name}.#{appsignal_reverse_class_name}.other"
22
+ def self.appsignal_instrument_method(method_name, options = {})
23
+ alias_method "appsignal_uninstrumented_#{method_name}", method_name
24
+ define_method method_name do |*args, **kwargs, &block|
25
+ name = options.fetch(:name) do
26
+ "#{method_name}.#{appsignal_reverse_class_name}.other"
27
+ end
28
+ Appsignal.instrument name do
29
+ send "appsignal_uninstrumented_#{method_name}", *args, **kwargs, &block
30
+ end
31
+ end
32
+ end
33
+ else
34
+ def self.appsignal_instrument_class_method(method_name, options = {})
35
+ singleton_class.send \
36
+ :alias_method, "appsignal_uninstrumented_#{method_name}", method_name
37
+ singleton_class.send(:define_method, method_name) do |*args, &block|
38
+ name = options.fetch(:name) do
39
+ "#{method_name}.class_method.#{appsignal_reverse_class_name}.other"
40
+ end
41
+ Appsignal.instrument name do
42
+ send "appsignal_uninstrumented_#{method_name}", *args, &block
43
+ end
26
44
  end
27
- Appsignal.instrument name do
28
- send "appsignal_uninstrumented_#{method_name}", *args, &block
45
+ end
46
+
47
+ def self.appsignal_instrument_method(method_name, options = {})
48
+ alias_method "appsignal_uninstrumented_#{method_name}", method_name
49
+ define_method method_name do |*args, &block|
50
+ name = options.fetch(:name) do
51
+ "#{method_name}.#{appsignal_reverse_class_name}.other"
52
+ end
53
+ Appsignal.instrument name do
54
+ send "appsignal_uninstrumented_#{method_name}", *args, &block
55
+ end
29
56
  end
30
57
  end
31
58
  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
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appsignal
4
+ module Integrations
5
+ module UnicornIntegration
6
+ # Make sure that appsignal is started and the last transaction
7
+ # in a worker gets flushed.
8
+ #
9
+ # We'd love to be able to hook this into Unicorn in a less
10
+ # intrusive way, but this is the best we can do given the
11
+ # options we have.
12
+
13
+ module Server
14
+ def worker_loop(worker)
15
+ Appsignal.forked
16
+ super
17
+ end
18
+ end
19
+
20
+ module Worker
21
+ def close
22
+ Appsignal.stop("unicorn")
23
+ super
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -3,35 +3,33 @@
3
3
  module Appsignal
4
4
  module Integrations
5
5
  # @api private
6
- module WebmachinePlugin
7
- module FSM
8
- def run_with_appsignal
9
- transaction = Appsignal::Transaction.create(
10
- SecureRandom.uuid,
11
- Appsignal::Transaction::HTTP_REQUEST,
12
- request,
13
- :params_method => :query
14
- )
6
+ module WebmachineIntegration
7
+ def run
8
+ transaction = Appsignal::Transaction.create(
9
+ SecureRandom.uuid,
10
+ Appsignal::Transaction::HTTP_REQUEST,
11
+ request,
12
+ :params_method => :query
13
+ )
15
14
 
16
- transaction.set_action_if_nil("#{resource.class.name}##{request.method}")
15
+ transaction.set_action_if_nil("#{resource.class.name}##{request.method}")
17
16
 
18
- Appsignal.instrument("process_action.webmachine") do
19
- run_without_appsignal
20
- end
21
-
22
- Appsignal::Transaction.complete_current!
17
+ Appsignal.instrument("process_action.webmachine") do
18
+ super
23
19
  end
24
20
 
25
- private
21
+ Appsignal::Transaction.complete_current!
22
+ end
23
+
24
+ private
26
25
 
27
- def handle_exceptions_with_appsignal
28
- handle_exceptions_without_appsignal do
29
- begin
30
- yield
31
- rescue Exception => e # rubocop:disable Lint/RescueException
32
- Appsignal.set_error(e)
33
- raise e
34
- end
26
+ def handle_exceptions
27
+ super do
28
+ begin
29
+ yield
30
+ rescue Exception => e # rubocop:disable Lint/RescueException
31
+ Appsignal.set_error(e)
32
+ raise e
35
33
  end
36
34
  end
37
35
  end