出于调试的目的,我想使用Django的日志机制来记录每一个传入的请求,当它“到达”django-rest框架的门口时。
Djagno以以下方式(从settings.py中的logging部分)记录其请求(仅“警告”日志级别及更高级别):
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
我希望实现类似的功能(注意:日志级别是DEBUG):
'rest_framework.request': {
'handlers': ['logfile'],
'level': 'DEBUG',
'propagate': False,
},
有没有一种方法可以做到这一点,而不需要在DRF的源代码中嵌入记录器?
DRF中是否有某种我不知道的“日志后端”选项?
我制作了一个通用的RequestLogMiddleware
,它可以通过中间件中的
decorator\u连接到任何Django
视图中。
import socket
import time
class RequestLogMiddleware(object):
def process_request(self, request):
request.start_time = time.time()
def process_response(self, request, response):
if response['content-type'] == 'application/json':
if getattr(response, 'streaming', False):
response_body = '<<<Streaming>>>'
else:
response_body = response.content
else:
response_body = '<<<Not JSON>>>'
log_data = {
'user': request.user.pk,
'remote_address': request.META['REMOTE_ADDR'],
'server_hostname': socket.gethostname(),
'request_method': request.method,
'request_path': request.get_full_path(),
'request_body': request.body,
'response_status': response.status_code,
'response_body': response_body,
'run_time': time.time() - request.start_time,
}
# save log_data in some way
return response
from django.utils.decorators import decorator_from_middleware
from .middleware import RequestLogMiddleware
class RequestLogViewMixin(object):
"""
Adds RequestLogMiddleware to any Django View by overriding as_view.
"""
@classmethod
def as_view(cls, *args, **kwargs):
view = super(RequestLogViewMixin, cls).as_view(*args, **kwargs)
view = decorator_from_middleware(RequestLogMiddleware)(view)
return view
from rest_framework import generics
from ...request_log.mixins import RequestLogViewMixin
class SomeListView(
RequestLogViewMixin,
generics.ListAPIView
):
...
覆盖APIView。initial()
方法添加日志记录。
以下方法由视图的用户直接调用。dispatch()方法。它们执行调用处理程序方法之前或之后需要执行的任何操作,例如。get()。post()、put()、patch()和。删除()。
。initial(self、request、*args、**kwargs)
执行调用处理程序方法之前需要执行的任何操作。此方法用于强制权限和限制,以及执行内容协商。
做了一个自定义的中间件:
import logging
import time
logger = logging.getLogger(__name__)
class APILogMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
start_time = time.time()
response = self.get_response(request)
duration = time.time() - start_time
response_ms = duration * 1000
user = str(getattr(request, 'user', ''))
method = str(getattr(request, 'method', '')).upper()
status_code = str(getattr(response, 'status_code', ''))
request_path = str(getattr(request, 'path', ''))
if status_code == '200' and response_ms > 2000:
logger.info({
"message": "*****SLOW RESPONSE****",
"path": request_path,
"response_time": str(response_ms) + " ms",
"method": method,
"user": user,
"status_code": status_code
})
return response
这将记录所有需要2秒钟以上才能返回响应的API。只需在设置中添加中间件的完整路径=[“path.to.APILogMiddleware”]。派克