DEBUG=False 时不会触发自定义记录器
Custom logger is not being triggered when DEBUG=False
我在settings.py
中有以下代码:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_true': { '()': 'django.utils.log.RequireDebugTrue', },
},
'handlers': {
'console': {
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
'kodular': {
'level': 'WARNING',
'class': 'account.reporter.KodularExceptionHandler',
},
},
'loggers': {
'django': {
'handlers': ['console', 'kodular'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),
},
},
}
KodularExceptionHandler
class 看起来像这样:
from copy import copy
import json
import logging
import requests
from django.conf import settings
from django.utils.log import AdminEmailHandler
from django.views.debug import ExceptionReporter
class KodularExceptionHandler(AdminEmailHandler):
def emit(self, record, *args, **kwargs):
print("Triggered")
try:
request = record.request
subject = record.getMessage()
except Exception:
return
if record.exc_info:
exc_info = record.exc_info
else:
exc_info = (None, record.getMessage(), None)
reporter = ExceptionReporter(request, is_email=True, *exc_info)
message = "%s\n\n%s" % (self.format(copy(record)), reporter.get_traceback_text())
text = "**Error Level**: *%s* | **Status Code**: `%s`\n\n\n" % (record.levelname, record.status_code)
url = 'https://api.github.com/repos/'+settings.GITHUB_ORG+'/'+settings.GITHUB_REPO+'/issues'
session = requests.Session()
session.auth = (settings.GITHUB_USERNAME, settings.GITHUB_PASSWORD)
issue = {'title': subject,
'body': text+message.replace('*', '\*').replace('_', '\_'),
'labels': ["error"]}
r = session.post(url, json.dumps(issue))
if r.status_code != 201:
return
github_issue_url = json.loads(r.content)['html_url']
if record.levelname == "WARNING":
return
attachments = [{
'title': subject,
'color': 'danger',
'actions': [{
'type': 'button',
'text': 'Github Issue',
'url': github_issue_url,
'style': 'primary',
}],
'fields': [{
"title": "Level",
"value": record.levelname,
"short": True
},{
"title": "Method",
"value": request.method if request else 'No Request',
"short": True
},{
"title": "Path",
"value": request.path if request else 'No Request',
"short": True
},{
"title": "User",
"value": ( (request.user.username + ' (' + str(request.user.pk) + ')'
if request.user.is_authenticated else 'Anonymous' )
if request else 'No Request' ),
"short": True
},{
"title": "Status Code",
"value": record.status_code,
"short": True
},{
"title": "UA",
"value": ( request.META['HTTP_USER_AGENT']
if request and request.META else 'No Request' ),
"short": False
},{
"title": 'GET Params',
"value": json.dumps(request.GET) if request else 'No Request',
"short": False
},{
"title": "POST Data",
"value": json.dumps(request.POST) if request else 'No Request',
"short": False
}]
}]
data = { 'payload': json.dumps({'attachments': attachments}) }
webhook_url = settings.SLACK_HOOK
r = requests.post(webhook_url, data=data)
当我在设置中设置 DEBUG = True
时,一切正常:控制台处理错误(并打印 "Reached"),Github 创建问题并发送 Slack 通知。
但是,如果我设置 DEBUG = False
,就会出错。正如预期的那样,控制台输出的信息较少;但既没有创建 Github 问题,也没有发送 Slack 通知。
我认为记录器处理程序的某处存在问题。看起来 KodularExceptionHandler
没有被触发,因为控制台不打印 "Reached",而当启用调试时它会打印。
知道是什么导致自定义错误报告 class 在调试设置为 false 时未被触发吗?
发生这种情况是因为这是 AdminEmailHandler
的默认行为(如配置中所定义),它是 KodularExceptionHandler
class 的父 class .由于 AdminEmailHandler
class 在加载 django 应用程序时启用了 django.utils.log.RequireDebugFalse
过滤器 (https://github.com/django/django/blob/stable/2.2.x/django/utils/log.py#L49),因此此过滤器扩展到从处理程序继承的任何 classes .
您可以使用设置 'disable_existing_loggers': True
,或者根本不继承 AdminEmailHandler
。如果您查看 AdminEmailHandler
(https://github.com/django/django/blob/stable/2.2.x/django/utils/log.py#L79) 的代码,您会注意到您已经覆盖了它的大部分代码(__init__
除外)。也许您可以继承 logging.Handler
。
我的 urls.py
文件有一点问题。我正在使用自定义错误页面处理程序:
from account import views
handler404 = views.error404
handler500 = views.error500
但是,文件 views.py
看起来像这样:
from django.shortcuts import render
from account.admin import requires_login
def error404(request, *args, **kwargs):
return render(request, 'error/404.html')
def error500(request, *args, **kwargs):
return render(request, 'error/500.html')
我通过将其更改为
来修复所有问题
from django.shortcuts import render
from account.admin import requires_login
def error404(request, *args, **kwargs):
return render(request, 'error/404.html', status=404)
def error500(request, *args, **kwargs):
return render(request, 'error/500.html', status=500)
我在settings.py
中有以下代码:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_true': { '()': 'django.utils.log.RequireDebugTrue', },
},
'handlers': {
'console': {
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
'kodular': {
'level': 'WARNING',
'class': 'account.reporter.KodularExceptionHandler',
},
},
'loggers': {
'django': {
'handlers': ['console', 'kodular'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),
},
},
}
KodularExceptionHandler
class 看起来像这样:
from copy import copy
import json
import logging
import requests
from django.conf import settings
from django.utils.log import AdminEmailHandler
from django.views.debug import ExceptionReporter
class KodularExceptionHandler(AdminEmailHandler):
def emit(self, record, *args, **kwargs):
print("Triggered")
try:
request = record.request
subject = record.getMessage()
except Exception:
return
if record.exc_info:
exc_info = record.exc_info
else:
exc_info = (None, record.getMessage(), None)
reporter = ExceptionReporter(request, is_email=True, *exc_info)
message = "%s\n\n%s" % (self.format(copy(record)), reporter.get_traceback_text())
text = "**Error Level**: *%s* | **Status Code**: `%s`\n\n\n" % (record.levelname, record.status_code)
url = 'https://api.github.com/repos/'+settings.GITHUB_ORG+'/'+settings.GITHUB_REPO+'/issues'
session = requests.Session()
session.auth = (settings.GITHUB_USERNAME, settings.GITHUB_PASSWORD)
issue = {'title': subject,
'body': text+message.replace('*', '\*').replace('_', '\_'),
'labels': ["error"]}
r = session.post(url, json.dumps(issue))
if r.status_code != 201:
return
github_issue_url = json.loads(r.content)['html_url']
if record.levelname == "WARNING":
return
attachments = [{
'title': subject,
'color': 'danger',
'actions': [{
'type': 'button',
'text': 'Github Issue',
'url': github_issue_url,
'style': 'primary',
}],
'fields': [{
"title": "Level",
"value": record.levelname,
"short": True
},{
"title": "Method",
"value": request.method if request else 'No Request',
"short": True
},{
"title": "Path",
"value": request.path if request else 'No Request',
"short": True
},{
"title": "User",
"value": ( (request.user.username + ' (' + str(request.user.pk) + ')'
if request.user.is_authenticated else 'Anonymous' )
if request else 'No Request' ),
"short": True
},{
"title": "Status Code",
"value": record.status_code,
"short": True
},{
"title": "UA",
"value": ( request.META['HTTP_USER_AGENT']
if request and request.META else 'No Request' ),
"short": False
},{
"title": 'GET Params',
"value": json.dumps(request.GET) if request else 'No Request',
"short": False
},{
"title": "POST Data",
"value": json.dumps(request.POST) if request else 'No Request',
"short": False
}]
}]
data = { 'payload': json.dumps({'attachments': attachments}) }
webhook_url = settings.SLACK_HOOK
r = requests.post(webhook_url, data=data)
当我在设置中设置 DEBUG = True
时,一切正常:控制台处理错误(并打印 "Reached"),Github 创建问题并发送 Slack 通知。
但是,如果我设置 DEBUG = False
,就会出错。正如预期的那样,控制台输出的信息较少;但既没有创建 Github 问题,也没有发送 Slack 通知。
我认为记录器处理程序的某处存在问题。看起来 KodularExceptionHandler
没有被触发,因为控制台不打印 "Reached",而当启用调试时它会打印。
知道是什么导致自定义错误报告 class 在调试设置为 false 时未被触发吗?
发生这种情况是因为这是 AdminEmailHandler
的默认行为(如配置中所定义),它是 KodularExceptionHandler
class 的父 class .由于 AdminEmailHandler
class 在加载 django 应用程序时启用了 django.utils.log.RequireDebugFalse
过滤器 (https://github.com/django/django/blob/stable/2.2.x/django/utils/log.py#L49),因此此过滤器扩展到从处理程序继承的任何 classes .
您可以使用设置 'disable_existing_loggers': True
,或者根本不继承 AdminEmailHandler
。如果您查看 AdminEmailHandler
(https://github.com/django/django/blob/stable/2.2.x/django/utils/log.py#L79) 的代码,您会注意到您已经覆盖了它的大部分代码(__init__
除外)。也许您可以继承 logging.Handler
。
我的 urls.py
文件有一点问题。我正在使用自定义错误页面处理程序:
from account import views
handler404 = views.error404
handler500 = views.error500
但是,文件 views.py
看起来像这样:
from django.shortcuts import render
from account.admin import requires_login
def error404(request, *args, **kwargs):
return render(request, 'error/404.html')
def error500(request, *args, **kwargs):
return render(request, 'error/500.html')
我通过将其更改为
来修复所有问题from django.shortcuts import render
from account.admin import requires_login
def error404(request, *args, **kwargs):
return render(request, 'error/404.html', status=404)
def error500(request, *args, **kwargs):
return render(request, 'error/500.html', status=500)