假设我想像这样记录格式化字符串:
%(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的额外字典,并且当前请求中的所有后续日志调用也记录当前用户。
发布于 2013-04-25 17:01:07
https://github.com/jedie/django-tools/blob/master/django_tools/middlewares/ThreadLocal.py上有一个ThreadLocal中间件,它可以帮助您解决当前请求随处可用的问题。
因此,您需要做的是将中间件添加到您的MIDDLEWARE_CLASSES设置中,并在某个地方创建一个函数,如下所示:
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
发布于 2013-05-22 08:05:50
这里有一种不需要线程本地变量或中间件的可行方法:在views.py
中,假设有一个将线程映射到请求的字典,以及一个用于序列化对它的访问的锁:
from threading import RLock
shared_data_lock = RLock()
request_map = {}
def set_request(request):
with shared_data_lock:
request_map[threading.current_thread()] = request
创建以下过滤器并附加到需要输出特定于请求的信息的处理程序:
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
然后,作为每个视图的第一个语句,在映射中设置请求:
def my_view(request, ...):
set_request(request)
# do your other view stuff here
使用此设置,您会发现日志输出包含特定于请求的相关信息。
发布于 2013-05-27 09:15:36
我想你要找的是一个custom log formatter。与mawimawi的答案结合使用以包含线程本地信息,您的format方法可以自动获取该信息并将其添加到每个记录的消息中。
有几件事需要考虑:首先,线程局部变量可能是危险的,更糟糕的是,如果您以使用线程池的方式进行部署,还会泄漏信息。其次,您需要谨慎编写格式化程序,以防它在没有线程本地信息的上下文中被调用。
https://stackoverflow.com/questions/16210101
复制相似问题