def format(self, record):
		try:
			request = record.request
		except AttributeError:
			return super().format(record=record)

		if record.exc_info:
			exc_info = record.exc_info
		else:
			exc_info = (None, record.getMessage(), None)

		reporter = ExceptionReporter(request, is_email=False, *exc_info)
		self.template = self.template or Template(LOG_TEMPLATE_500, name='Log 500 template')
		c = Context(reporter.get_traceback_data(), autoescape=False, use_l10n=False)
		
		frames = []
		
		for frame in c['frames']:
			fvars = (
				(k, str(v)
					.replace('&', '&')
					.replace('&lt;', '<')
					.replace('&gt;', '>')
					.replace('&quot;', '"')
					.replace("&#39;", '\'')
				)
				for (k, v) in frame['vars']
			)
			
			frame['vars'] = [
				(k, "'<WSGIRequest ...>'")
				if str(v).startswith("'<WSGIRequest")
				else (k, v)
				for (k, v) in fvars
			]
			
			frames.append(frame)
		
		formatted = self.template.render(c)
		
		divider = '-' * 80 + '\n'

		message = io.StringIO()
		message.write(divider)
		message.write(super().format(record=record))
		message.write('\n')
		message.write(formatted)
		message.write(divider)

		return message.getvalue()
    def format(self, record):
        try:
            request = record.request
        except AttributeError:
            return super().format(record=record)

        if record.exc_info:
            exc_info = record.exc_info
        else:
            exc_info = (None, record.getMessage(), None)

        reporter = ExceptionReporter(request, is_email=False, *exc_info)
        self.template = self.template or Template(LOG_TEMPLATE_500,
                                                  name='Log 500 template')
        c = Context(reporter.get_traceback_data(),
                    autoescape=False,
                    use_l10n=False)

        frames = []

        for frame in c['frames']:
            fvars = ((k, str(v).replace('&amp;', '&').replace(
                '&lt;', '<').replace('&gt;',
                                     '>').replace('&quot;',
                                                  '"').replace("&#39;", '\''))
                     for (k, v) in frame['vars'])

            frame['vars'] = [(k, "'<WSGIRequest ...>'")
                             if str(v).startswith("'<WSGIRequest") else (k, v)
                             for (k, v) in fvars]

            frames.append(frame)

        formatted = self.template.render(c)

        divider = '-' * 80 + '\n'

        message = io.StringIO()
        message.write(divider)
        message.write(super().format(record=record))
        message.write('\n')
        message.write(formatted)
        message.write(divider)

        return message.getvalue()
Ejemplo n.º 3
0
def server_error(request, template_name="500.html"):
    """
    500 error handler.
    """

    # Get exception info
    exc_type, exc_value, exc_traceback = sys.exc_info()
    if (
        getattr(settings, "TEMPLATION_DEBUG", False)
        and (exc_type.__name__ in DUMP_EXCEPTIONS)
        and get_resource_access_model().objects.filter(resource_pointer__resource=thread_locals.resource)
    ):
        reporter = ExceptionReporter(request, exc_type, exc_value, exc_traceback)

        t = Template(TEMPLATION_500_TEMPLATE, name="Technical 500 template")
        c = Context(reporter.get_traceback_data(), use_l10n=False)
        html = t.render(c)
        return HttpResponseServerError(html, content_type="text/html")

    return django_server_error(request, template_name)
Ejemplo n.º 4
0
def exception_email_format(request, exc_info):
    '''
	This function is used to  encrypt the sensitive input data and send email to notify server administrator
	'''
    if settings.DEBUG is False:
        reporter = ExceptionReporter(request, is_email=True, *exc_info)
        subject = r'Error:: IP %s : %s ' % (request.META.get('SERVER_ADDR'),
                                            reporter.exc_value)
        input_data = get_request_body(request)
        trace_data = reporter.get_traceback_data()
        if input_data:
            data_encrypt = response_output(input_data)
            trace_data['input_data'] = data_encrypt
        html_message = render_to_string('error_report.html', trace_data)
        ### send exception email through celery
        exception_email.delay_or_eager(subject,
                                       'ERROR MAIL',
                                       fail_silently=True,
                                       html_message=html_message)
    return
