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

Source Code for Module logilab.common.logging_ext

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