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)
示例#3
0
    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})
示例#4
0
 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)
示例#5
0
    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
            })
示例#6
0
		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()
示例#7
0
        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()
示例#8
0
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()
示例#10
0
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