Ejemplo n.º 1
0
    def test_json_properly_serialized_when_bytes_object(self):
        # orjson
        custom_formatter = ExtendedJsonFormatter(serializer=orjson.dumps)
        # Note: json.dumps by default uses this separator (', ', ': ')
        # adding a whitespace whereas with orjson it is not
        # so to have a perfect match is it necessary to specify it
        custom_orjson_serializer_msg = custom_formatter.format(self.record)

        # json
        serialized_result = self.formatter.format(self.record)
        content = json.loads(serialized_result)
        default_json_serializer_msg = self.formatter.serializer(
            content, separators=(",", ":"))

        self.assertEqual(custom_orjson_serializer_msg,
                         default_json_serializer_msg)
Ejemplo n.º 2
0
class ExtendedJsonFormatterTests(unittest.TestCase):
    def setUp(self):
        self.formatter = ExtendedJsonFormatter()
        self.record = ExtendedLogRecord(
            level=30,
            name="aiologger",
            pathname="/aiologger/tests/formatters/test_json_formatter.py",
            func="xablaufunc",
            lineno=42,
            msg={
                "dog": "Xablau",
                "action": "bark"
            },
            exc_info=None,
            args=None,
            extra=None,
            flatten=False,
            serializer_kwargs={},
        )

    def test_it_uses_default_log_fields_if_none_are_excluded_on_initialization(
            self):
        formatter = ExtendedJsonFormatter()
        self.assertEqual(ExtendedJsonFormatter.default_fields,
                         formatter.log_fields)

    def test_default_log_fields_can_be_excluded_with_exclude_fields_initialization_argument(
            self):
        formatter = ExtendedJsonFormatter(
            exclude_fields=(LOG_LEVEL_FIELDNAME, ))
        self.assertNotIn(LOG_LEVEL_FIELDNAME, formatter.log_fields)

    def test_formatter_fields_for_record_with_default_fields(self):
        result = dict(self.formatter.formatter_fields_for_record(self.record))
        self.assertEqual(
            result,
            {
                "logged_at": ANY,
                "line_number": 42,
                "function": "xablaufunc",
                "level": "WARNING",
                "file_path":
                "/aiologger/tests/formatters/test_json_formatter.py",
            },
        )

    @freeze_time("2018-06-16T10:16:00-03:00")
    def test_formatter_with_tz_info_utc(self):
        """
        Check that, if tz is not None, log messages must have timezone info
        """
        formatter = ExtendedJsonFormatter(tz=timezone.utc)
        result = dict(formatter.formatter_fields_for_record(self.record))
        self.assertEqual(
            result,
            {
                "logged_at": "2018-06-16T13:16:00+00:00",
                "line_number": 42,
                "function": "xablaufunc",
                "level": "WARNING",
                "file_path":
                "/aiologger/tests/formatters/test_json_formatter.py",
            },
        )

    @freeze_time("2018-06-16T16:20:00+00:00")
    def test_formatter_with_tz_info_america_sao_paulo_from_utc(self):
        """
        Current time is UTC and we want logs to be generated on America/Sao_Paulo (-3)
        """
        tz_america = timezone(timedelta(hours=-3))
        formatter = ExtendedJsonFormatter(tz=tz_america)
        result = dict(formatter.formatter_fields_for_record(self.record))
        self.assertEqual(
            result,
            {
                "logged_at": "2018-06-16T13:20:00-03:00",
                "line_number": 42,
                "function": "xablaufunc",
                "level": "WARNING",
                "file_path":
                "/aiologger/tests/formatters/test_json_formatter.py",
            },
        )

    @freeze_time("2018-06-16T15:20:00-07:00")
    def test_formatter_with_tz_info_other_zone(self):
        """
        Current time is NOT UTC (is -7) and we want logs to be generate in America/Sao_Paulo (-3)
        """
        tz_america = timezone(timedelta(hours=-3))
        formatter = ExtendedJsonFormatter(tz=tz_america)
        result = dict(formatter.formatter_fields_for_record(self.record))
        self.assertEqual(
            result,
            {
                "logged_at": "2018-06-16T19:20:00-03:00",
                "line_number": 42,
                "function": "xablaufunc",
                "level": "WARNING",
                "file_path":
                "/aiologger/tests/formatters/test_json_formatter.py",
            },
        )

    def test_formatter_fields_for_record_with_excluded_fields(self):
        log_fields = {LOG_LEVEL_FIELDNAME, LINE_NUMBER_FIELDNAME}

        with patch.object(self.formatter, "log_fields", log_fields):
            result = dict(
                self.formatter.formatter_fields_for_record(self.record))
            self.assertEqual(result, {"line_number": 42, "level": "WARNING"})

    def test_default_format(self):
        serialized_result = self.formatter.format(self.record)
        content = json.loads(serialized_result)
        self.assertEqual(
            content,
            {
                "logged_at": ANY,
                "line_number": 42,
                "function": "xablaufunc",
                "level": "WARNING",
                "file_path":
                "/aiologger/tests/formatters/test_json_formatter.py",
                "msg": {
                    "dog": "Xablau",
                    "action": "bark"
                },
            },
        )

    def test_flatten_record_attr_adds_msg_to_root(self):
        self.record.flatten = True
        serialized_result = self.formatter.format(self.record)

        content = json.loads(serialized_result)
        self.assertEqual(
            content,
            {
                "logged_at": ANY,
                "line_number": 42,
                "function": "xablaufunc",
                "level": "WARNING",
                "file_path":
                "/aiologger/tests/formatters/test_json_formatter.py",
                "dog": "Xablau",
                "action": "bark",
            },
        )

    def test_flatten_record_attr_does_nothing_if_msg_isnt_a_dict_instance(
            self):
        self.record.flatten = True
        self.record.msg = "Xablau, the dog"
        serialized_result = self.formatter.format(self.record)

        content = json.loads(serialized_result)
        self.assertEqual(
            content,
            {
                "logged_at": ANY,
                "line_number": 42,
                "function": "xablaufunc",
                "level": "WARNING",
                "file_path":
                "/aiologger/tests/formatters/test_json_formatter.py",
                "msg": "Xablau, the dog",
            },
        )

    def test_serialized_kwargs_record_attr_is_passed_to_instance_serialized_function(
            self):
        self.record.serializer_kwargs = {"indent": 2, "sort_keys": True}
        expected_msg = {
            "logged_at": ANY,
            "line_number": 42,
            "function": "xablaufunc",
            "level": "WARNING",
            "file_path": "/aiologger/tests/formatters/test_json_formatter.py",
            "msg": {
                "dog": "Xablau",
                "action": "bark"
            },
        }

        with patch.object(self.formatter, "serializer") as serializer:
            self.formatter.format(self.record)
            serializer.assert_called_once_with(
                expected_msg,
                indent=2,
                sort_keys=True,
                default=self.formatter._default_handler,
            )

    def test_extra_record_attr_adds_content_to_root_of_msg(self):
        self.record.extra = {"female_dog": "Xena"}
        serialized_result = self.formatter.format(self.record)

        content = json.loads(serialized_result)
        self.assertEqual(
            content,
            {
                "logged_at": ANY,
                "line_number": 42,
                "function": "xablaufunc",
                "level": "WARNING",
                "file_path":
                "/aiologger/tests/formatters/test_json_formatter.py",
                "msg": {
                    "dog": "Xablau",
                    "action": "bark"
                },
                "female_dog": "Xena",
            },
        )