Ejemplo n.º 5
0
    def emit(self, record, *args, **kwargs):

        # original AdminEmailHandler 'emit' method code (but without actually sending email)
        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 = record.getMessage()
            request = None
        subject = f'{record.levelname}: {self.format_subject(subject)}'

        # Since we add a nicely formatted traceback on our own, create a copy
        # of the log record without the exception data.
        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 = ExceptionReporter(request, is_email=True, *exc_info)
        message = reporter.get_traceback_data()
        # message = '%s\n\n%s' % (self.format(no_exc_record), reporter.get_traceback_text())

        # self.send_mail(subject, message, fail_silently=True, html_message=html_message)

        # this is where original 'emit' method code ends

        # construct slack attachment detail fields
        colors = {'ERROR': 'danger', 'INFO': 'good', 'WARNING': 'warning'}
        attachments = [
            {
                'title':
                subject,
                'color':
                colors.get(record.levelname, '#1d9bd1'),
                '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': getattr(record, 'status_code', None),
                    '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,
                }],
            },
        ]
        if record.levelname == 'ERROR':
            extra_data = [
                'frames', 'request_meta', 'filtered_POST_items',
                'template_info', 'template_does_not_exist', 'postmortem'
            ]

            # slack message attachment text has max of 8000 bytes
            # lets split it up into 7900 bytes long chunks to be on the safe side
            split = 7900
            byte_size = 0
            response = ''
            part = 1

            for field in extra_data:
                data = json.dumps(message[field], indent=2, default=str)
                byte_size += len(data) + len(field) + len(data) + 3
                if byte_size < split:
                    response += f'{field}:\n{data}\n'
                else:
                    # add main error message body
                    attachments.append({
                        'color': 'danger',
                        'title': f'Extra details ({part})',
                        'text': response,
                        'ts': time.time(),
                    })

                    part += 1
                    byte_size = len(data) + len(field) + len(data) + 3
                    response = f'{field}:\n{data}\n'
            # add main error message body
            attachments.append({
                'color': 'danger',
                'title': f'Extra details ({part})',
                'text': response,
                'ts': time.time(),
            })

        # construct main text
        main_text = (
            'Alert at ' +
            time.strftime('%A, %d %b %Y %H:%M:%S +0000', time.gmtime()))

        # construct data
        data = {
            'payload':
            json.dumps({
                'main_text': main_text,
                'attachments': attachments
            }),
        }

        # setup channel webhook
        webhook_url = os.getenv('SLACK_ERROR_WEBHOOK')

        # send it
        requests.post(webhook_url, data=data)
Ejemplo n.º 6
0
    def log_event(cls, request, response=None, exception=None):
        from django.views.debug import ExceptionReporter

        stack_info = {}
        if exception:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            summary = "{0}: {1}".format(exception.__class__.__name__, unicode(exception))
            lineno = traceback.tb_lineno(exc_traceback)

            stack = traceback.extract_stack(exc_traceback.tb_frame)
            path = stack[0][0]

            try:
                reporter = ExceptionReporter(request, is_email=False, *(exc_type, exc_value, exc_traceback))
                django_data = reporter.get_traceback_data()

                stack_info["frames"] = django_data.get("frames", [])

                #Traceback objects aren't JSON serializable, so delete them
                for frame in stack_info["frames"]:
                    if "tb" in frame:
                        del frame["tb"]

                stack_info["lastframe"] = django_data.get("lastframe", {})
            except Exception:
                logging.exception("Unable to get html traceback info for some reason")
            level = EVENT_LEVEL_ERROR

        else:
            summary = "{0} at {1}".format(response.status_code, request.path)
            lineno = 0
            path = "?".join([request.path, request.META.get('QUERY_STRING')])
            exception = HttpResponse()
            level = EVENT_LEVEL_WARNING if response.status_code == 404 else EVENT_LEVEL_INFO

        error, created = Error.objects.get_or_create(
            exception_class_name=exception.__class__.__name__,
            file_path=path,
            line_number=lineno,
            defaults={
                'level': level,
                'summary': summary,
                'exception_class_name': exception.__class__.__name__ if exception else ""
            }
        )

        @db.transactional(xg=True)
        def txn(_error):
            _error = Error.objects.get(pk=_error.pk)

            Event.objects.create(
                error=_error,
                request_repr=repr(request).strip(),
                request_method=request.method,
                request_url=request.build_absolute_uri(),
                request_querystring=request.META['QUERY_STRING'],
                logged_in_user_email=getattr(getattr(request, "user", None), "email", ""),
                stack_info_json=json.dumps(stack_info),
                app_version=os.environ.get('CURRENT_VERSION_ID', 'Unknown'),
                request_json=construct_request_json(request)
            )

            _error.last_event = timezone.now()
            _error.event_count += 1
            _error.save()

        txn(error)
