我正在寻找一种在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
带有值)传递给每个异步函数调用下游,这样代码的每个部分都可以使用正确的上下文进行监视和记录。
我正在寻找更清洁/更简单的解决方案。
由于
亚历
答案 0 :(得分:0)
请求上下文的概念在异步框架中并不是很好(特别是如果你有大量流量),因为可能有数百个并发请求的简单事实很难确定哪个&# 34;上下文"使用。这适用于Flask,Falcon,Django等顺序框架,因为请求是逐个处理的,并且很容易确定您正在处理哪个请求。
在请求开始和结束之间处理功能的首选方法是分别覆盖prepare
和on_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