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...')
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...')