Ejemplo n.º 7
0
def get_exception_info(request):   
    # We use Django's debug reporter, even though we are doing our own template.
    # This is because it has a great way of collecting all the useful info we 
    # need, so no reason not to leverage it 
    exc_info = sys.exc_info()
    reporter = ExceptionReporter(request, *exc_info)
    ctx = reporter.get_traceback_data()
    
    # This is a refactor of what the technical_500_template contains, just
    # doing the logic in Python rather than in a template. We collect all this
    # information so that we can log it.
    exception_type = ctx['exception_type'] if 'exception_type' in ctx else "No exception supplied"
    exception_value = ctx['exception_value'] if 'exception_value' in ctx else "No exception supplied"
    django_version = ctx["django_version_info"]
    python_executable = ctx['sys_executable']
    python_version = ctx['sys_version_info']
    python_path = ctx['sys_path']
    server_time = str(ctx['server_time'])
    unicode_hint = None
    if 'unicode_hint' in ctx:
        unicdoe_hint = ctx['unicode_hint']
    last_frame = None
    if 'lastframe' in ctx:
        frame_info = ctx['lastframe']
        last_frame = "%s in %s, line %s" % (frame_info['filename'], frame_info['function'], frame_info['lineno'])
    loaders = []
    if 'template_does_not_exist' in ctx and 'loader_debug_info' in ctx and ctx['loader_debug_info']:
        for loader in ctx['loader_debug_info']:
            loader_info = {"name": loader['loader'], "templates": []}
            for tmpl in loader['templates']:
                loader_info['templates'].append({"file": tmpl['name'], "exists": tmpl['exists']})
            loaders.append(loader_info)
    template_errors = None
    if 'template_info' in ctx and ctx['template_info']:
        template_info = ctx['template_info']
        template_errors = {
            "name": template_info['name'],
            "line": template_info['line'],
            "message": template_info['message']
        }
    exception_info = []
    if 'frames' in ctx:
        frames = ctx['frames']
        for frame in frames:
            frame_info = {
                "filename": frame['filename'],
                "function": frame['function'],
                "line": frame['lineno'],
                "context_line": frame['context_line'],
                "vars": []
            }
            if 'vars' in frame:
                for var in frame['vars']:
                    frame_info['vars'].append({
                        "variable": str(var[0]),
                        "value": format(var[1])
                    })
            exception_info.append(frame_info)
    request_info = {
        "path_info": request.path_info,
        "method": request.META['REQUEST_METHOD'],
        "url": request.build_absolute_uri(),
        "GET": {},
        "POST": {},
        "FILES": {},
        "COOKIES": {},
        "META": {}
    }
    if hasattr(request, "GET"):
        for key, value in request.GET.iteritems():
            request_info['GET'][key] = format(value)
    if "filtered_POST" in ctx:
        for key, value in ctx['filtered_POST'].iteritems():
            request_info['POST'][key] = format(value)
    if hasattr(request, "FILES"):
        for key, value in request.FILES.iteritems():
            request_info['FILES'][key] = format(value)
    if hasattr(request, "COOKIES"):
        for key, value in request.COOKIES.iteritems():
            request_info['COOKIES'][key] = format(value)
    if hasattr(request, "META"):
        for key, value in request.META.iteritems():
            request_info['META'][key] = format(value)
    settings_info = {}
    for key, value in ctx['settings'].iteritems():
        settings_info[key] = format(value)
        
    ctx['errorid'] = errorid = uuid.uuid4().hex
    
    full_info = dict(
        __time=datetime.datetime.now().isoformat(),
        __uuid=errorid,
        settings=settings_info,
        request=request_info,
        traceback=exception_info,
        stack=traceback.format_exc(exc_info[2]),
        last_frame=last_frame,
        template_loaders=loaders,
        template_errors=template_errors,
        unicode_hint=unicdoe_hint,
        exception_type=exception_type,
        exception_value=exception_value,
        django_version=django_version,
        python_version=python_version,
        python_executable=python_executable,
        python_path=python_path,
        server_time=server_time
    )
    
    return (errorid, ctx, full_info)
