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 if stream.errors == 'strict': 31 # emulate backslashreplace error handler 32 encoding = stream.encoding 33 msg = msg.encode(encoding, "backslashreplace").decode(encoding) 34 stream.write('%s\n' % msg) 35 stream.flush() 36 37 def log(self, level, msg, *args): 38 self._log(level, msg, args) 39 40 def debug(self, msg, *args): 41 self._log(DEBUG, msg, args) 42 43 def info(self, msg, *args): 44 self._log(INFO, msg, args) 45 46 def warn(self, msg, *args): 47 self._log(WARN, msg, args) 48 49 def error(self, msg, *args): 50 self._log(ERROR, msg, args) 51 52 def fatal(self, msg, *args): 53 self._log(FATAL, msg, args) 54 55_global_log = Log() 56log = _global_log.log 57debug = _global_log.debug 58info = _global_log.info 59warn = _global_log.warn 60error = _global_log.error 61fatal = _global_log.fatal 62 63def set_threshold(level): 64 # return the old threshold for use from tests 65 old = _global_log.threshold 66 _global_log.threshold = level 67 return old 68 69def set_verbosity(v): 70 if v <= 0: 71 set_threshold(WARN) 72 elif v == 1: 73 set_threshold(INFO) 74 elif v >= 2: 75 set_threshold(DEBUG) 76