提问者:小点点

记录对django rest框架的请求


出于调试的目的,我想使用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中是否有某种我不知道的“日志后端”选项?


共3个答案

匿名用户

我制作了一个通用的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”]。派克