appsignal 3.10.0-java → 3.11.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +88 -0
- data/Gemfile +1 -0
- data/benchmark.rake +99 -42
- data/lib/appsignal/cli/demo.rb +0 -1
- data/lib/appsignal/config.rb +54 -98
- data/lib/appsignal/demo.rb +15 -20
- data/lib/appsignal/event_formatter/rom/sql_formatter.rb +1 -0
- data/lib/appsignal/event_formatter.rb +3 -2
- data/lib/appsignal/helpers/instrumentation.rb +331 -19
- data/lib/appsignal/hooks/action_cable.rb +21 -16
- data/lib/appsignal/hooks/active_job.rb +14 -8
- data/lib/appsignal/hooks/delayed_job.rb +1 -1
- data/lib/appsignal/hooks/shoryuken.rb +3 -63
- data/lib/appsignal/integrations/action_cable.rb +5 -7
- data/lib/appsignal/integrations/active_support_notifications.rb +1 -0
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +36 -35
- data/lib/appsignal/integrations/data_mapper.rb +1 -0
- data/lib/appsignal/integrations/delayed_job_plugin.rb +27 -33
- data/lib/appsignal/integrations/dry_monitor.rb +1 -0
- data/lib/appsignal/integrations/excon.rb +1 -0
- data/lib/appsignal/integrations/http.rb +1 -0
- data/lib/appsignal/integrations/net_http.rb +1 -0
- data/lib/appsignal/integrations/object.rb +6 -0
- data/lib/appsignal/integrations/que.rb +13 -20
- data/lib/appsignal/integrations/railtie.rb +1 -1
- data/lib/appsignal/integrations/rake.rb +1 -5
- data/lib/appsignal/integrations/redis.rb +1 -0
- data/lib/appsignal/integrations/redis_client.rb +1 -0
- data/lib/appsignal/integrations/resque.rb +2 -5
- data/lib/appsignal/integrations/shoryuken.rb +75 -0
- data/lib/appsignal/integrations/sidekiq.rb +7 -15
- data/lib/appsignal/integrations/unicorn.rb +1 -0
- data/lib/appsignal/integrations/webmachine.rb +2 -5
- data/lib/appsignal/logger.rb +7 -3
- data/lib/appsignal/probes/helpers.rb +1 -0
- data/lib/appsignal/probes/mri.rb +1 -0
- data/lib/appsignal/probes/sidekiq.rb +1 -0
- data/lib/appsignal/probes.rb +3 -0
- data/lib/appsignal/rack/abstract_middleware.rb +18 -12
- data/lib/appsignal/rack/event_handler.rb +39 -8
- data/lib/appsignal/rack/generic_instrumentation.rb +1 -0
- data/lib/appsignal/rack/grape_middleware.rb +2 -1
- data/lib/appsignal/rack/streaming_listener.rb +1 -0
- data/lib/appsignal/rack.rb +29 -0
- data/lib/appsignal/span.rb +1 -0
- data/lib/appsignal/transaction.rb +308 -101
- data/lib/appsignal/utils/data.rb +0 -1
- data/lib/appsignal/utils/hash_sanitizer.rb +0 -1
- data/lib/appsignal/utils/integration_logger.rb +0 -13
- data/lib/appsignal/utils/integration_memory_logger.rb +0 -13
- data/lib/appsignal/utils/json.rb +0 -1
- data/lib/appsignal/utils/query_params_sanitizer.rb +0 -1
- data/lib/appsignal/utils/stdout_and_logger_message.rb +0 -1
- data/lib/appsignal/utils.rb +6 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +6 -5
- data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
- data/spec/lib/appsignal/config_spec.rb +138 -43
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +43 -74
- data/spec/lib/appsignal/hooks/activejob_spec.rb +9 -0
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +2 -443
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -171
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +459 -0
- data/spec/lib/appsignal/integrations/que_spec.rb +3 -4
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +167 -0
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +4 -4
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +13 -1
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +48 -3
- data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -10
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +4 -2
- data/spec/lib/appsignal/rack_spec.rb +63 -0
- data/spec/lib/appsignal/transaction_spec.rb +1634 -1071
- data/spec/lib/appsignal/utils/integration_logger_spec.rb +12 -16
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -10
- data/spec/lib/appsignal_spec.rb +323 -10
- data/spec/support/helpers/transaction_helpers.rb +44 -20
- data/spec/support/matchers/transaction.rb +15 -1
- data/spec/support/testing.rb +1 -1
- metadata +6 -2
|
@@ -9,6 +9,7 @@ module Appsignal
|
|
|
9
9
|
# Do not use this middleware directly. Instead use
|
|
10
10
|
# {InstrumentationMiddleware}.
|
|
11
11
|
#
|
|
12
|
+
# @abstract
|
|
12
13
|
# @api private
|
|
13
14
|
class AbstractMiddleware
|
|
14
15
|
DEFAULT_ERROR_REPORTING = :default
|
|
@@ -33,11 +34,7 @@ module Appsignal
|
|
|
33
34
|
if wrapped_instrumentation
|
|
34
35
|
env[Appsignal::Rack::APPSIGNAL_TRANSACTION]
|
|
35
36
|
else
|
|
36
|
-
Appsignal::Transaction.create(
|
|
37
|
-
SecureRandom.uuid,
|
|
38
|
-
Appsignal::Transaction::HTTP_REQUEST,
|
|
39
|
-
request
|
|
40
|
-
)
|
|
37
|
+
Appsignal::Transaction.create(Appsignal::Transaction::HTTP_REQUEST)
|
|
41
38
|
end
|
|
42
39
|
|
|
43
40
|
unless wrapped_instrumentation
|
|
@@ -80,7 +77,7 @@ module Appsignal
|
|
|
80
77
|
# Either another {AbstractMiddleware} or {EventHandler} is higher in the
|
|
81
78
|
# stack and will report the exception and complete the transaction.
|
|
82
79
|
#
|
|
83
|
-
# @see
|
|
80
|
+
# @see #instrument_app_call_with_exception_handling
|
|
84
81
|
def instrument_app_call(env, transaction)
|
|
85
82
|
if @instrument_event_name
|
|
86
83
|
Appsignal.instrument(@instrument_event_name) do
|
|
@@ -108,7 +105,7 @@ module Appsignal
|
|
|
108
105
|
# {#instrument_app_call} this will report any exceptions being
|
|
109
106
|
# raised.
|
|
110
107
|
#
|
|
111
|
-
# @see
|
|
108
|
+
# @see #instrument_app_call
|
|
112
109
|
def instrument_app_call_with_exception_handling(env, transaction, wrapped_instrumentation)
|
|
113
110
|
instrument_app_call(env, transaction)
|
|
114
111
|
rescue Exception => error # rubocop:disable Lint/RescueException
|
|
@@ -147,7 +144,14 @@ module Appsignal
|
|
|
147
144
|
transaction.set_metadata("method", request_method) if request_method
|
|
148
145
|
|
|
149
146
|
transaction.set_params_if_nil { params_for(request) }
|
|
150
|
-
transaction.
|
|
147
|
+
transaction.set_session_data_if_nil do
|
|
148
|
+
request.session if request.respond_to?(:session)
|
|
149
|
+
end
|
|
150
|
+
transaction.set_headers_if_nil do
|
|
151
|
+
request.env if request.respond_to?(:env)
|
|
152
|
+
end
|
|
153
|
+
queue_start = Appsignal::Rack::Utils.queue_start_from(request.env)
|
|
154
|
+
transaction.set_queue_start(queue_start) if queue_start
|
|
151
155
|
end
|
|
152
156
|
|
|
153
157
|
def params_for(request)
|
|
@@ -155,9 +159,9 @@ module Appsignal
|
|
|
155
159
|
|
|
156
160
|
request.send(@params_method)
|
|
157
161
|
rescue => error
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
162
|
+
Appsignal.internal_logger.error(
|
|
163
|
+
"Exception while fetching params from '#{@request_class}##{@params_method}': " \
|
|
164
|
+
"#{error.class} #{error}"
|
|
161
165
|
)
|
|
162
166
|
nil
|
|
163
167
|
end
|
|
@@ -165,7 +169,9 @@ module Appsignal
|
|
|
165
169
|
def request_method_for(request)
|
|
166
170
|
request.request_method
|
|
167
171
|
rescue => error
|
|
168
|
-
Appsignal.internal_logger.error(
|
|
172
|
+
Appsignal.internal_logger.error(
|
|
173
|
+
"Exception while fetching the HTTP request method: #{error.class}: #{error}"
|
|
174
|
+
)
|
|
169
175
|
nil
|
|
170
176
|
end
|
|
171
177
|
|
|
@@ -7,10 +7,32 @@ module Appsignal
|
|
|
7
7
|
APPSIGNAL_EVENT_HANDLER_HAS_ERROR = "appsignal.event_handler.error"
|
|
8
8
|
RACK_AFTER_REPLY = "rack.after_reply"
|
|
9
9
|
|
|
10
|
-
#
|
|
10
|
+
# Instrumentation middleware using Rack's Events module.
|
|
11
|
+
#
|
|
12
|
+
# We recommend using this in combination with the
|
|
13
|
+
# {InstrumentationMiddleware}.
|
|
14
|
+
#
|
|
15
|
+
# This middleware will report the response status code as the
|
|
16
|
+
# `response_status` tag on the sample. It will also report the response
|
|
17
|
+
# status as the `response_status` metric.
|
|
18
|
+
#
|
|
19
|
+
# This middleware will ensure the AppSignal transaction is always completed
|
|
20
|
+
# for every request.
|
|
21
|
+
#
|
|
22
|
+
# @example Add EventHandler to a Rack app
|
|
23
|
+
# # Add this middleware as the first middleware of an app
|
|
24
|
+
# use ::Rack::Events, [Appsignal::Rack::EventHandler.new]
|
|
25
|
+
#
|
|
26
|
+
# # Then add the InstrumentationMiddleware
|
|
27
|
+
# use Appsignal::Rack::InstrumentationMiddleware
|
|
28
|
+
#
|
|
29
|
+
# @see https://docs.appsignal.com/ruby/integrations/rack.html
|
|
30
|
+
# Rack integration documentation.
|
|
31
|
+
# @api public
|
|
11
32
|
class EventHandler
|
|
12
33
|
include ::Rack::Events::Abstract
|
|
13
34
|
|
|
35
|
+
# @api private
|
|
14
36
|
def self.safe_execution(name)
|
|
15
37
|
yield
|
|
16
38
|
rescue => e
|
|
@@ -19,27 +41,27 @@ module Appsignal
|
|
|
19
41
|
)
|
|
20
42
|
end
|
|
21
43
|
|
|
44
|
+
# @api private
|
|
22
45
|
attr_reader :id
|
|
23
46
|
|
|
47
|
+
# @api private
|
|
24
48
|
def initialize
|
|
25
49
|
@id = SecureRandom.uuid
|
|
26
50
|
end
|
|
27
51
|
|
|
52
|
+
# @api private
|
|
28
53
|
def request_handler?(given_id)
|
|
29
54
|
id == given_id
|
|
30
55
|
end
|
|
31
56
|
|
|
57
|
+
# @api private
|
|
32
58
|
def on_start(request, _response)
|
|
33
59
|
event_handler = self
|
|
34
60
|
self.class.safe_execution("Appsignal::Rack::EventHandler#on_start") do
|
|
35
61
|
request.env[APPSIGNAL_EVENT_HANDLER_ID] ||= id
|
|
36
62
|
return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
|
|
37
63
|
|
|
38
|
-
transaction = Appsignal::Transaction.create(
|
|
39
|
-
SecureRandom.uuid,
|
|
40
|
-
Appsignal::Transaction::HTTP_REQUEST,
|
|
41
|
-
request
|
|
42
|
-
)
|
|
64
|
+
transaction = Appsignal::Transaction.create(Appsignal::Transaction::HTTP_REQUEST)
|
|
43
65
|
request.env[APPSIGNAL_TRANSACTION] = transaction
|
|
44
66
|
|
|
45
67
|
request.env[RACK_AFTER_REPLY] ||= []
|
|
@@ -49,7 +71,8 @@ module Appsignal
|
|
|
49
71
|
Appsignal::Rack::EventHandler
|
|
50
72
|
.safe_execution("Appsignal::Rack::EventHandler's after_reply") do
|
|
51
73
|
transaction.finish_event("process_request.rack", "", "")
|
|
52
|
-
|
|
74
|
+
queue_start = Appsignal::Rack::Utils.queue_start_from(request.env)
|
|
75
|
+
transaction.set_queue_start(queue_start) if queue_start
|
|
53
76
|
end
|
|
54
77
|
|
|
55
78
|
# Make sure the current transaction is always closed when the request
|
|
@@ -65,6 +88,7 @@ module Appsignal
|
|
|
65
88
|
end
|
|
66
89
|
end
|
|
67
90
|
|
|
91
|
+
# @api private
|
|
68
92
|
def on_error(request, _response, error)
|
|
69
93
|
self.class.safe_execution("Appsignal::Rack::EventHandler#on_error") do
|
|
70
94
|
return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
|
|
@@ -77,6 +101,7 @@ module Appsignal
|
|
|
77
101
|
end
|
|
78
102
|
end
|
|
79
103
|
|
|
104
|
+
# @api private
|
|
80
105
|
def on_finish(request, response)
|
|
81
106
|
return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
|
|
82
107
|
|
|
@@ -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.
|
|
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,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module Appsignal
|
|
4
4
|
module Rack
|
|
5
|
-
# @api
|
|
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 = {})
|
data/lib/appsignal/rack.rb
CHANGED
|
@@ -3,6 +3,35 @@
|
|
|
3
3
|
module Appsignal
|
|
4
4
|
# @api private
|
|
5
5
|
module Rack
|
|
6
|
+
class Utils
|
|
7
|
+
# Fetch the queue start time from the request environment.
|
|
8
|
+
#
|
|
9
|
+
# @since 3.11.0
|
|
10
|
+
# @param env [Hash] Request environment hash.
|
|
11
|
+
# @return [Integer, NilClass]
|
|
12
|
+
def self.queue_start_from(env)
|
|
13
|
+
return unless env
|
|
14
|
+
|
|
15
|
+
env_var = env["HTTP_X_QUEUE_START"] || env["HTTP_X_REQUEST_START"]
|
|
16
|
+
return unless env_var
|
|
17
|
+
|
|
18
|
+
cleaned_value = env_var.tr("^0-9", "")
|
|
19
|
+
return if cleaned_value.empty?
|
|
20
|
+
|
|
21
|
+
value = cleaned_value.to_i
|
|
22
|
+
if value > 4_102_441_200_000
|
|
23
|
+
# Value is in microseconds. Transform to milliseconds.
|
|
24
|
+
value / 1_000
|
|
25
|
+
elsif value < 946_681_200_000
|
|
26
|
+
# Value is too low to be plausible
|
|
27
|
+
nil
|
|
28
|
+
else
|
|
29
|
+
# Value is in milliseconds
|
|
30
|
+
value
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
6
35
|
# Alias constants that have moved with a warning message that points to the
|
|
7
36
|
# place to update the reference.
|
|
8
37
|
def self.const_missing(name)
|