【问题标题】:Django Error Logging: Adding request header, body and user informationDjango 错误记录:添加请求标头、正文和用户信息
【发布时间】:2017-11-26 12:15:10
【问题描述】:

寻找一种方法在我的错误日志中添加标题、正文和用户的电子邮件地址以及我的 views.py

中的异常堆栈跟踪

在网上搜索了几个小时后,许多人建议编写我自己的中间件,有些人建议将此类信息记录到单独的日志中。然而,知道你的代码哪里出错可以解决问题的一部分,确定它影响了哪个可怜的灵魂以及在该异常期间发送了哪些请求数据,这对于纠正问题大有帮助。将这些信息放在同一个日志文件中对我来说很有意义。

目前在我的views.py中,我有这个简单的设置:

from django.db.models import Min, Max, Q, F, Count, Sum
from django.db import connection
from django.conf import settings
from django.http import HttpResponse, HttpResponseRedirect
from myapp.models import *
import logging

logging.basicConfig(filename="errors.log",
                    level=logging.ERROR,
                    format='%(asctime)s: %(message)s')


def random_view(request):
    if request.user.is_authenticated() and request.user.is_active:
         # generic view code goes here.
    else:
        return HttpResponse(status=401)

此设置在一段时间内运行良好。每次出现异常时,都会注销时间、异常错误信息和堆栈跟踪。

我如何还可以添加 request.META、request.user.id 和 request.body 以及堆栈跟踪?

任何建议都会有所帮助。一个成功的答案,甚至更好!

谢谢

【问题讨论】:

标签: python django logging


【解决方案1】:

我认为您遇到的日志记录问题的完整解决方案是实施中间件。中间件将能够与您拥有的任何类型的视图实现一起使用,无论它是基于类的视图、基于函数的视图还是来自 DRF 的 APIView。

您可以为完整日志定义一个中间件。确保在身份验证中间件之后适当地放置中间件 -

MIDDLEWARE = [
    ...,
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    ...,
    'path.to.your.middleware.LogMiddleware'
]

在日志中间件中,您可以访问请求和响应。您可以通过记录器存储请求、用户(如果经过身份验证)和来自请求的所有 META 属性,或者如果需要,您甚至可以将其存储在数据库中。虽然,请注意,存储在数据库中是有代价的。您可以通过Django middleware documentation了解如何编写中间件。

import traceback

class LogMiddleware():
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        try:
            return self.get_response(request)
        except:
            if request.user.is_authenticated():
                # Log the user
            path = request.get_full_path() # Get the URL Path
            tb = traceback.format_exc() # Get the traceback
            meta = request.META # Get request meta information
            # Log everything
            raise  # Raise exception again after catching

您可以从HttpRequest 的 django 文档中了解所有元属性。如果您需要对此进行任何澄清,请告诉我。

【讨论】:

    【解决方案2】:

    我会在这里使用装饰器。直接切入代码...

    import logging
    from functools import wraps
    from django.http import HttpResponse, HttpRequest
    
    logging.basicConfig(filename="errors.log",
                        level=logging.ERROR,
                        format='%(asctime)s: %(message)s')
    log = logging.getLogger(__name__)
    
    def log_exceptions(wrapped):
        @wraps(wrapped)
        def wrapper(*args, **kwargs):
            try:
                return wrapped(*args, **kwargs)
            except:
                # log and re-raise
                request = args[0] if len(args) > 0 and isinstance(args[0], HttpRequest) else None
                msg = ("\nuser.id/email: {}/{}\nMETA: {}...\nbody: {}"
                       .format(request.user.id,
                               getattr(request.user, 'email','?'),
                               str(request.META)[:80],
                               request.body)
                       if request
                       else "not a HttpRequest")
                log.exception(msg)
                raise
        return wrapper
    
    @log_exceptions
    def random_view(request):
        raise ValueError("simulate a crash")
        if request.user.is_authenticated() and request.user.is_active:
            return HttpResponse('hi')
             # generic view code goes here.
        else:
            return HttpResponse(status=401)
    

    errors.log 应该捕获类似

    的内容
    2017-06-27 20:48:09,282: 
    user.id/email: 1/test@domain.com
    META: {'SESSION_MANAGER': 'local/acb:@/tmp/.ICE-unix/4255,unix/acb:/tmp/.ICE-unix/4255...
    body: b''
    Traceback (most recent call last):
      File "/home/rod/pyves/rangetest/rangetest/data/views.py", line 14, in wrapper
        return wrapped(*args, **kwargs)
      File "/home/rod/pyves/rangetest/rangetest/data/views.py", line 31, in random_view
        raise ValueError("simulate a crash")
    ValueError: simulate a crash
    

    注意,您也可能会在您的 errors.log 中看到 Django 崩溃日志。您可以使用 Django 的文档将日志拆分为单独的文件,但仍然很复杂 logging config

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-13
      • 2019-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多