def enable_system_logging(programname=None, fmt=None, logger=None, reconfigure=True, **kw): """ Redirect :mod:`logging` messages to the system log (e.g. ``/var/log/syslog``). :param programname: The program name to embed in log messages (a string, defaults to the result of :func:`~coloredlogs.find_program_name()`). :param fmt: The log format for system log messages (a string, defaults to :data:`DEFAULT_LOG_FORMAT`). :param logger: The logger to which the :class:`~logging.handlers.SysLogHandler` should be connected (defaults to the root logger). :param level: The logging level for the :class:`~logging.handlers.SysLogHandler` (defaults to :data:`.DEFAULT_LOG_LEVEL`). This value is coerced using :func:`~coloredlogs.level_to_number()`. :param reconfigure: If :data:`True` (the default) multiple calls to :func:`enable_system_logging()` will each override the previous configuration. :param kw: Refer to :func:`connect_to_syslog()`. :returns: A :class:`~logging.handlers.SysLogHandler` object or :data:`None`. If an existing handler is found and `reconfigure` is :data:`False` the existing handler object is returned. If the connection to the system logging daemon fails :data:`None` is returned. .. note:: When the logger's effective level is too restrictive it is relaxed (refer to `notes about log levels`_ for details). """ # Provide defaults for omitted arguments. programname = programname or find_program_name() logger = logger or logging.getLogger() fmt = fmt or DEFAULT_LOG_FORMAT level = level_to_number(kw.get('level', DEFAULT_LOG_LEVEL)) # Check whether system logging is already enabled. handler, logger = replace_handler(logger, match_syslog_handler, reconfigure) # Make sure reconfiguration is allowed or not relevant. if not (handler and not reconfigure): # Create a system logging handler. handler = connect_to_syslog(**kw) # Make sure the handler was successfully created. if handler: # Enable the use of %(programname)s. ProgramNameFilter.install(handler=handler, fmt=fmt, programname=programname) # Connect the formatter, handler and logger. handler.setFormatter(logging.Formatter(fmt)) logger.addHandler(handler) # Adjust the level of the selected logger. adjust_level(logger, level) return handler
def connect_to_syslog(address=None, facility=None, level=None): """ Create a :class:`~logging.handlers.SysLogHandler`. :param address: The device file or network address of the system logging daemon (a string or tuple, defaults to the result of :func:`find_syslog_address()`). :param facility: Refer to :class:`~logging.handlers.SysLogHandler`. Defaults to ``LOG_USER``. :param level: The logging level for the :class:`~logging.handlers.SysLogHandler` (defaults to :data:`.DEFAULT_LOG_LEVEL`). This value is coerced using :func:`~coloredlogs.level_to_number()`. :returns: A :class:`~logging.handlers.SysLogHandler` object or :data:`None` (if the system logging daemon is unavailable). The process of connecting to the system logging daemon goes as follows: - If :class:`~logging.handlers.SysLogHandler` supports the `socktype` option (it does since Python 2.7) the following two socket types are tried (in decreasing preference): 1. :data:`~socket.SOCK_RAW` avoids truncation of log messages but may not be supported. 2. :data:`~socket.SOCK_STREAM` (TCP) supports longer messages than the default (which is UDP). - If socket types are not supported Python's (2.6) defaults are used to connect to the selected `address`. """ if not address: address = find_syslog_address() if facility is None: facility = logging.handlers.SysLogHandler.LOG_USER if level is None: level = DEFAULT_LOG_LEVEL for socktype in socket.SOCK_RAW, socket.SOCK_STREAM, None: kw = dict(facility=facility, address=address) if socktype is not None: kw['socktype'] = socktype try: handler = logging.handlers.SysLogHandler(**kw) except (IOError, TypeError): # The socktype argument was added in Python 2.7 and its use will raise a # TypeError exception on Python 2.6. IOError is a superclass of socket.error # (since Python 2.6) which can be raised if the system logging daemon is # unavailable. pass else: handler.setLevel(level_to_number(level)) return handler
def test_level_to_number(self): """Make sure :func:`level_to_number()` works as intended.""" # Make sure the default levels are translated as expected. assert level_to_number('debug') == logging.DEBUG assert level_to_number('info') == logging.INFO assert level_to_number('warning') == logging.WARNING assert level_to_number('error') == logging.ERROR assert level_to_number('fatal') == logging.FATAL # Make sure bogus level names don't blow up. assert level_to_number('bogus-level') == logging.INFO
def test_level_to_number(self): """Make sure :func:`level_to_number()` works as intended.""" # Make sure the default levels are translated as expected. assert level_to_number('debug') == logging.DEBUG assert level_to_number('info') == logging.INFO assert level_to_number('warning') == logging.WARNING assert level_to_number('error') == logging.ERROR assert level_to_number('fatal') == logging.FATAL # Make sure bogus level names don't blow up. assert level_to_number('bogus-level') == logging.INFO
def enable_system_logging(programname=None, fmt=None, logger=None, reconfigure=True, **kw): """ Redirect :mod:`logging` messages to the system log (e.g. ``/var/log/syslog``). :param programname: The program name to embed in log messages (a string, defaults to the result of :func:`~coloredlogs.find_program_name()`). :param fmt: The log format for system log messages (a string, defaults to :data:`DEFAULT_LOG_FORMAT`). :param logger: The logger to which the :class:`~logging.handlers.SysLogHandler` should be connected (defaults to the root logger). :param level: The logging level for the :class:`~logging.handlers.SysLogHandler` (defaults to :data:`.DEFAULT_LOG_LEVEL`). This value is coerced using :func:`~coloredlogs.level_to_number()`. :param reconfigure: If :data:`True` (the default) multiple calls to :func:`enable_system_logging()` will each override the previous configuration. :param kw: Refer to :func:`connect_to_syslog()`. :returns: A :class:`~logging.handlers.SysLogHandler` object or :data:`None`. If an existing handler is found and `reconfigure` is :data:`False` the existing handler object is returned. If the connection to the system logging daemon fails :data:`None` is returned. .. note:: When the logger's effective level is too restrictive it is relaxed (refer to `notes about log levels`_ for details). """ # Provide defaults for omitted arguments. programname = programname or find_program_name() logger = logger or logging.getLogger() fmt = fmt or DEFAULT_LOG_FORMAT level = level_to_number(kw.get('level', DEFAULT_LOG_LEVEL)) # Check whether system logging is already enabled. handler, logger = replace_handler(logger, match_syslog_handler, reconfigure) # Make sure reconfiguration is allowed or not relevant. if not (handler and not reconfigure): # Create a system logging handler. handler = connect_to_syslog(**kw) # Make sure the handler was successfully created. if handler: # Enable the use of %(programname)s. ProgramNameFilter.install(handler=handler, fmt=fmt, programname=programname) # Connect the formatter, handler and logger. handler.setFormatter(logging.Formatter(fmt)) logger.addHandler(handler) # Adjust the level of the selected logger. adjust_level(logger, level) return handler