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
示例#2
0
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
示例#3
0
 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
示例#4
0
 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
示例#5
0
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