wrapped output for python logging.StreamHandler()

logging, python, word-wrap

Solution

With the caveat that this indeed is bad for any logs you're going to be saving (because it breaks `grep` or similar line-by-line searching), the easy way you could do this is with the `textwrap` module and a custom `logging.Formatter` subclass.

`textwrap` is a standard library module that word-wraps paragraphs and can also apply indentation and some other formatting. All that's really needed is to hook it up by making a custom formatter class that overrides the `format()` method (which handles putting together the entire log message, as opposed to some of the other methods that handle parts):

import logging
import textwrap

class WrappedFixedIndentingLog(logging.Formatter):
    def __init__(self, fmt=None, datefmt=None, style='%', width=70, indent=4):
        super().__init__(fmt=fmt, datefmt=datefmt, style=style)
        self.wrapper = textwrap.TextWrapper(width=width, subsequent_indent=' '*indent)

    def format(self, record):
        return self.wrapper.fill(super().format(record))

# standard stuff
rootLogger = logging.getLogger()
rootLogger.setLevel(logging.DEBUG)
consLogger = logging.StreamHandler()
rootLogger.addHandler(consLogger)

# indent=18 matches fixed width of asctime + levelname + spaces
consLogger.setFormatter(WrappedFixedIndentingLog(
    '%(asctime)-8s %(levelname)-8s %(message)s', '%H:%M:%S', indent=18))

message = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
rootLogger.log(logging.DEBUG, message)

Outputs:

18:48:56 DEBUG    Lorem ipsum dolor sit amet, consectetur adipisicing
                  elit, sed do eiusmod tempor incididunt ut labore et
                  dolore magna aliqua. Ut enim ad minim veniam, quis
                  nostrud exercitation ullamco laboris nisi ut aliquip
                  ex ea commodo consequat. Duis aute irure dolor in
                  reprehenderit in voluptate velit esse cillum dolore
                  eu fugiat nulla pariatur. Excepteur sint occaecat
                  cupidatat non proident, sunt in culpa qui officia
                  deserunt mollit anim id est laborum.

Problem

I use multiple handlers like ``` rootLogger = logging.getLogger() rootLogger.basicConfig(filename = logfile, level=logging.INFO) consLogger = logging.StreamHandler() consLogger.setFormatter(logging.Formatter('%(asctime)-8s %(levelname)-8s %(message)s', '%H:%M:%S')) consLogger.setLevel(logging.DEBUG) rootLogger.addHandler(consLogger) ``` and want consLogger (just consLogger, not all log handlers) to be properly wrapped and indented, like ``` 11:03:46 DEBUG text 11:03:47 DEBUG text again 11:03:47 DEBUG some text that is longer than current cons ole width or at least some pre-defined lin e length ``` where should I start?

Original source