Ejemplo n.º 8
0
    def formatException(self, exc_info, request=None):
        #pylint:disable=too-many-locals,arguments-differ
        reporter = ExceptionReporter(request, is_email=True, *exc_info)
        traceback_data = reporter.get_traceback_data()
        filtered_traceback_data = {}

        if request:
            request_dict = {
                'http_method': request.method,
                'http_path': request.path_info
            }
            params = {}
            for key, val in six.iteritems(request.GET):
                params.update({key: val})
            if params:
                request_dict.update({'GET': params})
            params = {}
            for key, val in six.iteritems(request.POST):
                params.update({key: val})
            if params:
                request_dict.update({'POST': params})
            params = {}
            for key, val in six.iteritems(request.FILES):
                params.update({key: val})
            if params:
                request_dict.update({'FILES': params})
            params = {}
            for key, val in six.iteritems(request.COOKIES):
                params.update({key: val})
            if params:
                request_dict.update({'COOKIES': params})
            params = {}
            for key in self.whitelists.get('meta', []):
                value = request.META.get(key, None)
                if value is not None:
                    params.update({key: value})
            if params:
                request_dict.update({'META': params})
            filtered_traceback_data.update({'request_data': request_dict})

        for frame in traceback_data.get('frames', []):
            frame.pop('tb', None)

        for key in self.whitelists.get('traceback', []):
            value = traceback_data.get(key, None)
            if value is not None:
                if key == 'settings':
                    value = {}
                    for settings_key in self.whitelists.get(key, []):
                        settings_value = traceback_data[key].get(
                            settings_key, None)
                        if settings_value is not None:
                            value.update({settings_key: settings_value})
                if key == 'frames':
                    frames = value
                    value = []
                    for frame in frames:
                        frame_dict = {}
                        for frame_key, frame_val in six.iteritems(frame):
                            frame_dict.update({frame_key: str(frame_val)})
                        value += [frame_dict]
                filtered_traceback_data.update({key: value})

        # Pip packages
        installed_packages = get_installed_distributions(local_only=False)
        filtered_traceback_data.update({
            'installed_packages': [{
                'name': package.project_name,
                'version': package.version,
                'location': package.location
            } for package in installed_packages]
        })

        return filtered_traceback_data
