【python】Python的logging模块封装

时间:2021-11-20 22:03:25
  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