From afde6fdd5ef3e6b0693a7e330777e85ef4cffddb Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 19 Oct 2011 12:59:33 -0500 Subject: Added X-Request-Id tracking and TaggedLogging to easily log that and other production concerns --- .../lib/action_dispatch/middleware/request_id.rb | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 actionpack/lib/action_dispatch/middleware/request_id.rb (limited to 'actionpack/lib/action_dispatch/middleware') diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb new file mode 100644 index 0000000000..968ad6c28d --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/request_id.rb @@ -0,0 +1,38 @@ +require 'digest/md5' + +module ActionDispatch + # Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through + # ActionDispatch::Request#uuid) and sends the same id to the client via the X-Request-Id header. + # + # The unique request id is either based off the X-Request-Id header in the request, which would typically be generated + # by a firewall, load balancer, or the web server, or, if this header is not available, a random uuid. If the + # header is accepted from the outside world, we sanitize it to a max of 255 chars and alphanumeric and dashes only. + # + # The unique request id can be used to trace a request end-to-end and would typically end up being part of log files + # from multiple pieces of the stack. + class RequestId + def initialize(app) + @app = app + end + + def call(env) + env["action_dispatch.request_id"] = external_request_id(env) || internal_request_id + + status, headers, body = @app.call(env) + + headers["X-Request-Id"] = env["action_dispatch.request_id"] + [ status, headers, body ] + end + + private + def external_request_id(env) + if env["HTTP_X_REQUEST_ID"].present? + env["HTTP_X_REQUEST_ID"].gsub(/[^\w\d\-]/, "").first(255) + end + end + + def internal_request_id + SecureRandom.uuid + end + end +end -- cgit v1.2.3