Source code for oio.common.logger

# Copyright (C) 2017 OpenIO SAS, as part of OpenIO SDS
#
# This library 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 3.0 of the License, or (at your option) any later version.
#
# This library 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 this library.

import os
import sys
import socket
import errno
import logging
from logging.handlers import SysLogHandler


[docs]class StreamToLogger(object): def __init__(self, logger, log_type='STDOUT'): self.logger = logger self.log_type = log_type
[docs] def write(self, value): value = value.strip() if value: self.logger.error('%s : %s', self.log_type, value)
[docs] def writelines(self, values): self.logger.error('%s : %s', self.log_type, '#012'.join(values))
[docs] def close(self): pass
[docs] def flush(self): pass
[docs]def redirect_stdio(logger): """ Close stdio, redirect stdout and stderr. :param logger: """ sys.excepthook = lambda * exc_info: \ logger.critical('UNCAUGHT EXCEPTION', exc_info=exc_info) stdio_fd = [sys.stdin, sys.stdout, sys.stderr] console_fds = [h.stream.fileno() for _, h in getattr( get_logger, 'console_handler4logger', {}).items()] stdio_fd = [fd for fd in stdio_fd if fd.fileno() not in console_fds] with open(os.devnull, 'r+b') as nullfile: for fd in stdio_fd: try: fd.flush() except IOError: pass try: os.dup2(nullfile.fileno(), fd.fileno()) except OSError: pass sys.stdout = StreamToLogger(logger) sys.stderr = StreamToLogger(logger, 'STDERR')
[docs]def get_logger( conf, name=None, verbose=False, fmt="%(process)d %(thread)X %(name)s %(levelname)s %(message)s"): if not conf: conf = {} if name is None: name = 'log' logger = logging.getLogger(name) logger.propagate = False syslog_prefix = conf.get('syslog_prefix', '') formatter = logging.Formatter(fmt=fmt) if syslog_prefix: fmt = '%s: %s' % (syslog_prefix, fmt) syslog_formatter = logging.Formatter(fmt=fmt) if not hasattr(get_logger, 'handler4logger'): get_logger.handler4logger = {} if logger in get_logger.handler4logger: logger.removeHandler(get_logger.handler4logger[logger]) facility = getattr(SysLogHandler, conf.get('log_facility', 'LOG_LOCAL0'), SysLogHandler.LOG_LOCAL0) log_address = conf.get('log_address', '/dev/log') try: handler = SysLogHandler(address=log_address, facility=facility) except socket.error as exc: if exc.errno not in [errno.ENOTSOCK, errno.ENOENT]: raise exc handler = SysLogHandler(facility=facility) handler.setFormatter(syslog_formatter) logger.addHandler(handler) get_logger.handler4logger[logger] = handler logging_level = getattr(logging, conf.get('log_level', 'INFO').upper(), logging.INFO) if (verbose or conf.get('is_cli') or hasattr(get_logger, 'console_handler4logger') or logging_level < logging.INFO): if not hasattr(get_logger, 'console_handler4logger'): get_logger.console_handler4logger = {} if logger in get_logger.console_handler4logger: logger.removeHandler(get_logger.console_handler4logger[logger]) console_handler = logging.StreamHandler(sys.__stderr__) console_handler.setFormatter(formatter) logger.addHandler(console_handler) get_logger.console_handler4logger[logger] = console_handler logger.setLevel(logging_level) return logger