"""
Log Handler
===========
"""
import logging
import os
import platform
from logging.config import dictConfig
from logging.handlers import RotatingFileHandler
import colors
from .Config import Configuration
[docs]class HostnameFilter(logging.Filter):
hostname = platform.node()
[docs] def filter(self, record):
record.hostname = HostnameFilter.hostname
return True
[docs]class HelperLogger(logging.Logger):
"""
The HelperLogger is used by the application / gui as their logging class and *extends* the default python
logger.logging class.
"""
config = Configuration()
if config.LOGGING_TO_FILE:
try:
if not os.path.exists(config.LOGGING_FILE_PATH):
os.makedirs(config.LOGGING_FILE_PATH)
except PermissionError:
logPath = os.path.expanduser("~")
logDict = {
"version": 1,
"formatters": {
"sysLogFormatter": {
"format": "%(asctime)s - %(name)-8s - %(levelname)-8s - %(message)s"
},
"simpleFormatter": {
"format": "%(asctime)s - %(name)-8s - %(levelname)-8s - %(message)s"
},
},
"handlers": {
"consoleHandler": {
"class": "logging.StreamHandler",
"level": "INFO",
"stream": "ext://sys.stdout",
"formatter": "simpleFormatter",
}
},
"root": {"level": "DEBUG", "handlers": ["consoleHandler"]},
}
dictConfig(logDict)
level_map = {
"debug": "magenta",
"info": "white",
"warning": "yellow",
"error": "red",
"critical": "red",
}
[docs] def __init__(self, name, level=logging.NOTSET):
super().__init__(name, level)
[docs] def debug(self, msg, *args, **kwargs):
"""
Log ‘msg % args’ with severity ‘DEBUG’ and color *MAGENTA.
To pass exception information, use the keyword argument exc_info with a true value, e.g.
.. code-block:: python
>>> logger.debug(“Houston, we have a thorny problem”)
:param msg: Message to log
:type msg: str
"""
msg = colors.color("{}".format(msg), fg=HelperLogger.level_map["debug"])
return super(HelperLogger, self).debug(msg, *args, **kwargs)
[docs] def info(self, msg, *args, **kwargs):
"""
Log ‘msg % args’ with severity ‘INFO’ and color *WHITE*.
To pass exception information, use the keyword argument exc_info with a true value, e.g.
.. code-block:: python
>>> logger.info(“Houston, we have an interesting problem”)
:param msg: Message to log
:type msg: str
"""
msg = colors.color("{}".format(msg), fg=HelperLogger.level_map["info"])
return super(HelperLogger, self).info(msg, *args, **kwargs)
[docs] def warning(self, msg, *args, **kwargs):
"""
Log ‘msg % args’ with severity ‘WARNING’ and color *YELLOW*.
To pass exception information, use the keyword argument exc_info with a true value, e.g.
.. code-block:: python
>>> logger.warning(“Houston, we have a bit of a problem”)
:param msg: Message to log
:type msg: str
"""
msg = colors.color("{}".format(msg), fg=HelperLogger.level_map["warning"])
return super(HelperLogger, self).warning(msg, *args, **kwargs)
[docs] def error(self, msg, *args, **kwargs):
"""
Log ‘msg % args’ with severity ‘ERROR’ and color *RED*.
Store logged message to the database for dashboard alerting.
To pass exception information, use the keyword argument exc_info with a true value, e.g.
.. code-block:: python
>>> logger.error(“Houston, we have a major problem”)
:param msg: Message to log
:type msg: str
"""
msg = colors.color("{}".format(msg), fg=HelperLogger.level_map["error"])
return super(HelperLogger, self).error(msg, *args, **kwargs)
[docs] def critical(self, msg, *args, **kwargs):
"""
Log ‘msg % args’ with severity ‘CRITICAL’ and color *RED*.
Store logged message to the database for dashboard alerting.
To pass exception information, use the keyword argument exc_info with a true value, e.g.
.. code-block:: python
>>> logger.critical(“Houston, we have a hell of a problem”)
:param msg: Message to log
:type msg: str
"""
msg = colors.color("{}".format(msg), fg=HelperLogger.level_map["critical"])
return super(HelperLogger, self).critical(msg, *args, **kwargs)
[docs]class UpdateHandler(HelperLogger):
"""
The UpdateHandler is used by the update process to provide written and visual feedback to the initiator of database
management tasks.
"""
[docs] def __init__(self, name, level=logging.NOTSET):
super().__init__(name, level)
formatter = logging.Formatter(
"%(asctime)s - %(name)-8s - %(levelname)-8s - %(message)s"
)
if self.config.LOGGING_TO_FILE:
crf = RotatingFileHandler(
filename=os.path.join(self.logPath, self.config.getUpdateLogFile()),
maxBytes=self.config.getMaxLogSize(),
backupCount=self.config.getBacklog(),
)
crf.setLevel(logging.DEBUG)
crf.setFormatter(formatter)
self.addHandler(crf)