首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >django日志为每个请求全局设置上下文?

django日志为每个请求全局设置上下文?
EN

Stack Overflow用户
提问于 2013-04-25 16:38:39
回答 3查看 2.3K关注 0票数 23

假设我想像这样记录格式化字符串:

代码语言:javascript
复制
%(levelname)s %(asctime)s %(module)s %(funcName)s %(message)s %(user_id)

可以使用以下类型的日志记录命令完成此操作:

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

这会将当前的userid添加到当前请求的日志消息中。

但是额外的字典需要添加到每个日志调用中。

有没有好的方法在django的公共函数(如Middleware,或视图的索引函数)中添加此上下文,以便设置带有用户id的额外字典,并且当前请求中的所有后续日志调用也记录当前用户。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-25 17:01:07

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

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

代码语言:javascript
复制
 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
票数 8
EN

Stack Overflow用户

发布于 2013-05-22 08:05:50

这里有一种不需要线程本地变量或中间件的可行方法:在views.py中,假设有一个将线程映射到请求的字典,以及一个用于序列化对它的访问的锁:

代码语言:javascript
复制
from threading import RLock
shared_data_lock = RLock()
request_map = {}

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

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

代码语言:javascript
复制
import logging
class RequestFilter(logging.Filter):
    def filter(self, record):
        with shared_data_lock:
            request = request_map.get(threading.current_thread())
        if request:
            # Set data from the request into the record, e.g.
            record.user_id = request.user.id
        return True

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

代码语言:javascript
复制
def my_view(request, ...):
    set_request(request)
    # do your other view stuff here

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

票数 2
EN

Stack Overflow用户

发布于 2013-05-27 09:15:36

我想你要找的是一个custom log formatter。与mawimawi的答案结合使用以包含线程本地信息,您的format方法可以自动获取该信息并将其添加到每个记录的消息中。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16210101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档