appsignal 3.9.3-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/.github/workflows/ci.yml +22 -19
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +180 -0
- data/Gemfile +1 -0
- data/README.md +0 -1
- data/Rakefile +1 -1
- data/benchmark.rake +99 -42
- data/build_matrix.yml +10 -12
- data/gemfiles/webmachine1.gemfile +5 -4
- data/lib/appsignal/cli/demo.rb +0 -1
- data/lib/appsignal/config.rb +57 -97
- data/lib/appsignal/demo.rb +15 -20
- data/lib/appsignal/environment.rb +6 -1
- 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 +490 -16
- data/lib/appsignal/hooks/action_cable.rb +21 -16
- data/lib/appsignal/hooks/active_job.rb +15 -14
- 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/padrino.rb +21 -25
- data/lib/appsignal/integrations/que.rb +13 -20
- data/lib/appsignal/integrations/railtie.rb +1 -1
- data/lib/appsignal/integrations/rake.rb +45 -15
- 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 -25
- data/lib/appsignal/integrations/unicorn.rb +1 -0
- data/lib/appsignal/integrations/webmachine.rb +12 -9
- 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 +67 -24
- data/lib/appsignal/rack/body_wrapper.rb +143 -0
- data/lib/appsignal/rack/event_handler.rb +39 -8
- data/lib/appsignal/rack/generic_instrumentation.rb +6 -4
- data/lib/appsignal/rack/grape_middleware.rb +3 -2
- data/lib/appsignal/rack/hanami_middleware.rb +1 -1
- data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +1 -3
- data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
- data/lib/appsignal/rack/streaming_listener.rb +14 -59
- data/lib/appsignal/rack.rb +60 -0
- data/lib/appsignal/span.rb +1 -0
- data/lib/appsignal/transaction.rb +353 -104
- 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 +9 -6
- data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
- data/spec/lib/appsignal/config_spec.rb +139 -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/rake_spec.rb +100 -17
- 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/padrino_spec.rb +181 -131
- 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/sinatra_spec.rb +10 -2
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +77 -17
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +144 -11
- data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
- data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -10
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -17
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +1 -1
- data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +4 -2
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +43 -120
- data/spec/lib/appsignal/rack_spec.rb +63 -0
- data/spec/lib/appsignal/transaction_spec.rb +1675 -953
- 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 +517 -13
- data/spec/support/helpers/transaction_helpers.rb +44 -20
- data/spec/support/matchers/transaction.rb +15 -1
- data/spec/support/mocks/dummy_app.rb +1 -1
- data/spec/support/testing.rb +1 -1
- metadata +12 -4
- data/support/check_versions +0 -22
|
@@ -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
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "rack"
|
|
4
|
-
|
|
5
3
|
module Appsignal
|
|
6
|
-
# @api private
|
|
7
4
|
module Rack
|
|
5
|
+
# @deprecated Use {InstrumentationMiddleware} instead.
|
|
6
|
+
# @api private
|
|
8
7
|
class GenericInstrumentation < AbstractMiddleware
|
|
9
8
|
def initialize(app, options = {})
|
|
10
|
-
options[:
|
|
9
|
+
options[:instrument_event_name] ||= "process_action.generic"
|
|
11
10
|
super
|
|
12
11
|
end
|
|
13
12
|
|
|
@@ -16,5 +15,8 @@ module Appsignal
|
|
|
16
15
|
transaction.set_action_if_nil("unknown")
|
|
17
16
|
end
|
|
18
17
|
end
|
|
18
|
+
|
|
19
|
+
# @api private
|
|
20
|
+
class GenericInstrumentationAlias < GenericInstrumentation; end
|
|
19
21
|
end
|
|
20
22
|
end
|
|
@@ -2,10 +2,11 @@
|
|
|
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
|
-
options[:
|
|
9
|
+
options[:instrument_event_name] = "process_request.grape"
|
|
9
10
|
options[:report_errors] = lambda { |env| !env["grape.skip_appsignal_error"] }
|
|
10
11
|
super
|
|
11
12
|
end
|
|
@@ -6,7 +6,7 @@ module Appsignal
|
|
|
6
6
|
class HanamiMiddleware < AbstractMiddleware
|
|
7
7
|
def initialize(app, options = {})
|
|
8
8
|
options[:params_method] ||= :params
|
|
9
|
-
options[:
|
|
9
|
+
options[:instrument_event_name] ||= "process_action.hanami"
|
|
10
10
|
super
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Appsignal
|
|
4
|
+
module Rack
|
|
5
|
+
# Rack instrumentation middleware.
|
|
6
|
+
#
|
|
7
|
+
# This Ruby gem automatically instruments several Rack based libraries,
|
|
8
|
+
# like Rails and Sinatra. This middleware does not need to be added
|
|
9
|
+
# manually to these frameworks.
|
|
10
|
+
#
|
|
11
|
+
# This instrumentation middleware will wrap an app and report how long the
|
|
12
|
+
# request and response took, report errors that occurred in the app, and
|
|
13
|
+
# report metadata about the request method and path.
|
|
14
|
+
#
|
|
15
|
+
# The action name for the endpoint is not set by default, which is required
|
|
16
|
+
# for performance monitoring. Set the action name in each endpoint using
|
|
17
|
+
# the {Appsignal::Helpers::Instrumentation#set_action} helper.
|
|
18
|
+
#
|
|
19
|
+
# If multiple of these middlewares, or
|
|
20
|
+
# {AbstractMiddleware} subclasses are present in an app, only the top
|
|
21
|
+
# middleware will report errors from apps and other middleware.
|
|
22
|
+
#
|
|
23
|
+
# This middleware is best used in combination with the {EventHandler}.
|
|
24
|
+
#
|
|
25
|
+
# @example
|
|
26
|
+
# # config.ru
|
|
27
|
+
# require "appsignal"
|
|
28
|
+
# # Configure and start AppSignal
|
|
29
|
+
#
|
|
30
|
+
# # Add the EventHandler first
|
|
31
|
+
# use ::Rack::Events, [Appsignal::Rack::EventHandler.new]
|
|
32
|
+
# # Add the instrumentation middleware second
|
|
33
|
+
# use Appsignal::Rack::InstrumentationMiddleware
|
|
34
|
+
#
|
|
35
|
+
# # Other middleware
|
|
36
|
+
#
|
|
37
|
+
# # Start app
|
|
38
|
+
#
|
|
39
|
+
# @example Customize instrumentation event category
|
|
40
|
+
# use Appsignal::Rack::InstrumentationMiddleware,
|
|
41
|
+
# :instrument_event_name => "custom.goup"
|
|
42
|
+
#
|
|
43
|
+
# @example Disable error reporting for this middleware
|
|
44
|
+
# use Appsignal::Rack::InstrumentationMiddleware, :report_errors => false
|
|
45
|
+
#
|
|
46
|
+
# @example Always report errors, even when wrapped by other instrumentation middleware
|
|
47
|
+
# use Appsignal::Rack::InstrumentationMiddleware, :report_errors => true
|
|
48
|
+
#
|
|
49
|
+
# @example Disable error reporting for this middleware based on the request env
|
|
50
|
+
# use Appsignal::Rack::InstrumentationMiddleware,
|
|
51
|
+
# :report_errors => lambda { |env| env["some_key"] == "some value" }
|
|
52
|
+
#
|
|
53
|
+
# @see https://docs.appsignal.com/ruby/integrations/rack.html
|
|
54
|
+
# @api public
|
|
55
|
+
class InstrumentationMiddleware < AbstractMiddleware
|
|
56
|
+
def initialize(app, options = {})
|
|
57
|
+
options[:instrument_event_name] ||= "process_request_middleware.rack"
|
|
58
|
+
super
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "rack"
|
|
4
|
-
|
|
5
3
|
module Appsignal
|
|
6
4
|
module Rack
|
|
7
5
|
# @api private
|
|
@@ -9,7 +7,7 @@ module Appsignal
|
|
|
9
7
|
def initialize(app, options = {})
|
|
10
8
|
options[:request_class] ||= ActionDispatch::Request
|
|
11
9
|
options[:params_method] ||= :filtered_parameters
|
|
12
|
-
options[:
|
|
10
|
+
options[:instrument_event_name] = nil
|
|
13
11
|
options[:report_errors] = true
|
|
14
12
|
super
|
|
15
13
|
end
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "rack"
|
|
4
|
-
|
|
5
3
|
module Appsignal
|
|
6
4
|
module Rack
|
|
7
5
|
# Stub old middleware. Prevents Sinatra middleware being loaded twice.
|
|
@@ -34,7 +32,7 @@ module Appsignal
|
|
|
34
32
|
def initialize(app, options = {})
|
|
35
33
|
options[:request_class] ||= Sinatra::Request
|
|
36
34
|
options[:params_method] ||= :params
|
|
37
|
-
options[:
|
|
35
|
+
options[:instrument_event_name] ||= "process_action.sinatra"
|
|
38
36
|
super
|
|
39
37
|
@raise_errors_on = raise_errors?(app)
|
|
40
38
|
end
|
|
@@ -1,73 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning \
|
|
4
|
+
"The constant Appsignal::Rack::StreamingListener has been deprecated. " \
|
|
5
|
+
"Please update the constant name to " \
|
|
6
|
+
"Appsignal::Rack::InstrumentationMiddleware."
|
|
7
|
+
|
|
3
8
|
module Appsignal
|
|
4
9
|
module Rack
|
|
5
|
-
#
|
|
10
|
+
# Instrumentation middleware that tracks exceptions in streaming Rack
|
|
11
|
+
# responses.
|
|
6
12
|
#
|
|
13
|
+
# @deprecated Use {InstrumentationMiddleware} instead.
|
|
7
14
|
# @api private
|
|
8
|
-
class StreamingListener
|
|
15
|
+
class StreamingListener < AbstractMiddleware
|
|
9
16
|
def initialize(app, options = {})
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@options = options
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def call(env)
|
|
16
|
-
if Appsignal.active?
|
|
17
|
-
call_with_appsignal_monitoring(env)
|
|
18
|
-
else
|
|
19
|
-
@app.call(env)
|
|
20
|
-
end
|
|
17
|
+
options[:instrument_event_name] ||= "process_streaming_request.rack"
|
|
18
|
+
super
|
|
21
19
|
end
|
|
22
20
|
|
|
23
|
-
def
|
|
24
|
-
request
|
|
25
|
-
transaction = Appsignal::Transaction.create(
|
|
26
|
-
SecureRandom.uuid,
|
|
27
|
-
Appsignal::Transaction::HTTP_REQUEST,
|
|
28
|
-
request
|
|
29
|
-
)
|
|
21
|
+
def add_transaction_metadata_after(transaction, request)
|
|
22
|
+
transaction.set_action_if_nil(request.env["appsignal.action"])
|
|
30
23
|
|
|
31
|
-
|
|
32
|
-
status, headers, body =
|
|
33
|
-
Appsignal.instrument("process_action.rack") do
|
|
34
|
-
@app.call(env)
|
|
35
|
-
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
36
|
-
transaction.set_error(e)
|
|
37
|
-
raise e
|
|
38
|
-
ensure
|
|
39
|
-
transaction.set_action_if_nil(env["appsignal.action"])
|
|
40
|
-
transaction.set_metadata("path", request.path)
|
|
41
|
-
transaction.set_metadata("method", request.request_method)
|
|
42
|
-
transaction.set_http_or_background_queue_start
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Wrap the result body with our StreamWrapper
|
|
46
|
-
[status, headers, StreamWrapper.new(body, transaction)]
|
|
24
|
+
super
|
|
47
25
|
end
|
|
48
26
|
end
|
|
49
27
|
end
|
|
50
|
-
|
|
51
|
-
class StreamWrapper
|
|
52
|
-
def initialize(stream, transaction)
|
|
53
|
-
@stream = stream
|
|
54
|
-
@transaction = transaction
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def each(&block)
|
|
58
|
-
@stream.each(&block)
|
|
59
|
-
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
60
|
-
@transaction.set_error(e)
|
|
61
|
-
raise e
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def close
|
|
65
|
-
@stream.close if @stream.respond_to?(:close)
|
|
66
|
-
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
67
|
-
@transaction.set_error(e)
|
|
68
|
-
raise e
|
|
69
|
-
ensure
|
|
70
|
-
Appsignal::Transaction.complete_current!
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
28
|
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Appsignal
|
|
4
|
+
# @api private
|
|
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
|
+
|
|
35
|
+
# Alias constants that have moved with a warning message that points to the
|
|
36
|
+
# place to update the reference.
|
|
37
|
+
def self.const_missing(name)
|
|
38
|
+
case name
|
|
39
|
+
when :GenericInstrumentation
|
|
40
|
+
require "appsignal/rack/generic_instrumentation"
|
|
41
|
+
|
|
42
|
+
callers = caller
|
|
43
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning \
|
|
44
|
+
"The constant Appsignal::Rack::GenericInstrumentation has been deprecated. " \
|
|
45
|
+
"Please use the new Appsignal::Rack::InstrumentationMiddleware middleware. " \
|
|
46
|
+
"This new middleware does not default the action name to 'unknown'. " \
|
|
47
|
+
"Set the action name for the endpoint using the Appsignal.set_action helper. " \
|
|
48
|
+
"Read our Rack docs for more information " \
|
|
49
|
+
"https://docs.appsignal.com/ruby/integrations/rack.html " \
|
|
50
|
+
"Update the constant name to " \
|
|
51
|
+
"Appsignal::Rack::InstrumentationMiddleware in the following file to " \
|
|
52
|
+
"remove this message.\n#{callers.first}"
|
|
53
|
+
# Return the alias so it can't ever get stuck in a recursive loop
|
|
54
|
+
Appsignal::Rack::GenericInstrumentationAlias
|
|
55
|
+
else
|
|
56
|
+
super
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|