7

Настройка логирования в Python: вывод всех сообщений в stdout и файл журнала

1

Как решить проблему с логированием в Python с использованием модуля logging? Мне нужно, чтобы все сообщения автоматически выводились как в файл журнала, так и в stdout. Например, я хочу, чтобы все вызовы logger.warning, logger.critical, logger.error записывались в соответствующие места, но при этом дублировались в stdout. Это нужно для того, чтобы избежать переписывания сообщений, как в следующем примере:

mylogger.critical("что-то не удалось")
print("что-то не удалось")

Хотелось бы узнать, как это можно реализовать?

5 ответ(ов)

0

Да, это возможно с использованием нескольких обработчиков (handlers) в модуле logging. Ниже представлен пример, который демонстрирует создание логгера с записью логов как в файл, так и в консоль с разными уровнями детализации.

import logging
import auxiliary_module

# создаем логгер с именем 'spam_application'
log = logging.getLogger('spam_application')
log.setLevel(logging.DEBUG)

# создаем форматтер и добавляем его к обработчикам
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# создаем обработчик для записи логов в файл, который будет фиксировать даже сообщения отладочного уровня
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
log.addHandler(fh)

# создаем обработчик для вывода логов в консоль с более высоким уровнем
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
ch.setFormatter(formatter)
log.addHandler(ch)

log.info('создание экземпляра auxiliary_module.Auxiliary')
a = auxiliary_module.Auxiliary()
log.info('экземпляр auxiliary_module.Auxiliary создан')

log.info('вызов auxiliary_module.Auxiliary.do_something')
a.do_something()
log.info('завершен вызов auxiliary_module.Auxiliary.do_something')

log.info('вызов auxiliary_module.some_function()')
auxiliary_module.some_function()
log.info('вызов auxiliary_module.some_function() завершен')

# не забудьте закрыть обработчики
for handler in log.handlers:
    handler.close()
    log.removeFilter(handler)

Обратите внимание, что мы используем FileHandler, чтобы записывать все сообщения уровня DEBUG и выше в файл spam.log, и StreamHandler, чтобы выводить только сообщения уровня ERROR и выше в консоль. Это позволяет гибко управлять тем, какие сообщения вы хотите фиксировать и отображать. Подробности можно найти в документации Python.

0

Для того чтобы просто записывать логи как в файл, так и в стандартный поток ошибок (stderr), вы можете использовать следующий код:

import logging

# Настройка базовой конфигурации логирования с указанием файла
logging.basicConfig(filename="logfile.txt")

# Создаем обработчик для вывода логов на stderr
stderrLogger = logging.StreamHandler()
stderrLogger.setFormatter(logging.Formatter(logging.BASIC_FORMAT))

# Добавляем обработчик stderr к корневому логгеру
logging.getLogger().addHandler(stderrLogger)

Этот код сначала настраивает логирование в файл logfile.txt, а затем создает дополнительный обработчик, который выводит логи в стандартный поток ошибок. Таким образом, вы получите логи как в файл, так и в консоль.

0

Поскольку никто не поделился компактным двустрочным решением, я решил представить своё:

logging.basicConfig(filename='logs.log', level=logging.DEBUG, format="%(asctime)s:%(levelname)s: %(message)s")
logging.getLogger().addHandler(logging.StreamHandler())

Этот код настраивает логирование в файл logs.log с уровнем отладки и добавляет потоковый обработчик для вывода логов в консоль.

0

Вот крайне простой пример использования модуля logging в Python:

import logging
l = logging.getLogger("test")

# Добавляем обработчик для записи в файл
f = logging.FileHandler("test.log")
l.addHandler(f)

# Добавляем обработчик для вывода в поток (stdout)
s = logging.StreamHandler()
l.addHandler(s)

# Отправляем тестовое сообщение в оба обработчика — уровень "critical" всегда будет логироваться
l.critical("test msg")

Вывод будет показывать сообщение "test msg" как в стандартном выводе (stdout), так и в файле test.log.

0

Вот простой, но явный способ настроить логирование в Python:

import logging
import sys

# Создаем логгер с именем текущего модуля
logger: logging.Logger = logging.getLogger(__name__)

# Добавляем обработчик для записи логов в файл
logger.addHandler(logging.FileHandler(f"{__name__}.log"))
# Добавляем обработчик для вывода логов в стандартный вывод
logger.addHandler(logging.StreamHandler(sys.stdout))

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь