1 #!/usr/local/python/bin 2 # coding=utf-8 3 4 '''Implements a simple log library. 5 6 This module is a simple encapsulation of logging module to provide a more 7 convenient interface to write log. The log will both print to stdout and 8 write to log file. It provides a more flexible way to set the log actions, 9 and also very simple. See examples showed below: 10 11 Example 1: Use default settings 12 13 import log 14 15 log.debug('hello, world') 16 log.info('hello, world') 17 log.error('hello, world') 18 log.critical('hello, world') 19 20 Result: 21 Print all log messages to file, and only print log whose level is greater 22 than ERROR to stdout. The log file is located in '/tmp/xxx.log' if the module 23 name is xxx.py. The default log file handler is size-rotated, if the log 24 file's size is greater than 20M, then it will be rotated. 25 26 Example 2: Use set_logger to change settings 27 28 # Change limit size in bytes of default rotating action 29 log.set_logger(limit = 10240) # 10M 30 31 # Use time-rotated file handler, each day has a different log file, see 32 # logging.handlers.TimedRotatingFileHandler for more help about 'when' 33 log.set_logger(when = 'D', limit = 1) 34 35 # Use normal file handler (not rotated) 36 log.set_logger(backup_count = 0) 37 38 # File log level set to INFO, and stdout log level set to DEBUG 39 log.set_logger(level = 'DEBUG:INFO') 40 41 # Both log level set to INFO 42 log.set_logger(level = 'INFO') 43 44 # Change default log file name and log mode 45 log.set_logger(filename = 'yyy.log', mode = 'w') 46 47 # Change default log formatter 48 log.set_logger(fmt = '[%(levelname)s] %(message)s' 49 ''' 50 51 __author__ = "tuantuan.lv <dangoakachan@foxmail.com>" 52 __status__ = "Development" 53 54 __all__ = ['set_logger', 'debug', 'info', 'warning', 'error', 55 'critical', 'exception'] 56 57 import os 58 import sys 59 import logging 60 import logging.handlers 61 62 # Color escape string 63 COLOR_RED='\033[1;31m' 64 COLOR_GREEN='\033[1;32m' 65 COLOR_YELLOW='\033[1;33m' 66 COLOR_BLUE='\033[1;34m' 67 COLOR_PURPLE='\033[1;35m' 68 COLOR_CYAN='\033[1;36m' 69 COLOR_GRAY='\033[1;37m' 70 COLOR_WHITE='\033[1;38m' 71 COLOR_RESET='\033[1;0m' 72 73 # Define log color 74 LOG_COLORS = { 75 'DEBUG': '%s', 76 'INFO': COLOR_GREEN + '%s' + COLOR_RESET, 77 'WARNING': COLOR_YELLOW + '%s' + COLOR_RESET, 78 'ERROR': COLOR_RED + '%s' + COLOR_RESET, 79 'CRITICAL': COLOR_RED + '%s' + COLOR_RESET, 80 'EXCEPTION': COLOR_RED + '%s' + COLOR_RESET, 81 } 82 83 # Global logger 84 g_logger = None 85 86 class ColoredFormatter(logging.Formatter): 87 '''A colorful formatter.''' 88 89 def __init__(self, fmt = None, datefmt = None): 90 logging.Formatter.__init__(self, fmt, datefmt) 91 92 def format(self, record): 93 level_name = record.levelname 94 msg = logging.Formatter.format(self, record) 95 96 return LOG_COLORS.get(level_name, '%s') % msg 97 98 def add_handler(cls, level, fmt, colorful, **kwargs): 99 '''Add a configured handler to the global logger.''' 100 global g_logger 101 102 if isinstance(level, str): 103 level = getattr(logging, level.upper(), logging.DEBUG) 104 105 handler = cls(**kwargs) 106 handler.setLevel(level) 107 108 if colorful: 109 formatter = ColoredFormatter(fmt) 110 else: 111 formatter = logging.Formatter(fmt) 112 113 handler.setFormatter(formatter) 114 g_logger.addHandler(handler) 115 116 return handler 117 118 def add_streamhandler(level, fmt): 119 '''Add a stream handler to the global logger.''' 120 return add_handler(logging.StreamHandler, level, fmt, True) 121 122 def add_filehandler(level, fmt, filename , mode, backup_count, limit, when): 123 '''Add a file handler to the global logger.''' 124 kwargs = {} 125 126 # If the filename is not set, use the default filename 127 if filename is None: 128 filename = getattr(sys.modules['__main__'], '__file__', 'log.py') 129 filename = os.path.basename(filename.replace('.py', '.log')) 130 filename = os.path.join('/tmp', filename) 131 132 kwargs['filename'] = filename 133 134 # Choose the filehandler based on the passed arguments 135 if backup_count == 0: # Use FileHandler 136 cls = logging.FileHandler 137 kwargs['mode' ] = mode 138 elif when is None: # Use RotatingFileHandler 139 cls = logging.handlers.RotatingFileHandler 140 kwargs['maxBytes'] = limit 141 kwargs['backupCount'] = backup_count 142 kwargs['mode' ] = mode 143 else: # Use TimedRotatingFileHandler 144 cls = logging.handlers.TimedRotatingFileHandler 145 kwargs['when'] = when 146 kwargs['interval'] = limit 147 kwargs['backupCount'] = backup_count 148 149 return add_handler(cls, level, fmt, False, **kwargs) 150 151 def init_logger(): 152 '''Reload the global logger.''' 153 global g_logger 154 155 if g_logger is None: 156 g_logger = logging.getLogger() 157 else: 158 logging.shutdown() 159 g_logger.handlers = [] 160 161 g_logger.setLevel(logging.DEBUG) 162 163 def set_logger(filename = None, mode = 'a', level='ERROR:DEBUG', 164 fmt = '[%(levelname)s] %(asctime)s %(message)s', 165 backup_count = 5, limit = 20480, when = None): 166 '''Configure the global logger.''' 167 level = level.split(':') 168 169 if len(level) == 1: # Both set to the same level 170 s_level = f_level = level[0] 171 else: 172 s_level = level[0] # StreamHandler log level 173 f_level = level[1] # FileHandler log level 174 175 init_logger() 176 add_streamhandler(s_level, fmt) 177 add_filehandler(f_level, fmt, filename, mode, backup_count, limit, when) 178 179 # Import the common log functions for convenient 180 import_log_funcs() 181 182 def import_log_funcs(): 183 '''Import the common log functions from the global logger to the module.''' 184 global g_logger 185 186 curr_mod = sys.modules[__name__] 187 log_funcs = ['debug', 'info', 'warning', 'error', 'critical', 188 'exception'] 189 190 for func_name in log_funcs: 191 func = getattr(g_logger, func_name) 192 setattr(curr_mod, func_name, func) 193 194 # Set a default logger 195 set_logger()
原文地址:https://www.oschina.net/code/snippet_813668_14236