1"""A simple log mechanism styled after PEP 282.""" 2 3# The class here is styled after PEP 282 so that it could later be 4# replaced with a standard Python logging implementation. 5 6DEBUG = 1 7INFO = 2 8WARN = 3 9ERROR = 4 10FATAL = 5 11 12import sys 13 14class Log: 15 16 def __init__(self, threshold=WARN): 17 self.threshold = threshold 18 19 def _log(self, level, msg, args): 20 if level not in (DEBUG, INFO, WARN, ERROR, FATAL): 21 raise ValueError('%s wrong log level' % str(level)) 22 23 if level >= self.threshold: 24 if args: 25 msg = msg % args 26 if level in (WARN, ERROR, FATAL): 27 stream = sys.stderr 28 else: 29 stream = sys.stdout 30 try: 31 stream.write('%s\n' % msg) 32 except UnicodeEncodeError: 33 # emulate backslashreplace error handler 34 encoding = stream.encoding 35 msg = msg.encode(encoding, "backslashreplace").decode(encoding) 36 stream.write('%s\n' % msg) 37 stream.flush() 38 39 def log(self, level, msg, *args): 40 self._log(level, msg, args) 41 42 def debug(self, msg, *args): 43 self._log(DEBUG, msg, args) 44 45 def info(self, msg, *args): 46 self._log(INFO, msg, args) 47 48 def warn(self, msg, *args): 49 self._log(WARN, msg, args) 50 51 def error(self, msg, *args): 52 self._log(ERROR, msg, args) 53 54 def fatal(self, msg, *args): 55 self._log(FATAL, msg, args) 56 57_global_log = Log() 58log = _global_log.log 59debug = _global_log.debug 60info = _global_log.info 61warn = _global_log.warn 62error = _global_log.error 63fatal = _global_log.fatal 64 65def set_threshold(level): 66 # return the old threshold for use from tests 67 old = _global_log.threshold 68 _global_log.threshold = level 69 return old 70 71def set_verbosity(v): 72 if v <= 0: 73 set_threshold(WARN) 74 elif v == 1: 75 set_threshold(INFO) 76 elif v >= 2: 77 set_threshold(DEBUG) 78