python-протоколирование stdout, но получение второй пустой строки для каждой записи


Я нахожусь на Linux Ubuntu 12.04 системы. Я использую этот код для регистрации всех stdout и stderr + дополнительных записей на информационном уровне в файл..

class LogFile(object):
    def __init__(self, name=None):
        self.logger = logging.getLogger(name)

    def write(self, msg, level=logging.INFO):
        self.logger.log(level, msg)

    def flush(self):
        for handler in self.logger.handlers:
            handler.flush()

logging.basicConfig(level=logging.INFO, 
                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
                    datefmt='%m-%d-%y %H:%M:%S',
                    filename='logging.log')
sys.stdout = LogFile('stdout')
sys.stderr = LogFile('stderr')

По какой-то причине всякий раз, когда я получаю запись, за ней всегда следует пустая строка, вот небольшой вывод моего журнала:

08-09-12 09:52:54 stdout       INFO     CheckCon: Checking Portal access.
08-09-12 09:52:54 stdout       INFO     

08-09-12 09:52:54 stdout       INFO     CheckCon: Portal ping successful.
08-09-12 09:52:54 stdout       INFO     

08-09-12 09:53:08 stderr       INFO     Bottle server starting up (using PasteServer())...

08-09-12 09:53:08 stderr       INFO     Listening on http://0.0.0.0:8654/

08-09-12 09:53:08 stderr       INFO     Hit Ctrl-C to quit.


08-09-12 09:53:08 stdout       INFO     URI: Generated https://*****
08-09-12 09:53:08 stdout       INFO     

08-09-12 09:53:08 stdout       INFO     CheckCon: Checking Portal access.
08-09-12 09:53:08 stdout       INFO     

08-09-12 09:53:08 stdout       INFO     serving on 0.0.0.0:8654 view at http://127.0.0.1:8654
08-09-12 09:53:08 stdout       INFO     

08-09-12 09:53:08 stdout       INFO     CheckCon: Google ping successful.
08-09-12 09:53:08 stdout       INFO     

Вот как это выглядит в файле, с пустой строкой stdout, а затем следует целая пустая строка. Если вы заметили, что выходные данные с сервера бутылок, кажется, не имеют пустой строки, но все еще a пустая строка между каждой строкой.

Кто-нибудь знает, что является причиной этого или как я могу предотвратить это ?

Правка:

Из предложений я изменил всю свою печать на logging.info, у меня все еще есть проблема, что сервер bottle and paste делает регулярные печати:

Итак, мой журнал теперь с измененным форматом format='%(asctime)s %(levelname)-4s: %(message)s':

08-09-12 12:44:40 INFO: URI: Generated https://****
08-09-12 12:44:40 INFO: CheckCon: Checking Portal access.
08-09-12 12:44:40 INFO: serving on 0.0.0.0:9002 view at http://127.0.0.1:9002
08-09-12 12:44:40 INFO: 

08-09-12 12:44:40 INFO: CheckCon: Google ping successful.
08-09-12 12:44:40 INFO: FullW: opening url: ****
08-09-12 12:44:40 INFO: FullW: showing.
08-09-12 12:44:40 INFO: LOOP: starting.

Из того, что я вижу, дополнительная пустая строка также из-за пустой информационной строки, так что теперь ближе..

Правка для уточнения вывода: То интересное:

+++08-09-12 13:01:04 stdout       INFO     serving on 0.0.0.0:9002 view at     http://127.0.0.1:9002+++
+++08-09-12 13:01:04 stdout       INFO     
+++

Окончательное Редактирование:

Изменил запись, чтобы проверить, если длина msg меньше 2 символов, и это устранило пустые строки.. хотя все еще не уверен на 100% в причине.

def write(self, msg, level=logging.INFO):
    if len(msg) < 2:
        pass
    else:
        self.logger.log(level, msg)
2 2

2 ответа:

Это связано с тем, как работает print.

Я изменил ваш пример так, что у меня есть print (level, msg) в методе write().

Он показывает мне следующее:

>>> x=LogFile("foo")
>>> print >>x, "123\n321\n444", "321", "222",
(20, '123\n321\n444')
(20, ' ')
(20, '321')
(20, ' ')
(20, '222')
>>> print >>x, "123\n321\n444", "321", "222"
(20, ' ')
(20, '123\n321\n444')
(20, ' ')
(20, '321')
(20, ' ')
(20, '222')
(20, '\n')
И если каждый из этих вызовов передается в вызов logger, Вы получаете запись для каждого из них. Чтобы справиться с этим, вы можете реализовать своего рода буферизацию, которая вызывает только logger.log() для полных строк и при закрытии.

Что я могу думать, так это то, что вы перезаписываете sys.stdout, фактическая команда, пишущая строки журнала, будет иметь добавленную новую строку: sys.stdout.write("log text\n"). Модуль/методы ведения журнала сами добавят новую строку, поэтому вы получите две новые строки.

, который, однако, должен показывать только совершенно пустую строку, а не пустую строку с только <date> <name> <level>. Это может быть вызвано одиночными sys.stdout.write("\n") утверждениями в другом месте.

Самый простой способ, который я могу придумать, чтобы предотвратить это, - это удалить новую строку из msg, и проверьте, пусто ли сообщение. Не самый красивый, но если это работает, то новая строка, вероятно, является причиной, и вы могли бы работать оттуда:
def write(self, msg, level=logging.INFO):
    msg = msg.rstrip("\n")
    if msg:
        self.logger.log(level, msg)