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,15 +2,32 @@
2
2
 
3
3
  module Appsignal
4
4
  module Rack
5
- APPSIGNAL_TRANSACTION = "appsignal.transaction"
6
- APPSIGNAL_EVENT_HANDLER_ID = "appsignal.event_handler_id"
7
- APPSIGNAL_EVENT_HANDLER_HAS_ERROR = "appsignal.event_handler.error"
8
- RACK_AFTER_REPLY = "rack.after_reply"
9
-
10
- # @api private
5
+ # Instrumentation middleware using Rack's Events module.
6
+ #
7
+ # We recommend using this in combination with the
8
+ # {InstrumentationMiddleware}.
9
+ #
10
+ # This middleware will report the response status code as the
11
+ # `response_status` tag on the sample. It will also report the response
12
+ # status as the `response_status` metric.
13
+ #
14
+ # This middleware will ensure the AppSignal transaction is always completed
15
+ # for every request.
16
+ #
17
+ # @example Add EventHandler to a Rack app
18
+ # # Add this middleware as the first middleware of an app
19
+ # use ::Rack::Events, [Appsignal::Rack::EventHandler.new]
20
+ #
21
+ # # Then add the InstrumentationMiddleware
22
+ # use Appsignal::Rack::InstrumentationMiddleware
23
+ #
24
+ # @see https://docs.appsignal.com/ruby/integrations/rack.html
25
+ # Rack integration documentation.
26
+ # @api public
11
27
  class EventHandler
12
28
  include ::Rack::Events::Abstract
13
29
 
30
+ # @api private
14
31
  def self.safe_execution(name)
15
32
  yield
16
33
  rescue => e
@@ -19,27 +36,29 @@ module Appsignal
19
36
  )
20
37
  end
21
38
 
39
+ # @api private
22
40
  attr_reader :id
23
41
 
42
+ # @api private
24
43
  def initialize
25
44
  @id = SecureRandom.uuid
26
45
  end
27
46
 
47
+ # @api private
28
48
  def request_handler?(given_id)
29
49
  id == given_id
30
50
  end
31
51
 
52
+ # @api private
32
53
  def on_start(request, _response)
54
+ return unless Appsignal.active?
55
+
33
56
  event_handler = self
34
57
  self.class.safe_execution("Appsignal::Rack::EventHandler#on_start") do
35
58
  request.env[APPSIGNAL_EVENT_HANDLER_ID] ||= id
36
59
  return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
37
60
 
38
- transaction = Appsignal::Transaction.create(
39
- SecureRandom.uuid,
40
- Appsignal::Transaction::HTTP_REQUEST,
41
- request
42
- )
61
+ transaction = Appsignal::Transaction.create(Appsignal::Transaction::HTTP_REQUEST)
43
62
  request.env[APPSIGNAL_TRANSACTION] = transaction
44
63
 
45
64
  request.env[RACK_AFTER_REPLY] ||= []
@@ -49,7 +68,8 @@ module Appsignal
49
68
  Appsignal::Rack::EventHandler
50
69
  .safe_execution("Appsignal::Rack::EventHandler's after_reply") do
51
70
  transaction.finish_event("process_request.rack", "", "")
52
- transaction.set_http_or_background_queue_start
71
+ queue_start = Appsignal::Rack::Utils.queue_start_from(request.env)
72
+ transaction.set_queue_start(queue_start) if queue_start
53
73
  end
54
74
 
55
75
  # Make sure the current transaction is always closed when the request
@@ -65,7 +85,10 @@ module Appsignal
65
85
  end
66
86
  end
67
87
 
88
+ # @api private
68
89
  def on_error(request, _response, error)
90
+ return unless Appsignal.active?
91
+
69
92
  self.class.safe_execution("Appsignal::Rack::EventHandler#on_error") do
70
93
  return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
71
94
 
@@ -77,7 +100,9 @@ module Appsignal
77
100
  end
78
101
  end
79
102
 
