import logging
import threading
class _Singleton(type):
""" A metaclass that creates a Singleton base class when called. """
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(_Singleton, cls).__call__(
*args, **kwargs
)
return cls._instances[cls]
[docs]class Singleton(_Singleton("SingletonMeta", (object,), {})):
"""Singleton meta"""
[docs]class Logger(Singleton):
"""Basic logging"""
FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
def __init__(self):
self._loggers = {}
self._log_level = logging.INFO
self._lock = threading.Lock()
def get_logger(self, name):
self._lock.acquire()
if self._loggers.get(name) is None:
logger = logging.getLogger(name)
logger.setLevel(self._log_level)
formatter = logging.Formatter(Logger.FORMAT)
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
if not logger.handlers:
logger.addHandler(console_handler)
self._loggers[name] = logger
self._lock.release()
return self._loggers.get(name)
@property
def level(self):
return self._log_level
@level.setter
def level(self, value):
for name in self._loggers:
self._loggers[name].setLevel(value)