Как отправить сообщение журнала INFO и DEBUG на стандартный вывод и сообщение более высокого уровня на стандартный вывод? - PullRequest
25 голосов
/ 20 февраля 2010

Есть ли простой способ с модулем регистрации Python для отправки сообщений с уровнем DEBUG или INFO и с более высоким уровнем в разные потоки?

В любом случае, это хорошая идея?

Ответы [ 6 ]

28 голосов
/ 16 июля 2015
import logging
import sys

class LessThanFilter(logging.Filter):
    def __init__(self, exclusive_maximum, name=""):
        super(LessThanFilter, self).__init__(name)
        self.max_level = exclusive_maximum

    def filter(self, record):
        #non-zero return means we log this message
        return 1 if record.levelno < self.max_level else 0

#Get the root logger
logger = logging.getLogger()
#Have to set the root logger level, it defaults to logging.WARNING
logger.setLevel(logging.NOTSET)

logging_handler_out = logging.StreamHandler(sys.stdout)
logging_handler_out.setLevel(logging.DEBUG)
logging_handler_out.addFilter(LessThanFilter(logging.WARNING))
logger.addHandler(logging_handler_out)

logging_handler_err = logging.StreamHandler(sys.stderr)
logging_handler_err.setLevel(logging.WARNING)
logger.addHandler(logging_handler_err)

#demonstrate the logging levels
logger.debug('DEBUG')
logger.info('INFO')
logger.warning('WARNING')
logger.error('ERROR')
logger.critical('CRITICAL')

За исключением реализации, я думаю, что это хорошая идея - использовать средства ведения журналов в python для вывода на терминал, в частности, потому что вы можете добавить другой обработчик для дополнительного входа в файл.Если вы установите для stdout значение INFO, а не DEBUG, вы можете даже включить дополнительную информацию DEBUG, которую пользователь обычно не видит в файле журнала.

6 голосов
/ 20 февраля 2010

Да. Вы должны определить несколько обработчиков для вашей регистрации.

http://docs.python.org/library/logging.html#logging-to-multiple-destinations

http://docs.python.org/library/logging.handlers.html#module-logging.handlers

5 голосов
/ 17 мая 2013

У меня была та же проблема, и я написал собственный обработчик журналирования под названием SplitStreamHandler:

import sys
import logging

class SplitStreamHandler(logging.Handler):
    def __init__(self):
        logging.Handler.__init__(self)

    def emit(self, record):
        # mostly copy-paste from logging.StreamHandler
        try:
            msg = self.format(record)
            if record.levelno < logging.WARNING:
                stream = sys.stdout
            else:
                stream = sys.stderr
            fs = "%s\n"

            try:
                if (isinstance(msg, unicode) and
                    getattr(stream, 'encoding', None)):
                    ufs = fs.decode(stream.encoding)
                    try:
                        stream.write(ufs % msg)
                    except UnicodeEncodeError:
                        stream.write((ufs % msg).encode(stream.encoding))
                else:
                    stream.write(fs % msg)
            except UnicodeError:
                stream.write(fs % msg.encode("UTF-8"))

            stream.flush()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)
2 голосов
/ 17 февраля 2012

прямо из обновленных документов, теперь это дело довольно хорошо.

http://docs.python.org/howto/logging.html#logging-advanced-tutorial

import sys # Add this.
import logging

# create logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)

# create console handler and set level to debug
ch = logging.StreamHandler( sys.__stdout__ ) # Add this
ch.setLevel(logging.DEBUG)

# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# add formatter to ch
ch.setFormatter(formatter)

# add ch to logger
logger.addHandler(ch)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

Я упомянул в комментариях два изменения, которые необходимо выполнить в примере, чтобы вывод выводился в стандартный вывод. Вы также можете использовать фильтры для перенаправления в зависимости от уровня.

больше информации, чтобы понять изменения в http://docs.python.org/library/logging.handlers.html#module-logging.handlers

1 голос
/ 20 февраля 2010

Не обязательно хорошая идея (может показаться смешанным, что информация и сообщения отладки смешиваются с обычным выводом!), Но выполнимо, так как вы можете иметь несколько объектов-обработчиков и пользовательский фильтр для каждого из их, чтобы выбрать, какие записи журнала должен обрабатывать каждый обработчик.

0 голосов
/ 31 июля 2015
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import logging
import sys

class LessThenFilter(logging.Filter):
    def __init__(self, level):
        self._level = level
        logging.Filter.__init__(self)

    def filter(self, rec):
        return rec.levelno < self._level

log = logging.getLogger()
log.setLevel(logging.NOTSET)

sh_out = logging.StreamHandler(stream=sys.stdout)
sh_out.setLevel(logging.DEBUG)
sh_out.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
sh_out.addFilter(LessThenFilter(logging.WARNING))
log.addHandler(sh_out)

sh_err = logging.StreamHandler(stream=sys.stderr)
sh_err.setLevel(logging.WARNING)
sh_err.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
log.addHandler(sh_err)

logging.critical('x')
logging.error('x')
logging.warning('x')
logging.info('x')
logging.debug('x')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...