请求ID日志记录

为了在出现问题时帮助调试,可以找到特定请求的相关日志。一种方法是为每个请求生成一个唯一的请求ID,并将其添加到每个日志消息中。

如果希望在整个应用程序中跟踪请求,例如在请求上下文之外的数据操作中。您可以使用 thread-local 存储请求ID的上下文对象:

# context.py

import threading

class _Context:
    def __init__(self):
        self._thread_local = threading.local()

    @property
    def request_id(self):
        return getattr(self._thread_local, 'request_id', None)

    @request_id.setter
    def request_id(self, value):
        self._thread_local.request_id = value

ctx = _Context()

现在您可以创建一个 middleware 类,您可以创建一个唯一的ID并在线程本地设置它:

# middleware.py

from uuid import uuid4
from context import ctx

class RequestIDMiddleware:
    def process_request(self, req, resp):
        ctx.request_id = str(uuid4())

或者,如果您的所有应用程序逻辑都可以访问 request 你可以使用 context 对象以存储ID。

# middleware.py

from uuid import uuid4

# Optional logging package (pip install structlog)
import structlog

class RequestIDMiddleware:
    def process_request(self, req, resp):
        request_id = str(uuid4())
        # Using Falcon 2.0 syntax
        req.context.request_id = request_id

        # Or if your logger has built-in support for contexts
        req.context.log = structlog.get_logger(request_id=request_id)

使用登录 thread-local 上下文可以这样做:

# some_other_module.py

import logging

from context import ctx

def create_widget_object(name: str) -> Any:
    request_id = 'request_id={0}'.format(ctx.request_id)
    logging.debug('%s going to create widget: %s', request_id, name)
    try:
        # create the widget
    except:
        logging.exception('%s something went wrong', request_id)
    logging.debug('%s created widget: %s', request_id, name)