Skip to main content

Attach a unique identifier to every WSGI request.

Project description

request-id

https://img.shields.io/pypi/v/request-id.svg https://img.shields.io/travis/mmerickel/request-id/master.svg

Attach a unique identifier to every request in your WSGI application.

request-id is implemented as a WSGI middleware.

The package will do 3 things:

  1. Generate a unique request_id identifier which will be stored in the WSGI environ and set as the X-Request-ID response header.

  2. Rename the processing thread with the request_id such that any log messages output by the logger have the request_id attached.

  3. Log the request to the Python stdlib logging library, which can be used to generate a simple access log.

Installation

You may install the request-id package using pip:

$ pip install request-id

Configure with PasteDeploy

Update your application INI to run in a pipeline with the request-id filter:

[app:myapp]
use = egg:myapp

[filter:request-id]
use = egg:request-id
format = {status} {REQUEST_METHOD:<6} {REQUEST_PATH:<60} {REQUEST_ID}

[pipeline:main]
pipeline =
  request-id
  myapp

[loggers]
keys = translogger

[handlers]
keys = translogger

[formatters]
keys = minimal

[logger_translogger]
level = INFO
handlers = translogger
qualname = request_id
propagate = 0

[handler_translogger]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = minimal

[formatter_minimal]
format = %(message)s

Configure in code

Create a RequestIdMiddleware object and compose it with your WSGI application:

from request_id import RequestIdMiddleware
from wsgiref.simple_server import make_server

def app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    yield 'Hello World\n'

app = RequestIdMiddleware(
    app,
    format='{status} {REQUEST_METHOD:<6} {REQUEST_PATH:<60} {REQUEST_ID}',
)

if __name__ == '__main__':
    server = make_server('0.0.0.0', 8080, app)
    server.serve_forever()

Access the request_id

The request_id is stored in the request environ dictionary and may be accessed from anywhere this is available using request_id.get_request_id(request) where request is an instance of webob.request.Request.

Settings

logger_name

The name of the Python stdlib logger to which the log output will be delivered. Default: request_id

logging_level

The name of the Python stdlib logging level on which request information will be output. Default: INFO

format

A formatting string using PEP-3101 string format syntax. Possible options are:

  • REQUEST_ID

  • REMOTE_ADDR

  • REMOTE_USER

  • REQUEST_METHOD

  • REQUEST_URI

  • REQUEST_PATH

  • HTTP_HOST

  • HTTP_VERSION

  • HTTP_REFERER

  • HTTP_USER_AGENT

  • time

  • duration

  • bytes

  • status

Default: '{REMOTE_ADDR} {HTTP_HOST} {REMOTE_USER} [{time}] "{REQUEST_METHOD} {REQUEST_URI} {HTTP_VERSION}" {status} {bytes} {duration} "{HTTP_REFERER}" "{HTTP_USER_AGENT}" - {REQUEST_ID}

source_header

If not None then the request_id will be pulled from this header in the request. This is useful if another system upstream is setting a request identifier which you want to use in the WSGI application. Default: None

exclude_prefixes

A (space or line separated) list of URL paths to be ignored based on request.path_info. Paths should have a leading / in order to match properly. Default: None

Acknowledgements

This code is heavily based on the translogger middleware from Paste.

1.0.1 (2020-10-06)

  • Fix a bug in which exclude_prefixes was not matching in cases where the PATH_INFO in the WSGI environ was mutated while processing the request.

1.0 (2018-11-26)

  • Fix a bug in exclude_prefixes where it only matches the first request on Python 3.

0.3.1 (2017-11-26)

  • Fix changelog.

0.3 (2017-11-26)

  • Do not crash when the source header is missing. Instead set the request id to “-“.

  • Properly format the UTC offset in the {time} timestamp.

  • Add 100% test coverage.

0.2.1 (2016-11-03)

0.2 (2016-08-09)

  • Catch exceptions and return webob.exc.HTTPInternalServerError so that a request_id may be attached to the response.

0.1.2 (2016-07-26)

  • Fix a couple bugs with exclude_prefixes and add some docs for it.

0.1.1 (2016-07-26)

  • Add a new setting exclude_prefixes which can be used to avoid logging certain requests.

0.1.0 (2016-07-26)

  • Initial release.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page