Privacy Policy
Snippets index

  FakeLogger: a stupid simple Python logger replacement

import threading
import datetime
# Adapted from logging.__init__.py

CRITICAL = 50
ERROR = 40
WARNING = 30
INFO = 20
DEBUG = 10
NOTSET = 0

_levelToName = {
    CRITICAL: 'CRITICAL',
    ERROR: 'ERROR',
    WARNING: 'WARNING',
    INFO: 'INFO',
    DEBUG: 'DEBUG',
    NOTSET: 'NOTSET',
}
_nameToLevel = {
    'CRITICAL': CRITICAL,
    'ERROR': ERROR,
    'WARNING': WARNING,
    'INFO': INFO,
    'DEBUG': DEBUG,
    'NOTSET': NOTSET,
}

_lock = threading.RLock()

def _acquireLock():
    """
    Acquire the module-level lock for serializing access to shared data.

    This should be released with _releaseLock().
    """
    if _lock:
        _lock.acquire()

def _releaseLock():
    """
    Release the module-level lock acquired by calling _acquireLock().
    """
    if _lock:
        _lock.release()


class FakeLogger():

    def __init__(self, level=NOTSET):
        self.setLevel(level)

    @staticmethod
    def verbosity_to_log_level(verbosity):
        levels = [WARNING, INFO, DEBUG]
        log_level = levels[min(len(levels)-1, verbosity)]  # capped to number of levels
        return log_level

    def setLevel(self, level):
        self.level = level
        self.disabled = level <= NOTSET

    def _log(self, level, msg, args, **kwargs):
        _acquireLock()
        try:

            msg = str(msg)
            if args:
                msg = msg % args

            # [DEBUG] 2022-03-14 12:08:05,044|MainThread|Server binded to 0.0.0.0:6000
            level_name = '[' + _levelToName[level] + ']'
            line = '%-10.10s %s|%s|%s' % (
                level_name,
                datetime.datetime.now().isoformat().replace('T',' '),
                threading.currentThread().getName(),
                msg
            )

            print(line, flush=True)
        finally:
            _releaseLock()
        return

    def isEnabledFor(self, level):
        """
        Is this logger enabled for level 'level'?
        """
        if self.disabled:
            return False

        _acquireLock()
        try:
            is_enabled = (level >= self.level)
        finally:
            _releaseLock()
        return is_enabled

    def debug(self, msg, *args, **kwargs):
        if self.isEnabledFor(DEBUG):
            self._log(DEBUG, msg, args, **kwargs)

    def info(self, msg, *args, **kwargs):
        if self.isEnabledFor(INFO):
            self._log(INFO, msg, args, **kwargs)

    def warning(self, msg, *args, **kwargs):
        if self.isEnabledFor(WARNING):
            self._log(WARNING, msg, args, **kwargs)

    def error(self, msg, *args, **kwargs):
        if self.isEnabledFor(ERROR):
            self._log(ERROR, msg, args, **kwargs)

    # def exception(self, msg, *args, exc_info=True, **kwargs):
    #     """
    #     Convenience method for logging an ERROR with exception information.
    #     """
    #     self.error(msg, *args, exc_info=exc_info, **kwargs)

    def critical(self, msg, *args, **kwargs):
        if self.isEnabledFor(CRITICAL):
            self._log(CRITICAL, msg, args, **kwargs)


if __name__ == '__main__':

    print('With Level: ERROR ...')
    logger = FakeLogger(level=ERROR)
    logger.debug('...debug...')
    logger.info('...info...')
    logger.warning('...warning...')
    logger.error('...error...')
    logger.critical('...critical...')

    print('With Level: DEBUG ...')
    logger.setLevel(DEBUG)
    logger.debug('...debug...')
    logger.info('...info...')
    logger.warning('...warning...')
    logger.error('...error...')
    logger.critical('...critical...')