예제 #1
0
    def test_everything(self, cr):
        """
        Put all cases together.
        """
        exc = "Traceback:\nFake traceback...\nFakeError: yolo"
        stack = "fake stack trace"

        rv = cr(None, None, {
            "event": "test",
            "exception": exc,
            "key": "value",
            "foo": "bar",
            "timestamp": "13:13",
            "logger": "some_module",
            "level": "error",
            "stack": stack,
        })

        assert (
            dev.DIM + "13:13" + dev.RESET_ALL +
            " [" + dev.RED + dev.BRIGHT +
            dev._pad("error", cr._longest_level) +
            dev.RESET_ALL + "] " +
            PADDED_TEST +
            "[" + dev.BLUE + dev.BRIGHT +
            "some_module" +
            dev.RESET_ALL + "] " +
            dev.CYAN + "foo" + dev.RESET_ALL + "=" + dev.MAGENTA + "'bar'" +
            dev.RESET_ALL + " " +
            dev.CYAN + "key" + dev.RESET_ALL + "=" + dev.MAGENTA + "'value'" +
            dev.RESET_ALL +
            "\n" + stack + "\n\n" + "=" * 79 + "\n" +
            "\n" + exc
        ) == rv
예제 #2
0
    def test_init_accepts_overriding_levels(self, styles, padded):
        """
        Stdlib levels are rendered aligned, in brackets, and color coded.
        """
        my_styles = dev.ConsoleRenderer.get_default_level_styles(
            colors=dev._has_colorama
        )
        my_styles["MY_OH_MY"] = my_styles["critical"]
        cr = dev.ConsoleRenderer(
            colors=dev._has_colorama, level_styles=my_styles
        )

        # this would blow up if the level_styles override failed
        rv = cr(
            None, None, {"event": "test", "level": "MY_OH_MY", "foo": "bar"}
        )

        # fmt: off
        assert (
            "[" + dev.RED + styles.bright +
            dev._pad("MY_OH_MY", cr._longest_level) +
            styles.reset + "] " +
            padded +
            styles.kv_key + "foo" + styles.reset + "=" +
            styles.kv_value + "bar" + styles.reset
        ) == rv
예제 #3
0
    def test_pad_event_param(self):
        """
        `pad_event` parameter works.
        """
        rv = dev.ConsoleRenderer(42)(None, None, {"event": "test"})

        assert (dev.BRIGHT + dev._pad("test", 42) + dev.RESET_ALL + " ") == rv
예제 #4
0
    def test_everything(self, cr):
        """
        Put all cases together.
        """
        exc = "Traceback:\nFake traceback...\nFakeError: yolo"
        stack = "fake stack trace"

        rv = cr(
            None, None, {
                "event": "test",
                "exception": exc,
                "key": "value",
                "foo": "bar",
                "timestamp": "13:13",
                "logger": "some_module",
                "level": "error",
                "stack": stack,
            })

        assert (dev.DIM + "13:13" + dev.RESET_ALL + " [" + dev.RED +
                dev.BRIGHT + dev._pad("error", cr._longest_level) +
                dev.RESET_ALL + "] " + PADDED_TEST + "[" + dev.BLUE +
                dev.BRIGHT + "some_module" + dev.RESET_ALL + "] " + dev.CYAN +
                "foo" + dev.RESET_ALL + "=" + dev.MAGENTA + "'bar'" +
                dev.RESET_ALL + " " + dev.CYAN + "key" + dev.RESET_ALL + "=" +
                dev.MAGENTA + "'value'" + dev.RESET_ALL + "\n" + stack +
                "\n\n" + "=" * 79 + "\n" + "\n" + exc) == rv
