Django日志记录为每个请求全局设置上下文?

2024-10-02 00:21:09 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我想记录如下格式化字符串:

%(levelname)s %(asctime)s %(module)s %(funcName)s %(message)s %(user_id)

可以使用这种类型的日志记录命令来完成:

logging.error('Error fetching information', extra = { 'user_id': 22 } )

这将向当前请求的日志消息中添加当前用户标识。在

但是额外的dict需要添加到每个日志记录调用中。在

在django中的一个公共函数(例如中间件,或者视图的索引函数)中,有没有一个好的方法来添加这个上下文,这样就设置了带有用户id的额外字典,并且当前请求中所有进一步的日志记录调用也会记录当前用户。在


Tags: 函数字符串用户命令id类型messagelogging
3条回答

这里有一种没有线程局部变量或中间件的可能方法:在views.py中,有一个dict映射线程到请求,并有一个锁来序列化对它的访问:

from threading import RLock
shared_data_lock = RLock()
request_map = {}

def set_request(request):
    with shared_data_lock:
        request_map[threading.current_thread()] = request

创建以下筛选器并附加到需要输出请求特定信息的处理程序:

^{pr2}$

然后,作为每个视图的第一个语句,在映射中设置请求:

def my_view(request, ...):
    set_request(request)
    # do your other view stuff here

使用此设置,您应该会发现日志输出包含相关的请求特定信息。在

https://github.com/jedie/django-tools/blob/master/django_tools/middlewares/ThreadLocal.py上存在一个ThreadLocal中间件,它可以帮助您解决当前请求在任何地方都可用的问题。在

因此,您需要做的是将中间件添加到您的中间件类设置中,并在某个地方创建一个函数,如下所示:

 from django_tools.middlewares import ThreadLocal
 def log_something(levelname, module, funcname, message):
     user = ThreadLocal.get_current_user()
     # do your logging here. "user" is the user object and the user id is in user.pk

我想你在找一个custom log formatter。结合mawimawi给出的包含threadlocal信息的答案,format方法可以自动获取这些信息并将其添加到每个记录的消息中。在

有两件事需要考虑:首先,如果以使用线程池的方式进行部署,那么threadlocal变量可能是危险的,更糟糕的是,泄漏信息。其次,在编写格式化程序时需要谨慎,以防在没有threadlocal信息的上下文中调用它。在

相关问题 更多 >

    热门问题