5

What I want: To use the logging library instead of print statements, everywhere. Some times it is nice to not terminate with a new line. Consider this simplified example:

for file in files:
    print('Loading {}'.format(file), end='', flush=True)
    try:
        data = load(file)
        print('\rLoaded {}'.format(file))
    except:
        print('\rFailed loading {}'.format(file))

The obvious way would be to use:

handler = logging.StreamHandler()
handler.terminator = ""

However, I do not want to add a handler to my library, and I do want the default behaviour of my main logger to be to terminate with a new line. Terminating with "" feels like it should be the exception, rather than the rule.
Is there a way that I could do something like:

logger.info(msg, terminator="")

without having to create a lot of subclasses to the logging module?

Is my take on the problem reasonable, or is there a better way of handling this?

InvaderZim
  • 455
  • 3
  • 10
  • Somewhat relevant: http://stackoverflow.com/questions/12699645/how-can-i-suppress-newline-in-python-logging-module and http://stackoverflow.com/questions/7168790/suppress-newline-in-python-logging-module – InvaderZim Sep 15 '16 at 10:38
  • This is the Pythonic way...if only it were in the base logging module. – winderland Jun 12 '22 at 06:44

1 Answers1

2

I had a similar issue and this is what I use to get the results I wanted, seems to be similar to what you are trying to achieve:

import logging


def getLogger(name, fmt="[%(asctime)s]%(name)s<%(levelname)s>%(message)s",
              terminator='\n'):
    logger = logging.getLogger(name)
    cHandle = logging.StreamHandler()
    cHandle.terminator = terminator
    cHandle.setFormatter(logging.Formatter(fmt=fmt, datefmt="%H:%M:%S"))
    logger.addHandler(cHandle)
    return logger


logger = getLogger(r'\n', terminator='\n')
rlogger = getLogger(r'\r', terminator='\r')

logger.setLevel(logging.DEBUG)
rlogger.setLevel(logging.DEBUG)


logger.info('test0')
logger.info('test1')
logger.info('-----------------------\n')
rlogger.info('test2')
rlogger.info('test3\n\n')

for i in range(100000):
    rlogger.info("%d/%d", i + 1, 100000)
rlogger.info('\n')

Results:

[14:48:00]\n<INFO>test0
[14:48:00]\n<INFO>test1
[14:48:00]\n<INFO>-----------------------

[14:48:00]\r<INFO>test3

[14:48:04]\r<INFO>100000/100000
s4w3d0ff
  • 1,091
  • 10
  • 24
  • 1
    Thanks for the suggestion, but I do not want to have two distinct loggers, I think. Also, I'm writing a package with several modules and submodules. I'd prefer a solution where I can just import the regular logging module to submodules, and let the top level logger handle the actual logging. – InvaderZim Aug 29 '17 at 09:03