예제 #5
0
    def test_everything(self, cr, styles, padded):
        """
        Put all cases together.
        """
        exc = "Traceback:\nFake traceback...\nFakeError: yolo"
        stack = "fake stack trace"

        rv = cr(
            None,
            None,
            {
                "event": "test",
                "exception": exc,
                "key": "value",
                "foo": "bar",
                "timestamp": "13:13",
                "logger": "some_module",
                "level": "error",
                "stack": stack,
            },
        )

        # fmt: off
        assert (styles.timestamp + "13:13" + styles.reset + " [" +
                styles.level_error + styles.bright +
                dev._pad("error", cr._longest_level) + styles.reset + "] " +
                padded + "[" + dev.BLUE + styles.bright + "some_module" +
                styles.reset + "] " + styles.kv_key + "foo" + styles.reset +
                "=" + styles.kv_value + "bar" + styles.reset + " " +
                styles.kv_key + "key" + styles.reset + "=" + styles.kv_value +
                "value" + styles.reset + "\n" + stack + "\n\n" + "=" * 79 +
                "\n" + "\n" + exc) == rv
예제 #6
0
        def __call__(self, _, __, event_dict):
            from io import StringIO

            from structlog.dev import _pad

            sio = StringIO()

            ts = event_dict.pop('timestamp', None)
            if ts is not None:
                sio.write(
                    # can be a number if timestamp is UNIXy
                    self._styles.timestamp + str(ts) + self._styles.reset +
                    ' ')
            level = event_dict.pop('level', None)
            if level is not None:
                sio.write('[' + self._level_to_color[level] +
                          _pad(level, self._longest_level) +
                          self._styles.reset + '] ')

            logger_name = event_dict.pop('logger', None)
            if logger_name is not None:
                sio.write('[' + self._styles.logger_name +
                          self._styles.bright + logger_name +
                          self._styles.reset + '] ')

            event = str(event_dict.pop('event'))
            if event_dict:
                event = _pad(event, self._pad_event) + self._styles.reset + ' '
            else:
                event += self._styles.reset
            sio.write(self._styles.bright + event)

            stack = event_dict.pop('stack', None)
            exc = event_dict.pop('exception', None)
            sio.write(' '.join(self._styles.kv_key + key + self._styles.reset +
                               '=' + self._styles.kv_value +
                               self._repr(event_dict[key]) + self._styles.reset
                               for key in sorted(event_dict.keys())))

            if stack is not None:
                sio.write('\n' + stack)
                if exc is not None:
                    sio.write('\n\n' + '=' * 79 + '\n')
            if exc is not None:
                sio.write('\n' + exc)

            return sio.getvalue()
예제 #7
0
    def test_level(self, cr):
        """
        Levels are rendered aligned, in square brackets, and color coded.
        """
        rv = cr(None, None, {"event": "test", "level": "critical"})

        assert ("[" + dev.RED + dev.BRIGHT +
                dev._pad("critical", cr._longest_level) + dev.RESET_ALL +
                "] " + PADDED_TEST) == rv
예제 #8
0
    def test_pad_event_param(self):
        """
        `pad_event` parameter works.
        """
        rv = dev.ConsoleRenderer(42)(None, None, {"event": "test"})

        assert (
            dev.BRIGHT +
            dev._pad("test", 42) +
            dev.RESET_ALL + " "
        ) == rv
예제 #9
0
    def test_level(self, cr):
        """
        Levels are rendered aligned, in square brackets, and color coded.
        """
        rv = cr(None, None, {"event": "test", "level": "critical"})

        assert (
            "[" + dev.RED + dev.BRIGHT +
            dev._pad("critical", cr._longest_level) +
            dev.RESET_ALL + "] " +
            PADDED_TEST
        ) == rv
예제 #10
0
    def test_pad_event_param(self, styles):
        """
        `pad_event` parameter works.
        """
        rv = dev.ConsoleRenderer(42, dev._has_colorama)(None, None, {
            "event": "test",
            "foo": "bar"
        })

        assert (styles.bright + dev._pad("test", 42) + styles.reset + " " +
                styles.kv_key + "foo" + styles.reset + "=" + styles.kv_value +
                "'bar'" + styles.reset) == rv
예제 #11
0
    def test_level(self, cr, styles, padded):
        """
        Levels are rendered aligned, in square brackets, and color coded.
        """
        rv = cr(None, None, {
            "event": "test",
            "level": "critical",
            "foo": "bar"
        })

        assert ("[" + dev.RED + styles.bright +
                dev._pad("critical", cr._longest_level) + styles.reset + "] " +
                padded + styles.kv_key + "foo" + styles.reset + "=" +
                styles.kv_value + "'bar'" + styles.reset) == rv
