代码之家  ›  专栏  ›  技术社区  ›  AlexH

Django错误电子邮件太长。如何截断它?

  •  4
  • AlexH  · 技术社区  · 8 年前

    Django 1.9中的错误电子邮件似乎比以前长得多。这里有一整段关于“设置”的内容,我认为这是多余的,而且可能太暴露了。

    编辑Django发送的错误电子邮件的最佳方式是什么?

    编辑:我不只是想隐藏敏感信息。Django 1.9中的电子邮件中有很多内容,我想将电子邮件的格式更改为更短。我喜欢老样子。

    2 回复  |  直到 8 年前
        1
  •  8
  •   Airith    8 年前

    有一个django模板变量 TECHNICAL_500_TEMPLATE / TECHNICAL_500_TEXT_TEMPLATE django debug view 它控制错误报告中可见的内容,当然还有错误电子邮件。注释说明模板位于python变量中,以便在模板加载程序中断时生成错误。您可以在django包中更改此变量,但我不建议这样做。 技术500_模板 ExceptionReporter 类在同一文件中。

    班级 AdminEmailHandler 在里面 django utils log 然后使用 异常报告程序 以生成html错误报告。

    您可以将 管理员邮件处理程序 并覆盖 emit 函数来包含子类版本的 异常报告程序 使用您自己定义的 技术500_模板 .

    下面是一个例子:

    创造 reporter.py 具有

    from copy import copy
    
    from django.views import debug
    from django.utils import log
    from django.conf import settings
    from django import template
    
    TECHNICAL_500_TEMPLATE = """
        # custom template here, copy the original and make adjustments
    """
    TECHNICAL_500_TEXT_TEMPLATE = """
        # custom template here, copy the original and make adjustments
    """
    
    class CustomExceptionReporter(debug.ExceptionReporter):
        def get_traceback_html(self):
            t = debug.DEBUG_ENGINE.from_string(TECHNICAL_500_TEMPLATE)
            c = template.Context(self.get_traceback_data(), use_l10n=False)
            return t.render(c)
    
        def get_traceback_text(self):
            t = debug.DEBUG_ENGINE.from_string(TECHNICAL_500_TEXT_TEMPLATE)
            c = template.Context(self.get_traceback_data(), autoescape=False, use_l10n=False)
            return t.render(c)
    
    class CustomAdminEmailHandler(log.AdminEmailHandler):
        def emit(self, record):
            try:
                request = record.request
                subject = '%s (%s IP): %s' % (
                    record.levelname,
                    ('internal' if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS
                     else 'EXTERNAL'),
                    record.getMessage()
                )
            except Exception:
                subject = '%s: %s' % (
                    record.levelname,
                    record.getMessage()
                )
                request = None
            subject = self.format_subject(subject)
    
            no_exc_record = copy(record)
            no_exc_record.exc_info = None
            no_exc_record.exc_text = None
    
            if record.exc_info:
                exc_info = record.exc_info
            else:
                exc_info = (None, record.getMessage(), None)
    
            reporter = CustomExceptionReporter(request, is_email=True, *exc_info)
            message = "%s\n\n%s" % (self.format(no_exc_record), reporter.get_traceback_text())
            html_message = reporter.get_traceback_html() if self.include_html else None
            self.send_mail(subject, message, fail_silently=True, html_message=html_message)
    

    然后只需设置您的django设置以在 logging section .

    LOGGING = {
        # Your other logging settings
        # ...
        'handlers': {
            'mail_admins': {
                'level': 'ERROR',
                'class': 'project.reporter.CustomAdminEmailHandler',
                'filters': ['special']
            }
        },
    }
    

    如果您只想隐藏设置,可以在 'settings': get_safe_settings(), 第294行,如果覆盖并复制粘贴 def get_traceback_data(self): 在您的 CustomExceptionReporter

        2
  •  3
  •   lmaayanl    5 年前

    对于现在仍在寻找答案的人:

    在django 3.0中,他们添加了添加 reporter_class 其定制 只是 电子邮件主体和回溯文本呈现。

    因此,如果您只是想更改电子邮件模板,则无需同时覆盖 AdminEmailHandler .

    所以根据@Airith的回答,你需要:

    # custom_exception_reporter.py
    
    from django.views import debug
    from django import template
    
    TECHNICAL_500_TEXT_TEMPLATE = """ 
    # custom template here, copy the original and make adjustments 
    """
    
    class CustomExceptionReporter(debug.ExceptionReporter):
        def get_traceback_text(self):
            t = debug.DEBUG_ENGINE.from_string(TECHNICAL_500_TEXT_TEMPLATE)
            c = template.Context(self.get_traceback_data(), autoescape=False, use_l10n=False)
            return t.render(c)
    

    然后在日志配置中:

    'handlers': {
            'mail_admins': {
                 'level': 'ERROR',
                 'class': 'django.utils.log.AdminEmailHandler',
                 'include_html': False,
                 'reporter_class': 'project.custom_exception_reporter.CustomExceptionReporter'
            },
    

    两个注意事项:

    1. 如果您希望以HTML格式发送电子邮件正文,则需要另一个模板- TECHNICAL_500_TEMPLATE ,新功能- get_traceback_html() ,并设置 include_html = True 在日志配置中。在这里,您应该复制django的默认模板,只需更改所需内容即可。
    2. 如果您不想将整个模板保存在该文件中,而是保存在另一个.html文件中,请注意,即使您将其放置在您定义的模板目录中,它也找不到它。 我通过保留模板解决了这个问题。html文件与 自定义reporter.py文件。

    我的customexceptionreport示例。py,其中我将模板保存在同一目录中(如注释#2所述):

    import os
    from django.views import debug
    from django import template
    
    TECHNICAL_500_TEXT_TEMPLATE = "technical_500.text"
    
    
    class CustomExceptionReporter(debug.ExceptionReporter):
        def get_traceback_text(self):
            t = self._get_template(TECHNICAL_500_TEXT_TEMPLATE)
            c = template.Context(self.get_traceback_data(), autoescape=False, use_l10n=False)
            return t.render(c)
    
        @staticmethod
        def _get_template(template_name):
            dir_path = os.path.dirname(os.path.realpath(__file__))
            template_path = os.path.join(dir_path, template_name)
            with open(template_path, 'r') as fh:
                return debug.DEBUG_ENGINE.from_string(fh.read())
    
    

    您可以在django文档中阅读有关报告类的更多信息 here

    推荐文章