Ejemplo n.º 1
0
    def test_identity_from_function(self):
        # arrange args
        def process_function():
            pass

        # act
        identity = Resolver.resolve_identity(func=process_function)
        # assert
        self.assertEqual(identity, "process_function()")
Ejemplo n.º 2
0
    def test_identity_from_class(self):
        # arrange
        class MainProcess:
            def start(self):
                pass

        # act
        identity = Resolver.resolve_identity(MainProcess(), func=None)
        # assert
        self.assertEqual(identity, "MainProcess()")
Ejemplo n.º 3
0
 def test_identity_default(self):
     # act
     identity = Resolver.resolve_identity(func=None, trace_id="abcd")
     # assert
     self.assertEqual(identity, "observe(abcd)")
Ejemplo n.º 4
0
        def inner(*args: Any, **kwargs: Any) -> Any:

            # setup tracing and tags
            trace_id = Resolver.resolve_trace_id(trace_id_from=trace_id_from,
                                                 **kwargs)
            identity = Resolver.resolve_identity(*args,
                                                 func=func,
                                                 trace_id=trace_id)
            additional_tags = Resolver.resolve_tags_from(tags_from=tags_from,
                                                         **kwargs)
            all_tags = additional_tags + static_tags

            imetric = Provider.get_metric(*args)

            # start timing
            time_start: float = time.monotonic()

            try:
                # actual function execution
                response: Any = func(*args, **kwargs)

                # calculate process time
                process_time = int(time.monotonic() - time_start) * 1000
                # append extra tags
                all_tags.append(
                    Resolver.resolve_observed_sli_tag(
                        process_time=process_time))

                # send metrics, finished successfully
                imetric.timing("%s.time.finished" % metric, process_time,
                               all_tags)
                imetric.gauge("%s.time_gauge.finished" % metric, process_time,
                              all_tags)
                imetric.increment("%s.finished" % metric, 1, all_tags)

            except Exception as ex:
                # calculate process time
                process_time = int(time.monotonic() - time_start) * 1000
                # append extra tags
                all_tags.append('exception:%s' % type(ex).__name__)
                all_tags.append(
                    Resolver.resolve_observed_sli_tag(
                        process_time=process_time))

                # accept on, returns True
                if type(ex) in accept_on:
                    # log warning
                    Provider.get_logger(*args).warning(
                        "%s: %s(%s) during '%s' accepted.\n%s" %
                        (identity, type(ex).__name__, ex, func.__name__,
                         traceback.format_exc()))
                    # send metrics, raised but accepted
                    imetric.timing("%s.time.accepted" % metric, process_time,
                                   all_tags)
                    imetric.gauge("%s.time_gauge.accepted" % metric,
                                  process_time, all_tags)
                    imetric.increment('%s.exception.accepted' % metric, 1,
                                      all_tags)
                    # return truthy, to be acknowledged
                    return True

                # decline on, returns False
                if type(ex) in decline_on:
                    # log error
                    Provider.get_logger(*args).error(
                        "%s: %s(%s) during '%s' declined.\n%s" %
                        (identity, type(ex).__name__, ex, func.__name__,
                         traceback.format_exc()))
                    # send metrics, raised but declined
                    imetric.timing("%s.time.declined" % metric, process_time,
                                   all_tags)
                    imetric.gauge("%s.time_gauge.declined" % metric,
                                  process_time, all_tags)
                    imetric.increment('%s.exception.declined' % metric, 1,
                                      all_tags)
                    # return falsy, not to be acknowledged
                    return False

                # unhandled exception, log error
                Provider.get_logger(*args).error(
                    "%s: %s(%s) during '%s' raised.\n%s" %
                    (identity, type(ex).__name__, ex, func.__name__,
                     traceback.format_exc()))

                # send metrics, raised and unhandled
                imetric.timing("%s.time.raised" % metric, process_time,
                               all_tags)
                imetric.gauge("%s.time_gauge.raised" % metric, process_time,
                              all_tags)
                imetric.increment('%s.exception.raised' % metric, 1, all_tags)

                # check if notification client available
                slack = Provider.get_slack(*args)
                if slack:
                    # notify
                    slack.error(header=identity,
                                title=type(ex).__name__,
                                text=f"{ex}\n{traceback.format_exc()}")
                # re-raise
                raise ex

            finally:
                # send metric, start
                imetric.increment("%s.start" % metric, 1, all_tags)

            # return actual response of the function
            return response