Как отключить буфер ведения журнала, чтобы получать журналы в режиме реального времени с помощью инструмента командной строки Python?

#python #python-3.x #logging #argparse

#python #python-3.x #ведение журнала #argparse

Вопрос:

У меня есть инструмент командной строки, который создает множество журналов. Я хочу, чтобы эти журналы отправлялись в stdout , как только они будут созданы. Прямо сейчас программа завершает все (что может занять несколько минут), а затем отправляет все stdout всем сразу. Это означает, что в настоящее время пользователь не знает о том, что происходит внутри, и я хочу это изменить.

До сих пор я пытался передать -u флаг в качестве аргумента командной строки, но это ничего не меняет. У меня такое чувство, что мне нужно использовать logging.handlers.BufferingHandler with flush() в каком-то качестве, но я не смог разобраться с этим путем переделки.

 def some_func(flag: bool):
    if flag:
        logging.info('flag is truthy')
        return
    logging.warning('flag is falsy')
  

Я бы хотел, чтобы вышеупомянутая функция показывала пользователю один из этих журналов, как только журнал будет создан.
Примечание: в настоящее время я устанавливаю уровень ведения журнала с помощью logging.root.setLevel(logging.INFO) .

Спасибо!

Ответ №1:

вы должны установить переменную среды PYTHONUNBUFFERED=1.

Ответ №2:

Используйте StreamHandler в модуле ведения журнала

 import logging

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

# create console handler and set level to debug
ch = logging.StreamHandler()
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.warning('warn message')
logger.error('error message')
logger.critical('critical message')
  

Это приведет к сбросу всех журналов на консоль

 $ python simple_logging_module.py
2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message
2005-03-19 15:10:26,620 - simple_example - INFO - info message
2005-03-19 15:10:26,695 - simple_example - WARNING - warn message
2005-03-19 15:10:26,697 - simple_example - ERROR - error message
2005-03-19 15:10:26,773 - simple_example - CRITICAL - critical message
  

Комментарии:

1. Я немного смущен тем, почему вы просто скопировали и вставили код из здесь , но это решение не создает журналы stdout в режиме реального времени, поэтому, к сожалению, оно не отвечает на вопрос.

2. я использовал тот же обработчик в проектах, он будет передавать все журналы на консоль afaik, можете ли вы предоставить свою конфигурацию ведения журнала? и, кстати, это из официальных документов docs.python.org/3/howto/logging.html#configuring-logging

3. Прямо сейчас единственное место, где я настраиваю ведение журнала, — это logging.root.setLevel(logging.INFO if args.verbose else logging.WARNING) внутри if __name__ == '__main__': блока, после того как я проанализирую другие аргументы командной строки.

4. Пожалуйста, взгляните [сюда] ( docs.python.org/2/howto/logging.html#useful-handlers ). Если вы явно используете MemoryHandler или BufferingHandler , журналы будут отправлены в буфер, а затем вы захотите очистить его. вы говорите, что в OP?

5. Да, сэр, именно это я и говорю. Мне просто нужно как можно скорее получить журналы, когда инструмент запущен.