Ejemplo n.º 9
0
def get_exception_info(request):
    # We use Django's debug reporter, even though we are doing our own template.
    # This is because it has a great way of collecting all the useful info we
    # need, so no reason not to leverage it
    exc_info = sys.exc_info()
    reporter = ExceptionReporter(request, *exc_info)
    ctx = reporter.get_traceback_data()

    # This is a refactor of what the technical_500_template contains, just
    # doing the logic in Python rather than in a template. We collect all this
    # information so that we can log it.
    exception_type = ctx[
        'exception_type'] if 'exception_type' in ctx else "No exception supplied"
    exception_value = ctx[
        'exception_value'] if 'exception_value' in ctx else "No exception supplied"
    django_version = ctx["django_version_info"]
    python_executable = ctx['sys_executable']
    python_version = ctx['sys_version_info']
    python_path = ctx['sys_path']
    server_time = str(ctx['server_time'])
    unicode_hint = None
    if 'unicode_hint' in ctx:
        unicdoe_hint = ctx['unicode_hint']
    last_frame = None
    if 'lastframe' in ctx:
        frame_info = ctx['lastframe']
        last_frame = "%s in %s, line %s" % (frame_info['filename'],
                                            frame_info['function'],
                                            frame_info['lineno'])
    loaders = []
    if 'template_does_not_exist' in ctx and 'loader_debug_info' in ctx and ctx[
            'loader_debug_info']:
        for loader in ctx['loader_debug_info']:
            loader_info = {"name": loader['loader'], "templates": []}
            for tmpl in loader['templates']:
                loader_info['templates'].append({
                    "file": tmpl['name'],
                    "exists": tmpl['exists']
                })
            loaders.append(loader_info)
    template_errors = None
    if 'template_info' in ctx and ctx['template_info']:
        template_info = ctx['template_info']
        template_errors = {
            "name": template_info['name'],
            "line": template_info['line'],
            "message": template_info['message']
        }
    exception_info = []
    if 'frames' in ctx:
        frames = ctx['frames']
        for frame in frames:
            frame_info = {
                "filename": frame['filename'],
                "function": frame['function'],
                "line": frame['lineno'],
                "context_line": frame['context_line'],
                "vars": []
            }
            if 'vars' in frame:
                for var in frame['vars']:
                    frame_info['vars'].append({
                        "variable": str(var[0]),
                        "value": format(var[1])
                    })
            exception_info.append(frame_info)
    request_info = {
        "path_info": request.path_info,
        "method": request.META['REQUEST_METHOD'],
        "url": request.build_absolute_uri(),
        "GET": {},
        "POST": {},
        "FILES": {},
        "COOKIES": {},
        "META": {}
    }
    if hasattr(request, "GET"):
        for key, value in request.GET.iteritems():
            request_info['GET'][key] = format(value)
    if "filtered_POST" in ctx:
        for key, value in ctx['filtered_POST'].iteritems():
            request_info['POST'][key] = format(value)
    if hasattr(request, "FILES"):
        for key, value in request.FILES.iteritems():
            request_info['FILES'][key] = format(value)
    if hasattr(request, "COOKIES"):
        for key, value in request.COOKIES.iteritems():
            request_info['COOKIES'][key] = format(value)
    if hasattr(request, "META"):
        for key, value in request.META.iteritems():
            request_info['META'][key] = format(value)
    settings_info = {}
    for key, value in ctx['settings'].iteritems():
        settings_info[key] = format(value)

    ctx['errorid'] = errorid = uuid.uuid4().hex

    full_info = dict(__time=datetime.datetime.now().isoformat(),
                     __uuid=errorid,
                     settings=settings_info,
                     request=request_info,
                     traceback=exception_info,
                     stack=traceback.format_exc(exc_info[2]),
                     last_frame=last_frame,
                     template_loaders=loaders,
                     template_errors=template_errors,
                     unicode_hint=unicdoe_hint,
                     exception_type=exception_type,
                     exception_value=exception_value,
                     django_version=django_version,
                     python_version=python_version,
                     python_executable=python_executable,
                     python_path=python_path,
                     server_time=server_time)

    return (errorid, ctx, full_info)
Ejemplo n.º 10
0
    def log_event(cls, request, response=None, exception=None):
        from django.views.debug import ExceptionReporter

        stack_info = {}
        if exception:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            summary = "{0}: {1}".format(exception.__class__.__name__, unicode(exception))
            lineno = traceback.tb_lineno(exc_traceback)

            stack = traceback.extract_tb(exc_traceback)
            unique_path = "|".join(line[0] for line in stack)
            path = stack[-1][0]

            try:
                reporter = ExceptionReporter(request, is_email=False, *(exc_type, exc_value, exc_traceback))
                django_data = reporter.get_traceback_data()

                stack_info["frames"] = django_data.get("frames", [])

                #Traceback objects aren't JSON serializable, so delete them
                for frame in stack_info["frames"]:
                    if "tb" in frame:
                        del frame["tb"]

                stack_info["lastframe"] = django_data.get("lastframe", {})
            except Exception:
                logging.exception("Unable to get html traceback info for some reason")
            level = EVENT_LEVEL_ERROR

        else:
            summary = u"{0} at {1}".format(response.status_code, request.path)
            lineno = 0
            path = "?".join([request.path, request.META.get('QUERY_STRING')])
            unique_path = path
            exception = HttpResponse()
            level = EVENT_LEVEL_WARNING if response.status_code == 404 else EVENT_LEVEL_INFO

        exception_name = exception.__class__.__name__

        # unique_path is either the full URL or the combined paths from the
        # entire stack trace.
        path_hash = Error.hash_for_file_path(unique_path)

        error, created = Error.objects.get_or_create(
            exception_class_name=exception_name,
            hashed_file_path=path_hash,
            line_number=lineno,
            defaults={
                'file_path': path,
                'level': level,
                'summary': summary
            }
        )

        @atomic(xg=True)
        def txn(_error):
            _error = Error.objects.get(pk=_error.pk)

            event = Event.objects.create(
                error=_error,
                request_repr=repr(request).strip(),
                request_method=request.method,
                request_url=request.build_absolute_uri(),
                request_querystring=request.META['QUERY_STRING'],
                logged_in_user_email=getattr(getattr(request, "user", None), "email", ""),
                stack_info_json=json.dumps(stack_info),
                app_version=os.environ.get('CURRENT_VERSION_ID', 'Unknown'),
                request_json=construct_request_json(request)
            )

            _error.last_event = timezone.now()
            _error.event_count += 1
            _error.save()
            return event

        to_sleep = 1
        while True:
            try:
                return txn(error)
            except TransactionFailedError:
                time.sleep(to_sleep)
                to_sleep *= 2
                to_sleep = min(to_sleep, 8)
                continue
