Class: RightSupport::Rack::RequestTracker
- Defined in:
- lib/right_support/rack/request_tracker.rb
Overview
middleware to detect a request ID header or generate a new ID for each incoming request. the purpose is to track a request lineage throughout a chain of internal API calls and, in some cases, out to external APIs that also support the X-Request-ID header as a de-facto standard (google it).
Constant Summary collapse
- Generator =
shorthand
::RightSupport::Data::Token
- REQUEST_ID_HEADER =
used by many public services to represent a client-generated request ID that can be tracked and safely logged throughout the lineage of a request. this is also supported by goa middleware.
'X-Request-Id'.freeze
- HTTP_REQUEST_ID_HEADER =
incoming header as found in Rack env hash, if any.
'HTTP_X_REQUEST_ID'.freeze
- REQUEST_UUID_HEADER =
LEGACY: still supported but new code should use the standard (see above).
"X-Request-Uuid".freeze
- HTTP_REQUEST_UUID_HEADER =
LEGACY: incoming header as found in Rack env hash, if any.
'HTTP_X_REQUEST_UUID'.freeze
- REQUEST_UUID_ENV_NAME =
LEGACY: refers to the generated or passed-in request ID. the key has been hardcoded in some places so is not easy to change and/or there is not much value to finding and replacing with _id in all cases.
'rack.request_uuid'.freeze
- REQUEST_LINEAGE_UUID_HEADER =
Deprecated.
do not send the lineage header as support may go away.
'HTTP_X_REQUEST_LINEAGE_UUID'.freeze
- UUID_SEPARATOR =
Deprecated.
do not send the lineage header as support may go away.
' '.freeze
- MAX_REQUEST_UUID_LENGTH =
limit request [UU]ID to something reasonable to keep our logs from overflowing on bad user-provided IDs. we do not want to be too restrictive in case people are encoding some useful information, etc. the issue is that the request ID will tend to show up a lot in logs.
128
Class Method Summary collapse
-
.copy_request_uuid(from_env, to_headers) ⇒ Hash
copies the request [UU]ID from the request environment to the given hash, if present.
-
.detect_request_uuid(env) ⇒ Array
detects whether the incoming env hash contains a request ID is some form and generates a new ID when missing.
-
.generate_request_uuid ⇒ String
generates a token (nicer than an actual UUID for logging) but we continue to refer to it as the “request UUID” for legacy reasons.
Instance Method Summary collapse
-
#call(env) ⇒ Array
request tracking.
-
#initialize(app) ⇒ RequestTracker
constructor
A new instance of RequestTracker.
Constructor Details
#initialize(app) ⇒ RequestTracker
Returns a new instance of RequestTracker.
65 66 67 |
# File 'lib/right_support/rack/request_tracker.rb', line 65 def initialize(app) @app = app end |
Class Method Details
.copy_request_uuid(from_env, to_headers) ⇒ Hash
copies the request [UU]ID from the request environment to the given hash, if present. does nothing if request [UU]ID is not set (because middleware was not present, etc.)
128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/right_support/rack/request_tracker.rb', line 128 def self.copy_request_uuid(from_env, to_headers) to_headers ||= {} if from_env if request_uuid = from_env[REQUEST_UUID_ENV_NAME] # note we always forward the _ID header as the standard. none of the # RS code ever actually accepted the _UUID header so that is a # non-issue. to_headers[REQUEST_ID_HEADER] = request_uuid end end to_headers end |
.detect_request_uuid(env) ⇒ Array
detects whether the incoming env hash contains a request ID is some form and generates a new ID when missing.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/right_support/rack/request_tracker.rb', line 89 def self.detect_request_uuid(env) request_uuid = '' response_header_name = nil { HTTP_REQUEST_ID_HEADER => REQUEST_ID_HEADER, HTTP_REQUEST_UUID_HEADER => REQUEST_UUID_HEADER, REQUEST_LINEAGE_UUID_HEADER => REQUEST_UUID_HEADER }.each do |in_key, out_key| if env.has_key?(in_key) request_uuid = env[in_key].to_s.strip response_header_name = out_key break end end # for legacy reasons we default to the -UUID header in response for newly- # generated IDs. we will use the -ID standard if that was passed-in. once # all apps are updated you will mostly see -ID in response except for API # calls initiated by browser code. the javascript can gradually be changed # to send -ID with requests as well. if request_uuid.empty? request_uuid = generate_request_uuid response_header_name = REQUEST_UUID_HEADER else # truncate, if necessary. request_uuid = request_uuid[0, MAX_REQUEST_UUID_LENGTH] end return request_uuid, response_header_name end |
.generate_request_uuid ⇒ String
generates a token (nicer than an actual UUID for logging) but we continue to refer to it as the “request UUID” for legacy reasons.
145 146 147 |
# File 'lib/right_support/rack/request_tracker.rb', line 145 def self.generate_request_uuid Generator.generate end |
Instance Method Details
#call(env) ⇒ Array
request tracking.
74 75 76 77 78 79 80 81 82 |
# File 'lib/right_support/rack/request_tracker.rb', line 74 def call(env) request_uuid, response_header_name = self.class.detect_request_uuid(env) env[REQUEST_UUID_ENV_NAME] = request_uuid status, headers, body = @app.call(env) headers[response_header_name] = request_uuid [status, headers, body] end |