def test_tags_from_returns_empty_list_on_no_match(self):
        # arrange kwargs
        my_kwargs = {
            "message": {
                "payload": {}
            },
            "another_message": {
                "payload": {}
            }
        }

        # act
        tags = Resolver.resolve_tags_from(tags_from=None, **my_kwargs)
        # assert
        self.assertEqual(tags, [])

        # act
        tags = Resolver.resolve_tags_from(tags_from={
            "message": None,
            "another_message": None
        },
                                          **my_kwargs)
        # assert
        self.assertEqual(tags, [])

        # act
        tags = Resolver.resolve_tags_from(tags_from={
            "message": [],
            "another_message": []
        },
                                          **my_kwargs)
        # assert
        self.assertEqual(tags, [])

        # act
        tags = Resolver.resolve_tags_from(tags_from={
            "message": [None, "adsad", [], {}],
            "another_message": [None, "adsad", [], {}]
        },
                                          **my_kwargs)
        # assert
        self.assertEqual(tags, [])

        # act
        tags = Resolver.resolve_tags_from(tags_from={
            "message": ["type", "schema"],
            "another_message": ["type", "schema"]
        },
                                          **my_kwargs)
        # assert
        self.assertEqual(tags, [])
    def test_tags_from_returns_tags_from_message_and_another_message(self):
        # arrange kwargs
        my_kwargs = {
            "message": {
                "type": "this_is_the_event_type_from_message",
                "schema": "this_is_the_event_schema_from_message",
                "payload": {}
            },
            "another_message": {
                "type": "this_is_the_event_type_from_another_message",
                "schema": "this_is_the_event_schema_from_another_message",
                "payload": {}
            }
        }

        # act
        tags = Resolver.resolve_tags_from(tags_from={
            "message": ["type", "schema"],
            "another_message": ["type", "schema"]
        },
                                          **my_kwargs)
        # assert
        self.assertEqual(tags, [
            "type:this_is_the_event_type_from_message",
            "schema:this_is_the_event_schema_from_message",
            "type:this_is_the_event_type_from_another_message",
            "schema:this_is_the_event_schema_from_another_message"
        ])
    def test_trace_id_returns_value(self):

        kwargs = {"message": {"eventId": "aaaa-1111-bbbb-2222-cccc"}}

        trace_id = Resolver.resolve_trace_id(
            trace_id_from={"message": "eventId"}, **kwargs)
        self.assertEqual(trace_id, "aaaa-1111-bbbb-2222-cccc")
    def test_tags_from_returns_tags_from_message_no_payload_of_message(self):
        """This tests that even if the user requests tags from the payload, it still just resolves the first level tags.
        Note:
            This can be implemented later if desired.
        """
        # arrange kwargs
        my_kwargs = {
            "message": {
                "type": "this_is_the_event_type_from_message",
                "schema": "this_is_the_event_schema_from_message",
                "payload": {
                    "name": "observe"
                }
            }
        }

        # act
        tags = Resolver.resolve_tags_from(
            tags_from={"message": ["type", "schema", {
                "payload": ["name"]
            }]},
            **my_kwargs)
        # assert
        self.assertEqual(tags, [
            "type:this_is_the_event_type_from_message",
            "schema:this_is_the_event_schema_from_message"
        ])
 def test_tags_from_returns_empty_list_on_tag_value_not_string(self):
     # arrange kwargs
     my_kwargs = {"message": {"type": 1234}}
     # act
     tags = Resolver.resolve_tags_from(tags_from={"message": ["type"]},
                                       **my_kwargs)
     # assert
     self.assertEqual(tags, [])
 def test_tags_from_returns_empty_list_on_message_not_dict(self):
     # arrange kwargs
     my_kwargs = {"message": "type"}
     # act
     tags = Resolver.resolve_tags_from(
         tags_from={"message": ["type", "schema"]}, **my_kwargs)
     # assert
     self.assertEqual(tags, [])
 def test_threshold_1800001ms(self):
     """This tests that the last value of the threshold map is returns correctly.
     """
     # arrange
     process_time = 1800001
     # act
     tag = Resolver.resolve_observed_sli_tag(process_time=process_time)
     # assert
     self.assertEqual(tag, "observed_sli:OVER_30min")
 def test_threshold_100ms(self):
     """This tests that the first value of the threshold map is returned correctly, at the edge to the second value.
     """
     # arrange
     process_time = 100
     # act
     tag = Resolver.resolve_observed_sli_tag(process_time=process_time)
     # assert
     self.assertEqual(tag, "observed_sli:100ms")
    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()")
    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()")
    def test_tags_from_returns_tags_from_message_type_only(self):
        # arrange kwargs
        my_kwargs = {
            "message": {
                "type": "this_is_the_event_type_from_message"
            }
        }

        # act
        tags = Resolver.resolve_tags_from(
            tags_from={"message": ["type", "schema"]}, **my_kwargs)
        # assert
        self.assertEqual(tags, ["type:this_is_the_event_type_from_message"])
    def test_tags_from_returns_empty_list_on_no_kwargs(self):
        # act
        tags = Resolver.resolve_tags_from(tags_from=None)
        # assert
        self.assertEqual(tags, [])

        # act
        tags = Resolver.resolve_tags_from(tags_from={
            "message": None,
            "another_message": None
        })
        # assert
        self.assertEqual(tags, [])

        # act
        tags = Resolver.resolve_tags_from(tags_from={
            "message": [],
            "another_message": []
        })
        # assert
        self.assertEqual(tags, [])

        # act
        tags = Resolver.resolve_tags_from(
            tags_from={
                "message": [None, "adsad", [], {}],
                "another_message": [None, "adsad", [], {}]
            })
        # assert
        self.assertEqual(tags, [])

        # act
        tags = Resolver.resolve_tags_from(tags_from={
            "message": ["type", "schema"],
            "another_message": ["type", "schema"]
        })
        # assert
        self.assertEqual(tags, [])
    def test_threshold_map(self):
        """This tests the whole algorithm to obtain tags, excluding last value.
        """
        timings = list(observe_threshold_map.keys())
        expected_tags = list(observe_threshold_map.values())
        for i, process_time in enumerate(timings):
            tag = Resolver.resolve_observed_sli_tag(process_time=process_time)

            if i == 0:
                self.assertEqual(tag, "observed_sli:%s" % (expected_tags[i]))
            else:
                # return always the last value of the current match
                self.assertEqual(tag,
                                 "observed_sli:%s" % (expected_tags[i - 1]))
    def test_trace_id_returns_empty_string(self):

        trace_id = Resolver.resolve_trace_id(trace_id_from=None)
        self.assertEqual(trace_id, "")

        trace_id = Resolver.resolve_trace_id(trace_id_from=1337)
        self.assertEqual(trace_id, "")

        trace_id = Resolver.resolve_trace_id(trace_id_from="")
        self.assertEqual(trace_id, "")

        trace_id = Resolver.resolve_trace_id(trace_id_from={})
        self.assertEqual(trace_id, "")

        trace_id = Resolver.resolve_trace_id(trace_id_from=[])
        self.assertEqual(trace_id, "")

        trace_id = Resolver.resolve_trace_id(
            trace_id_from={"message": "eventId"})
        self.assertEqual(trace_id, "")
 def test_identity_default(self):
     # act
     identity = Resolver.resolve_identity(func=None, trace_id="abcd")
     # assert
     self.assertEqual(identity, "observe(abcd)")
Exemple #16
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