简体   繁体   中英

how to make logging.logger to behave like print

Let's say I got this logging.logger instance:

import logging
logger = logging.getLogger('root')
FORMAT = "[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s"
logging.basicConfig(format=FORMAT)
logger.setLevel(logging.DEBUG)

Problem comes when I try to use it like the builtin print with a dynamic number of arguments:

>>> logger.__class__
<class 'logging.Logger'>
>>> logger.debug("hello")
[<stdin>:1 -             <module>() ] hello
>>> logger.debug("hello","world")
Traceback (most recent call last):
  File "c:\Python2711\Lib\logging\__init__.py", line 853, in emit
    msg = self.format(record)
  File "c:\Python2711\Lib\logging\__init__.py", line 726, in format
    return fmt.format(record)
  File "c:\Python2711\Lib\logging\__init__.py", line 465, in format
    record.message = record.getMessage()
  File "c:\Python2711\Lib\logging\__init__.py", line 329, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Logged from file <stdin>, line 1

How could i emulate the print behaviour still using logging.Logger?

Wrapper based on @Jim's original answer:

import logging
import sys

_logger = logging.getLogger('root')
FORMAT = "[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s"
logging.basicConfig(format=FORMAT)
_logger.setLevel(logging.DEBUG)


class LogWrapper():

    def __init__(self, logger):
        self.logger = logger

    def info(self, *args, sep=' '):
        self.logger.info(sep.join("{}".format(a) for a in args))

    def debug(self, *args, sep=' '):
        self.logger.debug(sep.join("{}".format(a) for a in args))

    def warning(self, *args, sep=' '):
        self.logger.warning(sep.join("{}".format(a) for a in args))

    def error(self, *args, sep=' '):
        self.logger.error(sep.join("{}".format(a) for a in args))

    def critical(self, *args, sep=' '):
        self.logger.critical(sep.join("{}".format(a) for a in args))

    def exception(self, *args, sep=' '):
        self.logger.exception(sep.join("{}".format(a) for a in args))

    def log(self, *args, sep=' '):
        self.logger.log(sep.join("{}".format(a) for a in args))

logger = LogWrapper(_logger)

Alternatively, define a function that accepts *args and then join them in your call to logger :

def log(*args, logtype='debug', sep=' '):
    getattr(logger, logtype)(sep.join(str(a) for a in args))

I added a logtype for flexibility here but you could remove it if not required.

Set sys.stdout as the stream for your logging.

eg logging.basicConfig(level=logging.INFO, stream=sys.stdout )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM