InvokeAI/invokeai/backend/util/logging.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

110 lines
3.4 KiB
Python
Raw Normal View History

# Copyright (c) 2023 Lincoln D. Stein and The InvokeAI Development Team
"""invokeai.util.logging
Logging class for InvokeAI that produces console messages that follow
the conventions established in InvokeAI 1.X through 2.X.
One way to use it:
from invokeai.backend.util.logging import InvokeAILogger
logger = InvokeAILogger.getLogger(__name__)
logger.critical('this is critical')
logger.error('this is an error')
logger.warning('this is a warning')
logger.info('this is info')
logger.debug('this is debugging')
Console messages:
### this is critical
*** this is an error ***
** this is a warning
>> this is info
| this is debugging
Another way:
import invokeai.backend.util.logging as ialog
2023-04-29 13:43:40 +00:00
ialogger.debug('this is a debugging message')
"""
import logging
add logging support This commit adds invokeai.backend.util.logging, which provides support for formatted console and logfile messages that follow the status reporting conventions of earlier InvokeAI versions. Examples: ### A critical error (logging.CRITICAL) *** A non-fatal error (logging.ERROR) ** A warning (logging.WARNING) >> Informational message (logging.INFO) | Debugging message (logging.DEBUG) This style logs everything through a single logging object and is identical to using Python's `logging` module. The commonly-used module-level logging functions are implemented as simple pass-thrus to logging: import invokeai.backend.util.logging as ialog ialog.debug('this is a debugging message') ialog.info('this is a informational message') ialog.log(level=logging.CRITICAL, 'get out of dodge') ialog.disable(level=logging.INFO) ialog.basicConfig(filename='/var/log/invokeai.log') Internally, the invokeai logging module creates a new default logger named "invokeai" so that its logging does not interfere with other module's use of the vanilla logging module. So `logging.error("foo")` will go through the regular logging path and not add the additional message decorations. For more control, the logging module's object-oriented logging style is also supported. The API is identical to the vanilla logging usage. In fact, the only thing that has changed is that the getLogger() method adds a custom formatter to the log messages. import logging from invokeai.backend.util.logging import InvokeAILogger logger = InvokeAILogger.getLogger(__name__) fh = logging.FileHandler('/var/invokeai.log') logger.addHandler(fh) logger.critical('this will be logged to both the console and the log file')
2023-04-11 14:46:38 +00:00
# module level functions
def debug(msg, *args, **kwargs):
InvokeAILogger.getLogger().debug(msg, *args, **kwargs)
add logging support This commit adds invokeai.backend.util.logging, which provides support for formatted console and logfile messages that follow the status reporting conventions of earlier InvokeAI versions. Examples: ### A critical error (logging.CRITICAL) *** A non-fatal error (logging.ERROR) ** A warning (logging.WARNING) >> Informational message (logging.INFO) | Debugging message (logging.DEBUG) This style logs everything through a single logging object and is identical to using Python's `logging` module. The commonly-used module-level logging functions are implemented as simple pass-thrus to logging: import invokeai.backend.util.logging as ialog ialog.debug('this is a debugging message') ialog.info('this is a informational message') ialog.log(level=logging.CRITICAL, 'get out of dodge') ialog.disable(level=logging.INFO) ialog.basicConfig(filename='/var/log/invokeai.log') Internally, the invokeai logging module creates a new default logger named "invokeai" so that its logging does not interfere with other module's use of the vanilla logging module. So `logging.error("foo")` will go through the regular logging path and not add the additional message decorations. For more control, the logging module's object-oriented logging style is also supported. The API is identical to the vanilla logging usage. In fact, the only thing that has changed is that the getLogger() method adds a custom formatter to the log messages. import logging from invokeai.backend.util.logging import InvokeAILogger logger = InvokeAILogger.getLogger(__name__) fh = logging.FileHandler('/var/invokeai.log') logger.addHandler(fh) logger.critical('this will be logged to both the console and the log file')
2023-04-11 14:46:38 +00:00
def info(msg, *args, **kwargs):
InvokeAILogger.getLogger().info(msg, *args, **kwargs)
add logging support This commit adds invokeai.backend.util.logging, which provides support for formatted console and logfile messages that follow the status reporting conventions of earlier InvokeAI versions. Examples: ### A critical error (logging.CRITICAL) *** A non-fatal error (logging.ERROR) ** A warning (logging.WARNING) >> Informational message (logging.INFO) | Debugging message (logging.DEBUG) This style logs everything through a single logging object and is identical to using Python's `logging` module. The commonly-used module-level logging functions are implemented as simple pass-thrus to logging: import invokeai.backend.util.logging as ialog ialog.debug('this is a debugging message') ialog.info('this is a informational message') ialog.log(level=logging.CRITICAL, 'get out of dodge') ialog.disable(level=logging.INFO) ialog.basicConfig(filename='/var/log/invokeai.log') Internally, the invokeai logging module creates a new default logger named "invokeai" so that its logging does not interfere with other module's use of the vanilla logging module. So `logging.error("foo")` will go through the regular logging path and not add the additional message decorations. For more control, the logging module's object-oriented logging style is also supported. The API is identical to the vanilla logging usage. In fact, the only thing that has changed is that the getLogger() method adds a custom formatter to the log messages. import logging from invokeai.backend.util.logging import InvokeAILogger logger = InvokeAILogger.getLogger(__name__) fh = logging.FileHandler('/var/invokeai.log') logger.addHandler(fh) logger.critical('this will be logged to both the console and the log file')
2023-04-11 14:46:38 +00:00
def warning(msg, *args, **kwargs):
InvokeAILogger.getLogger().warning(msg, *args, **kwargs)
add logging support This commit adds invokeai.backend.util.logging, which provides support for formatted console and logfile messages that follow the status reporting conventions of earlier InvokeAI versions. Examples: ### A critical error (logging.CRITICAL) *** A non-fatal error (logging.ERROR) ** A warning (logging.WARNING) >> Informational message (logging.INFO) | Debugging message (logging.DEBUG) This style logs everything through a single logging object and is identical to using Python's `logging` module. The commonly-used module-level logging functions are implemented as simple pass-thrus to logging: import invokeai.backend.util.logging as ialog ialog.debug('this is a debugging message') ialog.info('this is a informational message') ialog.log(level=logging.CRITICAL, 'get out of dodge') ialog.disable(level=logging.INFO) ialog.basicConfig(filename='/var/log/invokeai.log') Internally, the invokeai logging module creates a new default logger named "invokeai" so that its logging does not interfere with other module's use of the vanilla logging module. So `logging.error("foo")` will go through the regular logging path and not add the additional message decorations. For more control, the logging module's object-oriented logging style is also supported. The API is identical to the vanilla logging usage. In fact, the only thing that has changed is that the getLogger() method adds a custom formatter to the log messages. import logging from invokeai.backend.util.logging import InvokeAILogger logger = InvokeAILogger.getLogger(__name__) fh = logging.FileHandler('/var/invokeai.log') logger.addHandler(fh) logger.critical('this will be logged to both the console and the log file')
2023-04-11 14:46:38 +00:00
def error(msg, *args, **kwargs):
InvokeAILogger.getLogger().error(msg, *args, **kwargs)
add logging support This commit adds invokeai.backend.util.logging, which provides support for formatted console and logfile messages that follow the status reporting conventions of earlier InvokeAI versions. Examples: ### A critical error (logging.CRITICAL) *** A non-fatal error (logging.ERROR) ** A warning (logging.WARNING) >> Informational message (logging.INFO) | Debugging message (logging.DEBUG) This style logs everything through a single logging object and is identical to using Python's `logging` module. The commonly-used module-level logging functions are implemented as simple pass-thrus to logging: import invokeai.backend.util.logging as ialog ialog.debug('this is a debugging message') ialog.info('this is a informational message') ialog.log(level=logging.CRITICAL, 'get out of dodge') ialog.disable(level=logging.INFO) ialog.basicConfig(filename='/var/log/invokeai.log') Internally, the invokeai logging module creates a new default logger named "invokeai" so that its logging does not interfere with other module's use of the vanilla logging module. So `logging.error("foo")` will go through the regular logging path and not add the additional message decorations. For more control, the logging module's object-oriented logging style is also supported. The API is identical to the vanilla logging usage. In fact, the only thing that has changed is that the getLogger() method adds a custom formatter to the log messages. import logging from invokeai.backend.util.logging import InvokeAILogger logger = InvokeAILogger.getLogger(__name__) fh = logging.FileHandler('/var/invokeai.log') logger.addHandler(fh) logger.critical('this will be logged to both the console and the log file')
2023-04-11 14:46:38 +00:00
def critical(msg, *args, **kwargs):
InvokeAILogger.getLogger().critical(msg, *args, **kwargs)
def log(level, msg, *args, **kwargs):
InvokeAILogger.getLogger().log(level, msg, *args, **kwargs)
def disable(level=logging.CRITICAL):
InvokeAILogger.getLogger().disable(level)
2023-04-11 15:10:43 +00:00
def basicConfig(**kwargs):
InvokeAILogger.getLogger().basicConfig(**kwargs)
2023-04-11 16:23:13 +00:00
def getLogger(name: str=None)->logging.Logger:
return InvokeAILogger.getLogger(name)
class InvokeAILogFormatter(logging.Formatter):
'''
Repurposed from:
https://stackoverflow.com/questions/14844970/modifying-logging-message-format-based-on-message-logging-level-in-python3
'''
crit_fmt = "### %(msg)s"
2023-04-11 16:23:13 +00:00
err_fmt = "*** %(msg)s"
warn_fmt = "** %(msg)s"
info_fmt = ">> %(msg)s"
dbg_fmt = " | %(msg)s"
def __init__(self):
super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')
def format(self, record):
# Remember the format used when the logging module
# was installed (in the event that this formatter is
# used with the vanilla logging module.
format_orig = self._style._fmt
if record.levelno == logging.DEBUG:
self._style._fmt = InvokeAILogFormatter.dbg_fmt
if record.levelno == logging.INFO:
self._style._fmt = InvokeAILogFormatter.info_fmt
if record.levelno == logging.WARNING:
self._style._fmt = InvokeAILogFormatter.warn_fmt
if record.levelno == logging.ERROR:
self._style._fmt = InvokeAILogFormatter.err_fmt
if record.levelno == logging.CRITICAL:
self._style._fmt = InvokeAILogFormatter.crit_fmt
# parent class does the work
result = super().format(record)
self._style._fmt = format_orig
return result
class InvokeAILogger(object):
loggers = dict()
@classmethod
def getLogger(self, name:str='invokeai')->logging.Logger:
if name not in self.loggers:
logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
fmt = InvokeAILogFormatter()
ch.setFormatter(fmt)
logger.addHandler(ch)
self.loggers[name] = logger
return self.loggers[name]