On 07/02/2021 16:12, Peter J. Holzer wrote:
On 2021-02-06 21:01:37 -0600, Skip Montanaro wrote:
The logging package can log exceptions and call stacks, but it does
(in my opinion) a suboptimal job of it. Consider this simple example:
import logging
FORMAT = '%(asctime)-15s %(levelname)s %(message)s'
logging.basicConfig(format=FORMAT, force=True)
log.warning("msg", stack_info=True)
2021-02-06 20:46:52,399 WARNING msg
Stack (most recent call last):
   File "<stdin>", line 1, in <module>

It formats the warning message just fine, but simply dumps the
traceback onto the stream with no timestamp or level. For my purposes,
this is more important for exceptions. (I'm just using the stack trace
feature as it's easier in a small example.) I would like to call
something like

I suspect that it just adds the stack trace to the message, so that you
are left with a multi-line message.

If you are willing to process all multiline messages in the same way
that simplifies your custom Formatter:

def make_formatter_class(prefix, style):

    class PrefixFormatter(logging.Formatter):
        prefix_template = logging._STYLES[style][0](prefix)
        prefix_uses_time = prefix_template.usesTime()

        def usesTime(self):
            return self.prefix_uses_time or super().usesTime()

        def format(self, record):
            # this is supposed to set asctime attribute implicitly:
            text = super().format(record)

            lines = text.splitlines(True)
            if len(lines) > 1:
                prefix = self.prefix_template.format(record)
                return "".join(
                    lines[:1] + [prefix + line for line in lines[1:]]
                )
            return text

    return PrefixFormatter


# optional: monkey-patch to affect basicConfig()
logging.Formatter = make_formatter_class(
    prefix="X... %(asctime)s %(levelname)s ", style="%"
)
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to