# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
#
# logilab-common is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option) any
# later version.
#
# logilab-common is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with logilab-common. If not, see <http://www.gnu.org/licenses/>.
"""Extends the logging module from the standard library."""
__docformat__ = "restructuredtext en"
import os
import sys
import logging
from logilab.common.textutils import colorize_ansi
[docs]def set_log_methods(cls, logger):
"""bind standard logger's methods as methods on the class"""
cls.__logger = logger
for attr in ("debug", "info", "warning", "error", "critical", "exception"):
setattr(cls, attr, getattr(logger, attr))
[docs]def xxx_cyan(record):
if "XXX" in record.message:
return "cyan"
LOG_FORMAT = "%(asctime)s - (%(name)s) %(levelname)s: %(message)s"
LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
[docs]def get_handler(debug=False, syslog=False, logfile=None, rotation_parameters=None):
"""get an apropriate handler according to given parameters"""
if os.environ.get("APYCOT_ROOT"):
handler = logging.StreamHandler(sys.stdout)
if debug:
handler = logging.StreamHandler()
elif logfile is None:
if syslog:
from logging import handlers
handler = handlers.SysLogHandler()
else:
handler = logging.StreamHandler()
else:
try:
if rotation_parameters is None:
if os.name == "posix" and sys.version_info >= (2, 6):
from logging.handlers import WatchedFileHandler
handler = WatchedFileHandler(logfile)
else:
handler = logging.FileHandler(logfile)
else:
from logging.handlers import TimedRotatingFileHandler
handler = TimedRotatingFileHandler(logfile, **rotation_parameters)
except OSError:
handler = logging.StreamHandler()
return handler
[docs]def get_threshold(debug=False, logthreshold=None):
if logthreshold is None:
if debug:
logthreshold = logging.DEBUG
else:
logthreshold = logging.ERROR
elif isinstance(logthreshold, str):
logthreshold = getattr(logging, THRESHOLD_MAP.get(logthreshold, logthreshold))
return logthreshold
def _colorable_terminal():
isatty = hasattr(sys.__stdout__, "isatty") and sys.__stdout__.isatty()
if not isatty:
return False
if os.name == "nt":
try:
from colorama import init as init_win32_colors
except ImportError:
return False
init_win32_colors()
return True
[docs]def init_log(
debug=False,
syslog=False,
logthreshold=None,
logfile=None,
logformat=LOG_FORMAT,
logdateformat=LOG_DATE_FORMAT,
fmt=None,
rotation_parameters=None,
handler=None,
):
"""init the log service"""
logger = logging.getLogger()
if handler is None:
handler = get_handler(debug, syslog, logfile, rotation_parameters)
# only addHandler and removeHandler method while I would like a setHandler
# method, so do it this way :$
logger.handlers = [handler]
logthreshold = get_threshold(debug, logthreshold)
logger.setLevel(logthreshold)
if fmt is None:
if debug:
fmt = get_formatter(logformat=logformat, logdateformat=logdateformat)
else:
fmt = logging.Formatter(logformat, logdateformat)
handler.setFormatter(fmt)
return handler
# map logilab.common.logger thresholds to logging thresholds
THRESHOLD_MAP = {
"LOG_DEBUG": "DEBUG",
"LOG_INFO": "INFO",
"LOG_NOTICE": "INFO",
"LOG_WARN": "WARNING",
"LOG_WARNING": "WARNING",
"LOG_ERR": "ERROR",
"LOG_ERROR": "ERROR",
"LOG_CRIT": "CRITICAL",
}