예제 #1
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)
                sentry.user_context({
                    "aws_log_group_name": context.log_group_name,
                    "aws_log_stream_name": context.log_stream_name,
                    "aws_function_name": context.function_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.db import connection
                connection.close()
예제 #2
0
    def handle(self, *args, **options):
        task_name = self.get_task_name(options)

        try:
            start_time = time.time()
            self.run_task(options)

            runtime = round(time.time() - start_time, 2)

            # Monitor duration of the task
            logger.info("Task " + task_name + " executed in " + str(runtime) +
                        "s",
                        extra={
                            'task': task_name,
                            'success': True,
                            'runtime': runtime
                        })

        except Exception as error:
            if not settings.DEBUG:
                # Say if PROD or PRE-PROD and report to sentry a problem has been detected
                client.user_context({'prod_status': settings.PROD_STATUS})
                client.captureException()

                # Log the error
                logger.error("Task " + task_name + " failed",
                             extra={
                                 'task': task_name,
                                 'success': False
                             })
            else:
                raise error
예제 #3
0
def fetch(site):
    highlights = []
    fetcher = FETCHERS.get(site)

    if not fetcher:
        raise Exception("Fetcher for " + site + " does not exists!")

    num_pagelet = fetcher['num_pagelet']
    max_days_ago = fetcher['max_days_ago']

    try:
        highlights += fetcher['fetch'](num_pagelet=num_pagelet,
                                       max_days_ago=max_days_ago)

    except:
        # Say which fetcher failed and the prod status
        client.user_context({
            'prod_status': settings.PROD_STATUS,
            'highlights_fetcher': site
        })
        # Report to sentry problem detected
        client.captureException()

        logger.error("Error while fetching for " + str(site))

    # Update scrapping status in database
    scrapping_status_manager.update_scrapping_status(site, bool(highlights))

    # Tell sentry scrapping problem occurred
    if not highlights:
        raise ScrappingException("Failed to scrape " + site)

    return highlights
예제 #4
0
		def wrapper(event, context):
			tracing_id = get_tracing_id(event)
			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.
				sentry.user_context({
					"aws_log_group_name": getattr(context, "log_group_name"),
					"aws_log_stream_name": getattr(context, "log_stream_name"),
					"aws_function_name": getattr(context, "function_name"),
					"tracing_id": tracing_id
				})

			try:
				measurement = "%s_duration_ms" % (func.__name__)
				with influx_timer(measurement, timestamp=now()):
					return func(event, context)

			except Exception as e:
				logger.exception("Got an exception: %r", e)
				if sentry:
					logger.info("Inside sentry capture block.")
					sentry.captureException()
				else:
					logger.info("Sentry is not available.")
				raise
			finally:
				from django.db import connection
				connection.close()
예제 #5
0
    def process_exception(self, request, exception):
        id = HighlightsBotView.LATEST_SENDER_ID
        send_error_message(id)

        # Make sure the exception signal is fired for Sentry
        client.user_context({'user_id': id})
        got_request_exception.send(sender=self, request=request)

        return HttpResponse()
예제 #6
0
 def send_update_error_to_sentry(user, api_response):
     # This is needed to not include POST data (e.g. binary image), which
     # was causing sentry to fail at sending
     sentry_client.context.clear()
     sentry_client.user_context(
         {'hashed_uuid': user.hashed_uuid, 'user_email': user.email}
     )
     sentry_client.captureMessage(
         message='Updating company profile failed',
         data={},
         extra={'api_response': str(api_response.content)}
     )
예제 #7
0
    def wrapper(*args, **kwargs):
        if len(args) != 2:
            msg = "@lambda_handler must wrap functions with two arguments. E.g. handler(event, context)"
            raise ValueError(msg)

        event = args[0]
        context = args[1]
        if not hasattr(context, "log_group_name"):
            msg = "@lambda_handler has been used with a function whose second argument is not a context object."
            raise ValueError(msg)

        tracing_id = get_tracing_id(event, context)
        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.
            sentry.user_context({
                "aws_log_group_name":
                getattr(context, "log_group_name"),
                "aws_log_stream_name":
                getattr(context, "log_stream_name"),
                "aws_function_name":
                getattr(context, "function_name"),
                "tracing_id":
                tracing_id
            })

        try:
            measurement = "%s_duration_ms" % func.__name__
            handler_start = now()
            with influx_timer(
                    measurement,
                    timestamp=handler_start,
                    is_running_as_lambda=settings.IS_RUNNING_AS_LAMBDA):

                return func(*args, **kwargs)

        except Exception as e:
            logger.exception("Got an exception: %r", e)
            if sentry:
                logger.info("Inside sentry capture block.")
                sentry.captureException()
            else:
                logger.info("Sentry is not available.")
            raise
        finally:
            from django.db import connection
            connection.close()
예제 #8
0
    def process_exception(self, request, exception):
        id = HighlightsBotView.LATEST_SENDER_ID
        manager_response.send_error_message(id)

        # Make sure the exception signal is fired for Sentry
        client.user_context({'user_id': id})
        got_request_exception.send(sender=self, request=request)

        # Log the error
        logger.error("An error occurred: " + str(exception),
                     extra={
                         'user_id': id,
                         'method': request.method,
                         'full_path': request.get_full_path()
                     })

        return HttpResponse()
예제 #9
0
 def handle(self, *args, **options):
     try:
         start_time = time.time()
         self.run_task()
         # Monitor duration of the task
         logger.log("Task " + str(self.get_task_name()) + " executed in " +
                    str(round(time.time() - start_time, 2)) + "s",
                    forward=True)
     except Exception as error:
         if not settings.DEBUG:
             # Say if PROD or PRE-PROD
             client.user_context({'prod_status': settings.PROD_STATUS})
             # Report to sentry if problem detected
             client.captureException()
             # Report task had a problem
             logger.log("Task " + str(self.get_task_name()) + " failed",
                        forward=True)
         else:
             raise error
예제 #10
0
	def wrapper(*args, **kwargs):
		if len(args) != 2:
			msg = "@lambda_handler must wrap functions with two arguments. E.g. handler(event, context)"
			raise ValueError(msg)

		event = args[0]
		context = args[1]
		if not hasattr(context, "log_group_name"):
			msg = "@lambda_handler has been used with a function whose second argument is not a context object."
			raise ValueError(msg)

		tracing_id = get_tracing_id(event, context)
		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.
			sentry.user_context({
				"aws_log_group_name": getattr(context, "log_group_name"),
				"aws_log_stream_name": getattr(context, "log_stream_name"),
				"aws_function_name": getattr(context, "function_name"),
				"tracing_id": tracing_id
			})

		try:
			measurement = "%s_duration_ms" % func.__name__
			handler_start = now()
			with influx_timer(measurement,
							  timestamp=handler_start,
							  is_running_as_lambda=settings.IS_RUNNING_AS_LAMBDA):

				return func(*args, **kwargs)

		except Exception as e:
			logger.exception("Got an exception: %r", e)
			if sentry:
				logger.info("Inside sentry capture block.")
				sentry.captureException()
			else:
				logger.info("Sentry is not available.")
			raise
		finally:
			from django.db import connection
			connection.close()
		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
				)
				sentry.user_context({
					"aws_log_group_name": context.log_group_name,
					"aws_log_stream_name": context.log_stream_name,
					"aws_function_name": context.function_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.db import connection
				connection.close()
예제 #12
0
def post(url, params):
    """
    Make a POST request to the URL using the key-value pairs.  Return
    a set of key-value pairs.

    :url: URL to post to
    :params: Dict of parameters to include in post payload
    """
    payload = urlencode(params)
    start_time = time.time()
    response = requests.post(
        url,
        payload,
        headers={'content-type': 'text/namevalue; charset=utf-8'})
    if response.status_code != requests.codes.ok:
        raise exceptions.PayPalError("Unable to communicate with PayPal")

    # Convert response into a simple key-value format
    try:
        pairs = {}
        for key, value in parse_qsl(response.content):
            if isinstance(key, six.binary_type):
                key = key.decode('utf8')
            if isinstance(value, six.binary_type):
                value = value.decode('utf8')
            pairs[key] = value
    except Exception:
        client.user_context({'context': response.content})
        client.captureException()
        raise exceptions.PayPalError("There was an error with PayPal")

    # Add audit information
    pairs['_raw_request'] = payload
    pairs['_raw_response'] = response.content
    pairs['_response_time'] = (time.time() - start_time) * 1000.0

    return pairs
예제 #13
0
def post(url, params):
    """
    Make a POST request to the URL using the key-value pairs.  Return
    a set of key-value pairs.

    :url: URL to post to
    :params: Dict of parameters to include in post payload
    """
    payload = urlencode(params)
    start_time = time.time()
    response = requests.post(
        url, payload,
        headers={'content-type': 'text/namevalue; charset=utf-8'})
    if response.status_code != requests.codes.ok:
        raise exceptions.PayPalError("Unable to communicate with PayPal")

    # Convert response into a simple key-value format
    try:
        pairs = {}
        for key, value in parse_qsl(response.content):
            if isinstance(key, six.binary_type):
                key = key.decode('utf8')
            if isinstance(value, six.binary_type):
                value = value.decode('utf8')
            pairs[key] = value
    except Exception:
        client.user_context({'context': response.content})
        client.captureException()
        raise exceptions.PayPalError("There was an error with PayPal")

    # Add audit information
    pairs['_raw_request'] = payload
    pairs['_raw_response'] = response.content
    pairs['_response_time'] = (time.time() - start_time) * 1000.0

    return pairs
예제 #14
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