Django 错误邮件太长。我该如何截断它?
Django error email is too long. How do I truncate it?
Django 1.9 中的错误邮件似乎比以前长了很多。 "settings" 有一整节,我认为这是多余的,而且可能过于暴露。
编辑 Django 发送的错误电子邮件的最佳方法是什么?
编辑:我不只是想隐藏敏感信息。 Django 1.9 的邮件内容多了很多,我想把邮件的格式改短一些。我喜欢以前的方式。
django debug view 中有一个 django 模板变量 TECHNICAL_500_TEMPLATE
/TECHNICAL_500_TEXT_TEMPLATE
控制错误报告中可见的内容,当然还有错误电子邮件。注释解释说模板在 python 变量中,因此在模板加载程序中断时会生成错误。您可以在 django 包中更改此变量,但我不建议这样做。 TECHNICAL_500_TEMPLATE
被同一文件中的 ExceptionReporter
class 引用。
django utils log 中的 class AdminEmailHandler
然后使用 ExceptionReporter
生成 html 错误报告。
您可以 subclass AdminEmailHandler
并覆盖 emit
函数以包含您的 ExceptionReporter
的 subclassed 版本,它使用您自己定义的 TECHNICAL_500_TEMPLATE
.
这是一个例子:
用
创建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 行,如果您在 CustomExceptionReporter
中覆盖并复制粘贴 def get_traceback_data(self):
对于现在仍在寻找答案的人:
在 django 3.0 中,他们添加了添加 reporter_class
的选项,它自定义 just 电子邮件正文和回溯文本呈现。
因此,如果您只是想更改电子邮件模板,则无需同时覆盖 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'
},
两个注意事项:
- 如果您还希望将电子邮件正文作为 HTML 发送,您需要另一个模板 -
TECHNICAL_500_TEMPLATE
、新功能 - get_traceback_html()
,并设置 include_html = True
在日志配置中。同样在这里,您应该复制 django 的默认模板并更改您需要的内容。
- 如果您不想将整个模板保存在该文件中,而是保存在另一个 .html 文件中,请注意,即使您将它放在您定义的模板目录中,它也不会找到它。
我通过将 template.html 文件保存在与
自定义报告程序 .py 文件。
我的 custom_exception_report.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
中阅读有关报告 class 的更多信息
Django 1.9 中的错误邮件似乎比以前长了很多。 "settings" 有一整节,我认为这是多余的,而且可能过于暴露。
编辑 Django 发送的错误电子邮件的最佳方法是什么?
编辑:我不只是想隐藏敏感信息。 Django 1.9 的邮件内容多了很多,我想把邮件的格式改短一些。我喜欢以前的方式。
django debug view 中有一个 django 模板变量 TECHNICAL_500_TEMPLATE
/TECHNICAL_500_TEXT_TEMPLATE
控制错误报告中可见的内容,当然还有错误电子邮件。注释解释说模板在 python 变量中,因此在模板加载程序中断时会生成错误。您可以在 django 包中更改此变量,但我不建议这样做。 TECHNICAL_500_TEMPLATE
被同一文件中的 ExceptionReporter
class 引用。
django utils log 中的 class AdminEmailHandler
然后使用 ExceptionReporter
生成 html 错误报告。
您可以 subclass AdminEmailHandler
并覆盖 emit
函数以包含您的 ExceptionReporter
的 subclassed 版本,它使用您自己定义的 TECHNICAL_500_TEMPLATE
.
这是一个例子:
用
创建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 行,如果您在 CustomExceptionReporter
def get_traceback_data(self):
对于现在仍在寻找答案的人:
在 django 3.0 中,他们添加了添加 reporter_class
的选项,它自定义 just 电子邮件正文和回溯文本呈现。
因此,如果您只是想更改电子邮件模板,则无需同时覆盖 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'
},
两个注意事项:
- 如果您还希望将电子邮件正文作为 HTML 发送,您需要另一个模板 -
TECHNICAL_500_TEMPLATE
、新功能 -get_traceback_html()
,并设置include_html = True
在日志配置中。同样在这里,您应该复制 django 的默认模板并更改您需要的内容。 - 如果您不想将整个模板保存在该文件中,而是保存在另一个 .html 文件中,请注意,即使您将它放在您定义的模板目录中,它也不会找到它。 我通过将 template.html 文件保存在与 自定义报告程序 .py 文件。
我的 custom_exception_report.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
中阅读有关报告 class 的更多信息