mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	errors: Show what logger and source code the message comes from.
This commit is contained in:
		@@ -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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user