Ejemplo n.º 11
0
    def log_event(cls, request, response=None, exception=None):
        from django.views.debug import ExceptionReporter

        stack_info = {}
        if exception:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            summary = "{0}: {1}".format(exception.__class__.__name__, unicode(exception))
            lineno = traceback.tb_lineno(exc_traceback)

            stack = traceback.extract_tb(exc_traceback)
            unique_path = "|".join(line[0] for line in stack)
            path = stack[-1][0]

            try:
                reporter = ExceptionReporter(request, is_email=False, *(exc_type, exc_value, exc_traceback))
                django_data = reporter.get_traceback_data()

                stack_info["frames"] = django_data.get("frames", [])

                #Traceback objects aren't JSON serializable, so delete them
                for frame in stack_info["frames"]:
                    if "tb" in frame:
                        del frame["tb"]

                stack_info["lastframe"] = django_data.get("lastframe", {})
            except Exception:
                logging.exception("Unable to get html traceback info for some reason")
            level = EVENT_LEVEL_ERROR

        else:
            summary = "{0} at {1}".format(response.status_code, request.path)
            lineno = 0
            path = "?".join([request.path, request.META.get('QUERY_STRING')])
            unique_path = path
            exception = HttpResponse()
            level = EVENT_LEVEL_WARNING if response.status_code == 404 else EVENT_LEVEL_INFO

        exception_name = exception.__class__.__name__

        # unique_path is either the full URL or the combined paths from the
        # entire stack trace.
        path_hash = Error.hash_for_file_path(unique_path)

        #We try to get from the cache first because on the App Engine datastore
        #we'll get screwed by eventual consistency otherwise
        CACHE_KEY = "|".join([exception_name, path_hash, str(lineno)])
        error = cache.get(CACHE_KEY)
        if error:
            created = False
        else:
            try:
                error, created = Error.objects.get_or_create(
                    exception_class_name=exception_name,
                    hashed_file_path=path_hash,
                    line_number=lineno,
                    defaults={
                        'file_path': path,
                        'level': level,
                        'summary': summary,
                        'exception_class_name': exception.__class__.__name__ if exception else ""
                    }
                )
            except MultipleObjectsReturned:
                #FIXME: Temporary hack for App Engine If we created dupes, this de-dupes them
                errors = Error.objects.filter(exception_class_name=exception_name, hashed_file_path=path_hash, line_number=lineno).all()

                max_errors = 0
                to_keep = None
                to_remove = []
                for error in errors:
                    num_events = error.events.count()
                    if max_errors < num_events:
                        # Store the error with the most events
                        to_keep = error
                        max_errors = num_events
                    else:
                        #this error doesn't have the most events, so mark it for removal
                        to_remove.append(error)

                assert to_keep

                logging.warning("Removing {} duplicate errors".format(len(to_remove)))
                for error in to_remove:
                    error.events.all().update(error=to_keep)
                    error.delete()

                error = to_keep

            cache.set(CACHE_KEY, error)

        @db.transactional(xg=True)
        def txn(_error):
            _error = Error.objects.get(pk=_error.pk)

            event = Event.objects.create(
                error=_error,
                request_repr=repr(request).strip(),
                request_method=request.method,
                request_url=request.build_absolute_uri(),
                request_querystring=request.META['QUERY_STRING'],
                logged_in_user_email=getattr(getattr(request, "user", None), "email", ""),
                stack_info_json=json.dumps(stack_info),
                app_version=os.environ.get('CURRENT_VERSION_ID', 'Unknown'),
                request_json=construct_request_json(request)
            )

            _error.last_event = timezone.now()
            _error.event_count += 1
            _error.save()
            return event

        return txn(error)