예제 #12
0
    def test_level(self, cr, styles, padded):
        """
        Levels are rendered aligned, in square brackets, and color coded.
        """
        rv = cr(None, None, {
            "event": "test", "level": "critical", "foo": "bar"
        })

        assert (
            "[" + dev.RED + styles.bright +
            dev._pad("critical", cr._longest_level) +
            styles.reset + "] " +
            padded +
            styles.kv_key + "foo" + styles.reset + "=" +
            styles.kv_value + "bar" + styles.reset
        ) == rv
예제 #13
0
    def test_pad_event_param(self, styles):
        """
        `pad_event` parameter works.
        """
        rv = dev.ConsoleRenderer(42, dev._has_colorama)(None, None, {
            "event": "test",
            "foo": "bar"
        })

        assert (
            styles.bright +
            dev._pad("test", 42) +
            styles.reset + " " +
            styles.kv_key + "foo" + styles.reset + "=" +
            styles.kv_value + "bar" + styles.reset
        ) == rv
예제 #14
0
    def test_colorama_force_colors(self, styles, padded):
        """
        If force_colors is True, use colors even if the destination is non-tty.
        """
        cr = dev.ConsoleRenderer(colors=dev._has_colorama,
                                 force_colors=dev._has_colorama)

        rv = cr(None, None, {
            "event": "test",
            "level": "critical",
            "foo": "bar"
        })

        assert ("[" + dev.RED + styles.bright +
                dev._pad("critical", cr._longest_level) + styles.reset + "] " +
                padded + styles.kv_key + "foo" + styles.reset + "=" +
                styles.kv_value + "bar" + styles.reset) == rv

        assert not dev._has_colorama or dev._ColorfulStyles is cr._styles
예제 #15
0
    def test_everything(self, cr, styles, padded):
        """
        Put all cases together.
        """
        exc = "Traceback:\nFake traceback...\nFakeError: yolo"
        stack = "fake stack trace"

        rv = cr(None, None, {
            "event": "test",
            "exception": exc,
            "key": "value",
            "foo": "bar",
            "timestamp": "13:13",
            "logger": "some_module",
            "level": "error",
            "stack": stack,
        })

        assert (
            styles.timestamp + "13:13" + styles.reset +
            " [" + styles.level_error + styles.bright +
            dev._pad("error", cr._longest_level) +
            styles.reset + "] " +
            padded +
            "[" + dev.BLUE + styles.bright +
            "some_module" +
            styles.reset + "] " +
            styles.kv_key + "foo" + styles.reset + "=" +
            styles.kv_value + "bar" +
            styles.reset + " " +
            styles.kv_key + "key" + styles.reset + "=" +
            styles.kv_value + "value" +
            styles.reset +
            "\n" + stack + "\n\n" + "=" * 79 + "\n" +
            "\n" + exc
        ) == rv
예제 #16
0
 def test_negative(self):
     """
     If string is already too long, don't do anything.
     """
     assert len("test") == len(dev._pad("test", 2))
예제 #17
0
def padded(styles):
    return (
        styles.bright +
        dev._pad("test", dev._EVENT_WIDTH) +
        styles.reset + " "
    )
예제 #18
0
 def test_normal(self):
     """
     If chars are missing, adequate number of " " are added.
     """
     assert 100 == len(dev._pad("test", 100))
예제 #19
0
    level.
    """
    with pytest.raises(SystemError) as e:
        dev.ConsoleRenderer()

    assert ("ConsoleRenderer requires the colorama package installed."
            ) in e.value.args[0]


@pytest.fixture
def cr():
    return dev.ConsoleRenderer()


if dev.colorama is not None:
    PADDED_TEST = (dev.BRIGHT + dev._pad("test", dev._EVENT_WIDTH) +
                   dev.RESET_ALL + " ")


@pytest.mark.skipif(dev.colorama is None, reason="Requires colorama.")
class TestConsoleRenderer(object):
    def test_plain(self, cr):
        """
        Works with a plain event_dict with only the event.
        """
        rv = cr(None, None, {"event": "test"})

        assert PADDED_TEST == rv

    def test_timestamp(self, cr):
        """
