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('<', '<') .replace('>', '>') .replace('"', '"') .replace("'", '\'') ) 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('&', '&').replace( '<', '<').replace('>', '>').replace('"', '"').replace("'", '\'')) 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 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)
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
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)
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)
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)
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
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)
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
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)
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)
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