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

时间:2017-06-15 11:20:17

标签: python tornado

我正在寻找一种在Tornado中设置请求级别上下文的方法。 这对于记录目的很有用,可以在每个日志行中打印一些请求属性(如user_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带有值)传递给每个异步函数调用下游,这样代码的每个部分都可以使用正确的上下文进行监视和记录。 我正在寻找更清洁/更简单的解决方案。

由于

亚历

1 个答案:

答案 0 :(得分:0)

请求上下文的概念在异步框架中并不是很好(特别是如果你有大量流量),因为可能有数百个并发请求的简单事实很难确定哪个&# 34;上下文"使用。这适用于Flask,Falcon,Django等顺序框架,因为请求是逐个处理的,并且很容易确定您正在处理哪个请求。

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

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