import os import sys import logging import logging.handlers import cStringIO import traceback from alerta.common import config CONF = config.CONF _DEFAULT_LOG_FORMAT = "%(asctime)s.%(msecs).03d %(name)s[%(process)d] %(threadName)s %(levelname)s - %(message)s" _DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" log_opts = { 'syslog_facility': 'local7', } def _create_logging_excepthook(name): def logging_excepthook(type, value, tb): stringbuffer = cStringIO.StringIO() traceback.print_exception(type, value, tb, None, stringbuffer) lines = stringbuffer.getvalue() stringbuffer.close() getLogger(name).critical(lines) return logging_excepthook def setup(name): """Setup logging.""" config.register_opts(log_opts) sys.excepthook = _create_logging_excepthook(name) log_root = getLogger(name) if CONF.use_syslog: facility = CONF.syslog_facility try: syslog = logging.handlers.SysLogHandler(address='/dev/log', facility=facility) except IOError: pass else: log_root.addHandler(syslog) logpath = _get_log_file_path() if logpath: try: filelog = logging.handlers.WatchedFileHandler(logpath, encoding='utf-8') except IOError: raise log_root.addHandler(filelog) # TODO(nsatterl): test mode like openstack?? for handler in log_root.handlers: log_format = _DEFAULT_LOG_FORMAT date_format = _DEFAULT_LOG_DATE_FORMAT handler.setFormatter(logging.Formatter(fmt=log_format, datefmt=date_format)) if CONF.use_stderr: streamlog = ColorHandler() color_fmt = logging.Formatter("%(color)s" + _DEFAULT_LOG_FORMAT + "\033[0m") streamlog.setFormatter(color_fmt) log_root.addHandler(streamlog) if CONF.debug: log_root.setLevel(logging.DEBUG) elif CONF.verbose: log_root.setLevel(logging.INFO) else: log_root.setLevel(logging.WARNING) def getLogger(name=None): if name: return logging.getLogger(name) else: return logging.root def set_owner(uid=-1, gid=-1): return os.chown(_get_log_file_path(), uid, gid) def _get_prog_name(): return os.path.basename(sys.argv[0]) def _get_log_file_path(): logfile = CONF.log_file logdir = CONF.log_dir if logfile and not logdir: return logfile if logfile and logdir: return os.path.join(logdir, logfile) if logdir: prog = _get_prog_name() return '%s.log' % (os.path.join(logdir, prog)) class ColorHandler(logging.StreamHandler): # XXX - OpenStack colours for reference # # LEVEL_COLORS = { # logging.NOTSET: '', # logging.DEBUG: '\033[00;32m', # GREEN # logging.INFO: '\033[00;36m', # CYAN # #logging.AUDIT: '\033[01;36m', # BOLD CYAN # logging.WARN: '\033[01;33m', # BOLD YELLOW # logging.ERROR: '\033[01;31m', # BOLD RED # logging.CRITICAL: '\033[01;31m', # BOLD RED # } LEVEL_COLORS = { logging.NOTSET: '', logging.DEBUG: '\033[90m', # BLACK logging.INFO: '\033[92m', # GREEN logging.WARN: '\033[96m', # CYAN logging.ERROR: '\033[93m', # YELLOW logging.CRITICAL: '\033[91m', # RED } def format(self, record): record.color = self.LEVEL_COLORS[record.levelno] return logging.StreamHandler.format(self, record)