103
+ # @api private
80
104
  def on_finish(request, response)
105
+ return unless Appsignal.active?
81
106
  return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
82
107
 
83
108
  transaction = request.env[APPSIGNAL_TRANSACTION]
@@ -85,7 +110,13 @@ module Appsignal
85
110
 
86
111
  self.class.safe_execution("Appsignal::Rack::EventHandler#on_finish") do
87
112
  transaction.finish_event("process_request.rack", "", "")
88
- transaction.set_http_or_background_queue_start
113
+ transaction.set_params_if_nil { request.params }
114
+ transaction.set_headers_if_nil { request.env }
115
+ transaction.set_session_data_if_nil do
116
+ request.session if request.respond_to?(:session)
117
+ end
118
+ queue_start = Appsignal::Rack::Utils.queue_start_from(request.env)
119
+ transaction.set_queue_start(queue_start) if queue_start
89
120
  response_status =
90
121
  if response
91
122
  response.status
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Rack
5
+ # @deprecated Use {InstrumentationMiddleware} instead.
5
6
  # @api private
6
7
  class GenericInstrumentation < AbstractMiddleware
7
8
  def initialize(app, options = {})
@@ -2,8 +2,9 @@
2
2
 
3
3
  module Appsignal
4
4
  module Rack
5
- # @api private
5
+ # @api public
6
6
  class GrapeMiddleware < Appsignal::Rack::AbstractMiddleware
7
+ # @api private
7
8
  def initialize(app, options = {})
8
9
  options[:instrument_event_name] = "process_request.grape"
9
10
  options[:report_errors] = lambda { |env| !env["grape.skip_appsignal_error"] }
@@ -10,6 +10,7 @@ module Appsignal
10
10
  # Instrumentation middleware that tracks exceptions in streaming Rack
11
11
  # responses.
12
12
  #
13
+ # @deprecated Use {InstrumentationMiddleware} instead.
13
14
  # @api private
14
15
  class StreamingListener < AbstractMiddleware
15
16
  def initialize(app, options = {})
@@ -3,6 +3,41 @@
3
3
  module Appsignal
4
4
  # @api private
5
5
  module Rack
6
+ APPSIGNAL_TRANSACTION = "appsignal.transaction"
7
+ APPSIGNAL_EVENT_HANDLER_ID = "appsignal.event_handler_id"
8
+ APPSIGNAL_EVENT_HANDLER_HAS_ERROR = "appsignal.event_handler.error"
9
+ APPSIGNAL_RESPONSE_INSTRUMENTED = "appsignal.response_instrumentation_active"
10
+ RACK_AFTER_REPLY = "rack.after_reply"
11
+
12
+ class Utils
13
+ # Fetch the queue start time from the request environment.
14
+ #
15
+ # @since 3.11.0
16
+ # @param env [Hash] Request environment hash.
17
+ # @return [Integer, NilClass]
18
+ def self.queue_start_from(env)
19
+ return unless env
20
+
21
+ env_var = env["HTTP_X_QUEUE_START"] || env["HTTP_X_REQUEST_START"]
22
+ return unless env_var
23
+
24
+ cleaned_value = env_var.tr("^0-9", "")
25
+ return if cleaned_value.empty?
26
+
27
+ value = cleaned_value.to_i
28
+ if value > 4_102_441_200_000
29
+ # Value is in microseconds. Transform to milliseconds.
30
+ value / 1_000
31
+ elsif value < 946_681_200_000
32
+ # Value is too low to be plausible
33
+ nil
34
+ else
35
+ # Value is in milliseconds
36
+ value
37
+ end
38
+ end
39
+ end
40
+
6
41
  # Alias constants that have moved with a warning message that points to the
7
42
  # place to update the reference.
8
43
  def self.const_missing(name)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
+ # @api private
4
5
  class Span
5
6
  def initialize(namespace = nil, ext = nil)
6
7
  @ext = ext || Appsignal::Extension::Span.root(namespace || "")