def log_user_data(context_data, extra_data=None): """ Push extra user data into sentry for debugging purposes """ def _get_key(func, cdata): try: return func(cdata) except KeyError: return "undefined" extra_data = extra_data or {} # record pertinent debugging data whilst discarding anything # that is potentially sensitive data = { "urn": _get_key(lambda x: x["case"]["urn"], context_data), "notice_type": _get_key(lambda x: x["notice_type"]["sjp"], context_data), "doh": _get_key(lambda x: x["case"]["date_of_hearing"], context_data), "posting_date": _get_key(lambda x: x["case"]["posting_date"], context_data), "plea_made_by": _get_key(lambda x: x["case"]["plea_made_by"], context_data), "dx": _get_key(lambda x: x["dx"], context_data) } data.update(extra_data) client.extra_context(data)
def log_user_data(context_data, extra_data=None): """ Push extra user data into sentry for debugging purposes """ def _get_key(func, cdata): try: return func(cdata) except KeyError: return "undefined" extra_data = extra_data or {} # record pertinent debugging data whilst discarding anything # that is potentially sensitive data = { "urn": _get_key(lambda x: x["case"]["urn"], context_data), "notice_type": _get_key(lambda x: x["notice_type"]["sjp"], context_data), "doh": _get_key(lambda x: x["case"]["date_of_hearing"], context_data), "posting_date": _get_key(lambda x: x["case"]["posting_date"], context_data), "plea_made_by": _get_key(lambda x: x["case"]["plea_made_by"], context_data), "dx": _get_key(lambda x: x["dx"], context_data) } data.update(extra_data) client.extra_context(data)
def process_view(self, request, view_func, view_args, view_kwargs): from raven.contrib.django.raven_compat.models import client if getattr(request, 'couch_user', None): client.extra_context({'couch_user_id': request.couch_user.get_id}) if getattr(request, 'domain', None): client.tags_context({'domain': request.domain})
def send_messages(self, messages): """ Sends one or more SmsMessage objects and returns the number of messages sent """ for message in messages: try: sender = message.from_phone or self.sender logger.debug( "Executing JustSend API. Sending {count} messages " "from {sender}".format(count=len(message.to), sender=sender)) request_json = { "from": sender, "to": message.to[0], "message": message.body, "bulkVariant": self.bulk_variant } response = requests.post(url=self.url.format(key=self.api_key), json=request_json) logger.debug( "Executed JustSend API. Result: {response}".format( response=response)) if response.status_code != 200: if self.fail_silently: logger.error( "JustSend API request failed", extra={ 'stack': True, 'response_text': response.text, }, ) else: client.extra_context({ 'stack': True, 'request_json': request_json, 'reponse_text': response.text, }) raise Exception("Error invoking JustSend API") else: result = response.json() if result['responseCode'] != 'OK': if self.fail_silently: logger.error("Sending SMS via JustSend API failed", extra={ 'stack': True, }) else: client.extra_context({ 'reponse_text': response.text, }) raise Exception( "Error sending SMS using JustSend API") except Exception as e: if not self.fail_silently: raise return len(messages)
def process_view(self, request, view_func, view_args, view_kwargs): from raven.contrib.django.raven_compat.models import client if getattr(request, 'couch_user', None): client.extra_context({ 'couch_user_id': request.couch_user.get_id }) if getattr(request, 'domain', None): client.tags_context({ 'domain': request.domain })
def wrapper(event, context): tracing_id = get_tracing_id(event) if tracing else "" os.environ["TRACING_REQUEST_ID"] = tracing_id if sentry: # Provide additional metadata to sentry in case the exception # gets trapped and reported within the function. cloudwatch_url = build_cloudwatch_url( context.log_group_name, context.log_stream_name ) # Tags context can be used to group exceptions sentry.tags_context({ "aws_function_name": context.function_name }) # Extra context is just attached to the exception in Sentry sentry.extra_context({ "aws_log_group_name": context.log_group_name, "aws_log_stream_name": context.log_stream_name, "aws_cloudwatch_url": cloudwatch_url, "admin_url": build_admin_url(tracing_id), "tracing_id": tracing_id }) try: measurement = "%s_duration_ms" % (func.__name__) with influx_timer( measurement, timestamp=now(), cloudwatch_url=cloudwatch_url ): return func(event, context) except Exception as e: log.exception("Got an exception: %r", e) if sentry: sentry.captureException() else: log.info("Sentry is not available.") if not trap_exceptions: raise finally: from django import db db.connections.close_all()
def wrapper(event, context): cloudwatch_url = get_cloudwatch_url(context) # Provide additional metadata to sentry in case the exception # gets trapped and reported within the function. # Tags context can be used to group exceptions sentry.tags_context({"aws_function_name": context.function_name}) # Extra context is just attached to the exception in Sentry extra_context = { "aws_log_group_name": context.log_group_name, "aws_log_stream_name": context.log_stream_name, "aws_cloudwatch_url": get_cloudwatch_url(context), "event": event, } if tracing: extra_context["shortid"] = get_shortid(event) extra_context[ "upload_url"] = "https://hsreplay.net/uploads/upload/%s/" % ( extra_context["shortid"]) sentry.extra_context(extra_context) try: measurement = "%s_duration_ms" % (func.__name__) with influx_timer(measurement, timestamp=now(), cloudwatch_url=cloudwatch_url): return func(event, context) except Exception as e: log.exception("Got an exception: %r", e) sentry.captureException() if not trap_exceptions: raise finally: from django import db db.connections.close_all()
def _notify_multiple_devices(**kwargs): """ Send a message to multiple devices. A simple wrapper of pyfcm's notify_multiple_devices. See https://github.com/olucurious/PyFCM/blob/master/pyfcm/fcm.py for more details on options, etc. """ if fcm is None: return 0, 0 response = fcm.notify_multiple_devices(**kwargs) sentry_client.extra_context(response) tokens = kwargs.get('registration_ids', []) # check for invalid tokens and remove any corresponding push subscriptions indexed_results = list(enumerate(response['results'])) cleanup_tokens = [ tokens[i] for (i, result) in indexed_results if result.get('error') in ('InvalidRegistration', 'NotRegistered', 'MismatchSenderId', 'InvalidApnsCredential') ] if len(cleanup_tokens) > 0: PushSubscription.objects.filter(token__in=cleanup_tokens).delete() success_indices = [i for (i, result) in indexed_results if 'error' not in result] failure_indices = [i for (i, result) in indexed_results if 'error' in result] # tell Sentry if there were errors if len(failure_indices) > 0: sentry_client.captureMessage('FCM error while sending', extra=response) logger.warning( 'FCM error while sending: {} tokens successful, {} failed, {} removed from database'.format( len(success_indices), len(failure_indices), len(cleanup_tokens) ) ) return success_indices, failure_indices
def wrapper(event, context): tracing_id = get_tracing_id(event) if tracing else "" os.environ["TRACING_REQUEST_ID"] = tracing_id if sentry: # Provide additional metadata to sentry in case the exception # gets trapped and reported within the function. cloudwatch_url = build_cloudwatch_url(context.log_group_name, context.log_stream_name) # Tags context can be used to group exceptions sentry.tags_context( {"aws_function_name": context.function_name}) # Extra context is just attached to the exception in Sentry sentry.extra_context({ "aws_log_group_name": context.log_group_name, "aws_log_stream_name": context.log_stream_name, "aws_cloudwatch_url": cloudwatch_url, "admin_url": build_admin_url(tracing_id), "tracing_id": tracing_id }) try: measurement = "%s_duration_ms" % (func.__name__) with influx_timer(measurement, timestamp=now(), cloudwatch_url=cloudwatch_url): return func(event, context) except Exception as e: log.exception("Got an exception: %r", e) if sentry: sentry.captureException() else: log.info("Sentry is not available.") if not trap_exceptions: raise finally: from django import db db.connections.close_all()
def custom_exception_handler(exc, context): # First the get response by django rest framework response = exception_handler(exc, context) # For 500 errors, we create new response if not response: request = context.get('request') if request and request.user and request.user.id: sentry.user_context({ 'id': request.user.id, 'email': request.user.email, }) sentry.extra_context({ 'is_superuser': request.user.is_superuser, }) sentry.captureException() response = Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) # Empty the response body but keep the headers response.data = {} # Timestamp of exception response.data['timestamp'] = timezone.now() if hasattr(exc, 'status_code'): response.status_code = exc.status_code if hasattr(exc, 'code'): # If the raised exception defines a code, send it as # internal error code response.data['error_code'] = exc.code elif hasattr(exc, 'get_codes'): # Otherwise, try to map the exception.get_codes() value to an # internal error code. # If no internal code available, return http status code as # internal error code by default. response.data['error_code'] = map_error_codes( exc.get_codes(), response.status_code) else: response.data['error_code'] = response.status_code # Error message can be defined by the exception as message # or detail attributres # Otherwise, it is simply the stringified exception. errors = None user_error = None if hasattr(exc, 'message'): errors = exc.message elif hasattr(exc, 'detail'): errors = exc.detail elif response.status_code == 404: errors = 'Resource not found' else: errors = str(exc) user_error = standard_error_string if hasattr(exc, 'user_message'): user_error = exc.user_message # Wrap up string error inside non-field-errors if isinstance(errors, str): errors = { 'non_field_errors': [errors], } if user_error: errors['internal_non_field_errors'] = errors.get('non_field_errors') errors['non_field_errors'] = [user_error] response.data['errors'] = errors # If there is a link available for the exception, # send back the link as well. if hasattr(exc, 'link'): response.data['link'] = exc.link # Logging logger.error(traceback.format_exc()) return response