Ejemplo n.º 12
0
    def emit(self, record):
        if not switch_is_active("LOG_TO_DISCORD"):
            return

        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 = subject.replace("\n", "\\n").replace("\r", "\\r")

        if record.exc_info:
            exc_info = record.exc_info
        else:
            exc_info = (None, record.getMessage(), None)

        reporter = ExceptionReporter(request, *exc_info)
        data = reporter.get_traceback_data()

        location = f" at {request.path_info}" if request else ""
        heading = f"{data.get('exception_type', 'Report')}{location}"
        exception_value = data.get("exception_value",
                                   "No exception message supplied")
        fields = [
            {
                "name": "Subject",
                "value": subject,
                "inline": True
            },
            {
                "name": heading,
                "value": exception_value,
                "inline": False
            },
        ]

        if request:
            if request.GET != {}:
                fields.append({
                    "name": "GET parameters",
                    "value": str(dict(request.GET)),
                    "inline": False,
                })
            if request.POST != {}:
                fields.append({
                    "name": "POST parameters",
                    "value": str(dict(request.POST)),
                    "inline": False,
                })

        json = {
            "embeds": [{
                "title": "SC2 Ladder Exception",
                "fields": fields,
                "footer": {
                    "text": ""
                },
            }]
        }

        requests.post(settings.DISCORD_WEBHOOK, json=json)
Ejemplo n.º 13
0
    def formatException(self, exc_info, request=None):
        #pylint:disable=too-many-locals,arguments-differ
        reporter = ExceptionReporter(request, is_email=True, *exc_info)
        traceback_data = reporter.get_traceback_data()
        filtered_traceback_data = {}

        if request:
            request_dict = {
                'http_method': request.method,
                'http_path': request.path_info}
            params = {}
            for key, val in six.iteritems(request.GET):
                params.update({key: val})
            if params:
                request_dict.update({'GET': params})
            params = {}
            for key, val in six.iteritems(request.POST):
                params.update({key: val})
            if params:
                request_dict.update({'POST': params})
            params = {}
            for key, val in six.iteritems(request.FILES):
                params.update({key: val})
            if params:
                request_dict.update({'FILES': params})
            params = {}
            for key, val in six.iteritems(request.COOKIES):
                params.update({key: val})
            if params:
                request_dict.update({'COOKIES': params})
            params = {}
            for key in self.whitelists.get('meta', []):
                value = request.META.get(key, None)
                if value is not None:
                    params.update({key: value})
            if params:
                request_dict.update({'META': params})
            filtered_traceback_data.update({'request_data': request_dict})

        for frame in traceback_data.get('frames', []):
            frame.pop('tb', None)

        for key in self.whitelists.get('traceback', []):
            value = traceback_data.get(key, None)
            if value is not None:
                if key == 'settings':
                    value = {}
                    for settings_key in self.whitelists.get(key, []):
                        settings_value = traceback_data[key].get(
                            settings_key, None)
                        if settings_value is not None:
                            value.update({settings_key: settings_value})
                if key == 'frames':
                    frames = value
                    value = [] #pylint:disable=redefined-variable-type
                    for frame in frames:
                        frame_dict = {}
                        for frame_key, frame_val in six.iteritems(frame):
                            frame_dict.update({frame_key: str(frame_val)})
                        value += [frame_dict]
                filtered_traceback_data.update({key: value})

        # Pip packages
        installed_packages = get_installed_distributions(local_only=False)
        filtered_traceback_data.update({
            'installed_packages':
            [{'name': package.project_name,
              'version': package.version,
              'location': package.location}
             for package in installed_packages]
        })

        return filtered_traceback_data