예제 #20
0
def padded(styles):
    return (
        styles.bright + dev._pad("test", dev._EVENT_WIDTH) + styles.reset + " "
    )
예제 #21
0
 def test_negative(self):
     """
     If string is already too long, don't do anything.
     """
     assert len("test") == len(dev._pad("test", 2))
예제 #22
0
    def __call__(self, logger, name, event_dict):
        sio = StringIO()

        # ``readthedocs`` as programname is required because it's used by
        # syslog to filter messages and send them to different files.
        # https://www.rsyslog.com/doc/master/configuration/properties.html#message-properties
        sio.write("readthedocs")

        process_id = event_dict.pop("process_id", None)
        if process_id is not None:
            sio.write(
                "["
                + str(process_id)
                + "]"
            )

        # syslog tag delimiter
        sio.write(": ")

        ts = event_dict.pop("timestamp", None)
        if ts is not None:
            sio.write(
                # can be a number if timestamp is UNIXy
                self._styles.timestamp
                + str(ts)
                + self._styles.reset
                + " "
            )

        level = event_dict.pop("level", None)
        if level is not None:
            sio.write(
                "["
                + self._level_to_color.get(level, "")
                + _pad(level, self._longest_level)
                + self._styles.reset
                + "] "
            )

        # force event to str for compatibility with standard library
        event = event_dict.pop("event", None)
        if not isinstance(event, str):
            event = str(event)

        if event_dict:
            event = _pad(event, self._pad_event) + self._styles.reset + " "
        else:
            event += self._styles.reset
        sio.write(self._styles.bright + event)

        logger_name = event_dict.pop("logger", None)
        if logger_name is None:
            logger_name = event_dict.pop("logger_name", None)

        line_number = event_dict.pop("line_number", None)
        if logger_name is not None:
            sio.write(
                "["
                + self._styles.logger_name
                + self._styles.bright
                + logger_name
                + self._styles.reset
                + ":"
                + str(line_number)
                + "] "
            )

        stack = event_dict.pop("stack", None)
        exc = event_dict.pop("exception", None)
        exc_info = event_dict.pop("exc_info", None)

        event_dict_keys = event_dict.keys()
        if self._sort_keys:
            event_dict_keys = sorted(event_dict_keys)

        sio.write(
            " ".join(
                self._styles.kv_key
                + key
                + self._styles.reset
                + "="
                + self._styles.kv_value
                + self._repr(event_dict[key])
                + self._styles.reset
                for key in event_dict_keys
            )
        )

        if stack is not None:
            sio.write("\n" + stack)
            if exc_info or exc is not None:
                sio.write("\n\n" + "=" * 79 + "\n")

        if exc_info:
            if not isinstance(exc_info, tuple):
                exc_info = sys.exc_info()

            self._exception_formatter(sio, exc_info)
        elif exc is not None:
            if self._exception_formatter is not plain_traceback:
                warnings.warn(
                    "Remove `format_exc_info` from your processor chain "
                    "if you want pretty exceptions."
                )
            sio.write("\n" + exc)

        return sio.getvalue()
예제 #23
0
 def test_normal(self):
     """
     If chars are missing, adequate number of " " are added.
     """
     assert 100 == len(dev._pad("test", 100))
예제 #24
0
        dev.ConsoleRenderer()

    assert (
        "ConsoleRenderer requires the colorama package installed."
    ) in e.value.args[0]


@pytest.fixture
def cr():
    return dev.ConsoleRenderer()


if dev.colorama is not None:
    PADDED_TEST = (
        dev.BRIGHT +
        dev._pad("test", dev._EVENT_WIDTH) +
        dev.RESET_ALL + " "
    )


@pytest.mark.skipif(dev.colorama is None, reason="Requires colorama.")
class TestConsoleRenderer(object):
    def test_plain(self, cr):
        """
        Works with a plain event_dict with only the event.
        """
        rv = cr(None, None, {"event": "test"})

        assert PADDED_TEST == rv

    def test_timestamp(self, cr):