Package logilab :: Package common :: Module logging_ext
[frames] | no frames]

Source Code for Module logilab.common.logging_ext

  1  # -*- coding: utf-8 -*- 
  2   
  3  """Extends the logging module from the standard library. 
  4   
  5  :copyright: 2000-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 
  6  :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr 
  7  :license: General Public License version 2 - http://www.gnu.org/licenses 
  8  """ 
  9  __docformat__ = "restructuredtext en" 
 10   
 11  import os 
 12  import sys 
 13  import logging 
 14   
 15  from logilab.common.textutils import colorize_ansi 
 16   
 17   
18 -def set_log_methods(cls, logger):
19 """bind standard logger's methods as methods on the class""" 20 cls.__logger = logger 21 for attr in ('debug', 'info', 'warning', 'error', 'critical', 'exception'): 22 setattr(cls, attr, getattr(logger, attr))
23 24
25 -def xxx_cyan(record):
26 if 'XXX' in record.message: 27 return 'cyan'
28
29 -class ColorFormatter(logging.Formatter):
30 """ 31 A color Formatter for the logging standard module. 32 33 By default, colorize CRITICAL and ERROR in red, WARNING in orange, INFO in 34 green and DEBUG in yellow. 35 36 self.colors is customizable via the 'color' constructor argument (dictionary). 37 38 self.colorfilters is a list of functions that get the LogRecord 39 and return a color name or None. 40 """ 41
42 - def __init__(self, fmt=None, datefmt=None, colors=None):
43 logging.Formatter.__init__(self, fmt, datefmt) 44 self.colorfilters = [] 45 self.colors = {'CRITICAL': 'red', 46 'ERROR': 'red', 47 'WARNING': 'magenta', 48 'INFO': 'green', 49 'DEBUG': 'yellow', 50 } 51 if colors is not None: 52 assert isinstance(colors, dict) 53 self.colors.update(colors)
54
55 - def format(self, record):
56 msg = logging.Formatter.format(self, record) 57 if record.levelname in self.colors: 58 color = self.colors[record.levelname] 59 return colorize_ansi(msg, color) 60 else: 61 for cf in self.colorfilters: 62 color = cf(record) 63 if color: 64 return colorize_ansi(msg, color) 65 return msg
66
67 -def set_color_formatter(logger=None, **kw):
68 """ 69 Install a color formatter on the 'logger'. If not given, it will 70 defaults to the default logger. 71 72 Any additional keyword will be passed as-is to the ColorFormatter 73 constructor. 74 """ 75 if logger is None: 76 logger = logging.getLogger() 77 if not logger.handlers: 78 logging.basicConfig() 79 format_msg = logger.handlers[0].formatter._fmt 80 fmt = ColorFormatter(format_msg, **kw) 81 fmt.colorfilters.append(xxx_cyan) 82 logger.handlers[0].setFormatter(fmt)
83 84 85 LOG_FORMAT = '%(asctime)s - (%(name)s) %(levelname)s: %(message)s' 86 LOG_DATE_FORMAT = '%Y-%m-%d %H:%M:%S' 87
88 -def init_log(debug=False, syslog=False, logthreshold=None, logfile=None, 89 logformat=LOG_FORMAT, logdateformat=LOG_DATE_FORMAT):
90 """init the log service""" 91 if os.environ.get('APYCOT_ROOT'): 92 logthreshold = logging.CRITICAL 93 # redirect logs to stdout to avoid apycot output parsing failure 94 handler = logging.StreamHandler(sys.stdout) 95 else: 96 if debug: 97 handler = logging.StreamHandler() 98 elif logfile is None: 99 if syslog: 100 from logging import handlers 101 handler = handlers.SysLogHandler() 102 else: 103 handler = logging.StreamHandler() 104 else: 105 try: 106 handler = logging.FileHandler(logfile) 107 except IOError: 108 handler = logging.StreamHandler() 109 if logthreshold is None: 110 logthreshold = logging.ERROR 111 elif isinstance(logthreshold, basestring): 112 logthreshold = getattr(logging, THRESHOLD_MAP.get(logthreshold, 113 logthreshold)) 114 # configure the root logger 115 logger = logging.getLogger() 116 logger.setLevel(logthreshold) 117 # only addHandler and removeHandler method while I would like a 118 # setHandler method, so do it this way :$ 119 logger.handlers = [handler] 120 isatty = hasattr(sys.__stdout__, 'isatty') and sys.__stdout__.isatty() 121 if debug and isatty and sys.platform != 'win32': 122 fmt = ColorFormatter(logformat, logdateformat) 123 def col_fact(record): 124 if 'XXX' in record.message: 125 return 'cyan' 126 if 'kick' in record.message: 127 return 'red'
128 fmt.colorfilters.append(col_fact) 129 else: 130 fmt = logging.Formatter(logformat, logdateformat) 131 handler.setFormatter(fmt) 132 return handler 133 134 # map logilab.common.logger thresholds to logging thresholds 135 THRESHOLD_MAP = {'LOG_DEBUG': 'DEBUG', 136 'LOG_INFO': 'INFO', 137 'LOG_NOTICE': 'INFO', 138 'LOG_WARN': 'WARNING', 139 'LOG_WARNING': 'WARNING', 140 'LOG_ERR': 'ERROR', 141 'LOG_ERROR': 'ERROR', 142 'LOG_CRIT': 'CRITICAL', 143 } 144