| 1 | # -*- coding: iso-8859-1 -*- |
|---|
| 2 | # Copyright (c) 2007 LOGILAB S.A. (Paris, FRANCE). |
|---|
| 3 | # http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|---|
| 4 | # |
|---|
| 5 | # This program is free software; you can redistribute it and/or modify |
|---|
| 6 | # it under the terms of the GNU General Public License as published by |
|---|
| 7 | # the Free Software Foundation; either version 2 of the License, or |
|---|
| 8 | # (at your option) any later version. |
|---|
| 9 | # |
|---|
| 10 | # This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 11 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|---|
| 12 | # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details |
|---|
| 13 | # |
|---|
| 14 | # You should have received a copy of the GNU General Public License along with |
|---|
| 15 | # this program; if not, write to the Free Software Foundation, Inc., |
|---|
| 16 | # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|---|
| 17 | """ Copyright (c) 2007 LOGILAB S.A. (Paris, FRANCE). |
|---|
| 18 | http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|---|
| 19 | |
|---|
| 20 | This module provides extensions to the logging module from the standard library. |
|---|
| 21 | """ |
|---|
| 22 | |
|---|
| 23 | import logging |
|---|
| 24 | |
|---|
| 25 | from logilab.common.textutils import colorize_ansi |
|---|
| 26 | |
|---|
| 27 | def xxx_cyan(record): |
|---|
| 28 | if 'XXX' in record.message: |
|---|
| 29 | return 'cyan' |
|---|
| 30 | |
|---|
| 31 | class ColorFormatter(logging.Formatter): |
|---|
| 32 | """ |
|---|
| 33 | A color Formatter for the logging standard module. |
|---|
| 34 | |
|---|
| 35 | By default, colorize CRITICAL and ERROR in red, WARNING in orange |
|---|
| 36 | and INFO in yellow. |
|---|
| 37 | |
|---|
| 38 | self.colors is customizable via the 'color' constructor argument (dictionnary). |
|---|
| 39 | |
|---|
| 40 | self.colorfilters is a list of functions that get the LogRecord |
|---|
| 41 | and return a color name or None. |
|---|
| 42 | """ |
|---|
| 43 | |
|---|
| 44 | def __init__(self, fmt=None, datefmt=None, colors=None): |
|---|
| 45 | logging.Formatter.__init__(self, fmt, datefmt) |
|---|
| 46 | self.colorfilters = [] |
|---|
| 47 | self.colors = {'CRITICAL': 'red', |
|---|
| 48 | 'ERROR': 'red', |
|---|
| 49 | 'WARNING': 'magenta', |
|---|
| 50 | 'INFO': 'yellow', |
|---|
| 51 | } |
|---|
| 52 | if colors is not None: |
|---|
| 53 | assert isinstance(colors, dict) |
|---|
| 54 | self.colors.update(colors) |
|---|
| 55 | |
|---|
| 56 | def format(self, record): |
|---|
| 57 | msg = logging.Formatter.format(self, record) |
|---|
| 58 | if record.levelname in self.colors: |
|---|
| 59 | color = self.colors[record.levelname] |
|---|
| 60 | return colorize_ansi(msg, color) |
|---|
| 61 | else: |
|---|
| 62 | for cf in self.colorfilters: |
|---|
| 63 | color = cf(record) |
|---|
| 64 | if color: |
|---|
| 65 | return colorize_ansi(msg, color) |
|---|
| 66 | return msg |
|---|
| 67 | |
|---|
| 68 | def set_color_formatter(logger=None, **kw): |
|---|
| 69 | """ |
|---|
| 70 | Install a color formatter on the 'logger'. If not given, it will |
|---|
| 71 | defaults to the default logger. |
|---|
| 72 | |
|---|
| 73 | Any additional keyword will be passed as-is to the ColorFormatter |
|---|
| 74 | constructor. |
|---|
| 75 | """ |
|---|
| 76 | if logger is None: |
|---|
| 77 | logger = logging.getLogger() |
|---|
| 78 | if not logger.handlers: |
|---|
| 79 | logging.basicConfig() |
|---|
| 80 | format_msg = logger.handlers[0].formatter._fmt |
|---|
| 81 | fmt = ColorFormatter(format_msg, **kw) |
|---|
| 82 | fmt.colorfilters.append(xxx_cyan) |
|---|
| 83 | logger.handlers[0].setFormatter(fmt) |
|---|