Python 在Tornado中使用请求级上下文

Python 在Tornado中使用请求级上下文,python,tornado,Python,Tornado,我正在寻找一种在Tornado中设置请求级别上下文的方法。 这对于日志记录非常有用,可以在每个日志行中打印一些请求属性(如user\u id)。 我想在web.RequestHandler中填充上下文,然后在该请求调用的其他协同程序中访问它 class WebRequestHandler(web.RequestHandler): @gen.coroutine def post(self): RequestContext.test_mode = self.appli

我正在寻找一种在Tornado中设置请求级别上下文的方法。 这对于日志记录非常有用,可以在每个日志行中打印一些请求属性(如
user\u id
)。 我想在
web.RequestHandler
中填充上下文,然后在该请求调用的其他协同程序中访问它

class WebRequestHandler(web.RequestHandler):
    @gen.coroutine
    def post(self):
        RequestContext.test_mode = self.application.settings.get('test_mode', False)
        RequestContext.corr_id = self.request.header.get('X-Request-ID')

        result = yield some_func()

        self.write(result)


@gen.coroutine
def some_func()
    if RequestContext.test_mode:
        print "In test mode"

    do more async calls 
目前,我将
context
对象(
dict
带值)传递给下游的每个异步函数调用,这样代码的每个部分都可以使用正确的上下文进行监视和记录。 我正在寻找一个更干净/更简单的解决方案

谢谢


Alex

请求上下文的概念在异步框架中并不适用(特别是在流量很大的情况下),因为可能存在数百个并发请求,因此很难确定使用哪个“上下文”。这适用于Flask、Falcon、Django等顺序框架,因为请求是一个接一个地处理的,很容易确定要处理的请求

处理请求开始和结束之间的功能的首选方法是分别覆盖和

class WebRequestHandler(web.RequestHandler):

    def prepare(self):
        print('Logging...prepare')
        if self.application.settings.get('test_mode', False):
            print("In test mode")
        print('X-Request-ID: {0}'.format(self.request.header.get('X-Request-ID')))

    @gen.coroutine
    def post(self):
        result = yield some_func()
        self.write(result)

    def on_finish(self):
        print('Logging...on_finish')
简单的解决方案是创建一个表示请求上下文的对象,并将其传递到日志函数中。例如:

class RequestContext(object):
    """
    Hold request context
    """

class WebRequestHandler(web.RequestHandler):

    @gen.coroutine
    def post(self):
        # create new context obj and fill w/ necessary parameters
        request_context = RequestContext()
        request_context.test_mode = self.application.settings.get('test_mode', False)
        request_context.corr_id = self.request.header.get('X-Request-ID')

        # pass context objects into coroutine
        result = yield some_func(request_context)

        self.write(result)


@gen.coroutine
def some_func(request_context)
    if request_context.test_mode:
        print "In test mode"

    # do more async calls

目前,我正在通过将上下文对象(
dict
带值)推送到所有异步函数调用来实现
RequestContext
概念。它工作正常,即使在高流量。Tornado确实能够管理
StackContext
以便能够从
yield
恢复,我希望能够有一种方法来创建某种
GlobalStackContext
,该方法对请求中的所有
yield
调用可见。