errors: Show what logger and source code the message comes from.

This commit is contained in:
Greg Price 2017-11-30 16:26:37 -08:00 committed by Steve Howell
parent 77e47900dd
commit eea1ceb0db
3 changed files with 20 additions and 5 deletions

View File

@ -22,6 +22,10 @@ def format_subject(subject: str) -> str:
""" """
return subject.replace('\n', '\\n').replace('\r', '\\r') return subject.replace('\n', '\\n').replace('\r', '\\r')
def logger_repr(report: Dict[str, Any]) -> str:
return ("Logger %(logger_name)s, from module %(log_module)s line %(log_lineno)d:"
% report)
def user_info_str(report: Dict[str, Any]) -> str: def user_info_str(report: Dict[str, Any]) -> str:
if report['user_full_name'] and report['user_email']: if report['user_full_name'] and report['user_email']:
user_info = "%(user_full_name)s (%(user_email)s)" % (report) user_info = "%(user_full_name)s (%(user_email)s)" % (report)
@ -107,6 +111,7 @@ def notify_server_error(report: Dict[str, Any]) -> None:
def zulip_server_error(report: Dict[str, Any]) -> None: def zulip_server_error(report: Dict[str, Any]) -> None:
subject = '%(node)s: %(message)s' % (report) subject = '%(node)s: %(message)s' % (report)
logger_str = logger_repr(report)
user_info = user_info_str(report) user_info = user_info_str(report)
deployment = deployment_repr() deployment = deployment_repr()
@ -121,8 +126,8 @@ def zulip_server_error(report: Dict[str, Any]) -> None:
else: else:
request_repr = "Request info: none" request_repr = "Request info: none"
message = ("Error generated by %s\n\n~~~~ pytb\n%s\n\n~~~~\n%s\n%s" message = ("%s\nError generated by %s\n\n~~~~ pytb\n%s\n\n~~~~\n%s\n%s"
% (user_info, report['stack_trace'], deployment, request_repr)) % (logger_str, user_info, report['stack_trace'], deployment, request_repr))
realm = get_system_bot(settings.ERROR_BOT).realm realm = get_system_bot(settings.ERROR_BOT).realm
internal_send_message(realm, settings.ERROR_BOT, "stream", "errors", internal_send_message(realm, settings.ERROR_BOT, "stream", "errors",
@ -131,6 +136,7 @@ def zulip_server_error(report: Dict[str, Any]) -> None:
def email_server_error(report: Dict[str, Any]) -> None: def email_server_error(report: Dict[str, Any]) -> None:
subject = '%(node)s: %(message)s' % (report) subject = '%(node)s: %(message)s' % (report)
logger_str = logger_repr(report)
user_info = user_info_str(report) user_info = user_info_str(report)
deployment = deployment_repr() deployment = deployment_repr()
@ -144,8 +150,8 @@ def email_server_error(report: Dict[str, Any]) -> None:
else: else:
request_repr = "Request info: none\n" request_repr = "Request info: none\n"
message = ("Error generated by %s\n\n%s\n\n%s\n\n%s" message = ("%s\nError generated by %s\n\n%s\n\n%s\n\n%s"
% (user_info, report['stack_trace'], deployment, request_repr)) % (logger_str, user_info, report['stack_trace'], deployment, request_repr))
mail_admins(format_subject(subject), message, fail_silently=True) mail_admins(format_subject(subject), message, fail_silently=True)

View File

@ -119,7 +119,11 @@ def skip_site_packages_logs(record: logging.LogRecord) -> bool:
return True return True
def find_log_caller_module(record: logging.LogRecord) -> Optional[str]: def find_log_caller_module(record: logging.LogRecord) -> Optional[str]:
'''Find the module name corresponding to where this record was logged.''' '''Find the module name corresponding to where this record was logged.
Sadly `record.module` is just the innermost component of the full
module name, so we have to go reconstruct this ourselves.
'''
# Repeat a search similar to that in logging.Logger.findCaller. # Repeat a search similar to that in logging.Logger.findCaller.
# The logging call should still be on the stack somewhere; search until # The logging call should still be on the stack somewhere; search until
# we find something in the same source file, and that should give the # we find something in the same source file, and that should give the

View File

@ -11,6 +11,7 @@ from django.http import HttpRequest
from django.utils.log import AdminEmailHandler from django.utils.log import AdminEmailHandler
from django.views.debug import ExceptionReporter, get_exception_reporter_filter from django.views.debug import ExceptionReporter, get_exception_reporter_filter
from zerver.lib.logging_util import find_log_caller_module
from zerver.lib.queue import queue_json_publish from zerver.lib.queue import queue_json_publish
def add_request_metadata(report: Dict[str, Any], request: HttpRequest) -> None: def add_request_metadata(report: Dict[str, Any], request: HttpRequest) -> None:
@ -85,6 +86,10 @@ class AdminNotifyHandler(logging.Handler):
report['stack_trace'] = stack_trace report['stack_trace'] = stack_trace
report['message'] = message report['message'] = message
report['logger_name'] = record.name
report['log_module'] = find_log_caller_module(record)
report['log_lineno'] = record.lineno
if hasattr(record, "request"): if hasattr(record, "request"):
add_request_metadata(report, record.request) # type: ignore # record.request is added dynamically add_request_metadata(report, record.request) # type: ignore # record.request is added dynamically