У меня есть небольшой проект Python, который имеет следующую структуру -
Project
-- pkg01
-- test01.py
-- pkg02
-- test02.py
-- logging.conf
Я планирую использовать модуль регистрации по умолчанию для печати сообщений на стандартный вывод и файл журнала. Для использования модуля регистрации требуется некоторая инициализация -
import logging.config
logging.config.fileConfig('logging.conf')
logger = logging.getLogger('pyApp')
logger.info('testing')
В настоящее время я выполняю эту инициализацию в каждом модуле, прежде чем начать регистрировать сообщения. Можно ли выполнить эту инициализацию только один раз в одном месте, чтобы одни и те же настройки использовались повторно при ведении журнала по всему проекту?
fileConfig
каждый модуль, который ведет журналирование, если у вас нетif __name__ == '__main__'
логики во всех из них. Ответ prost не является хорошей практикой, если пакет является библиотекой, хотя он может работать для вас - не следует настраивать ведение журнала в пакетах библиотек, кроме добавления aNullHandler
.package/__init__.py
. Обычно это не то место, куда вы помещаетеif __name__ == '__main__'
код. Кроме того, пример Prost выглядит так, как будто он безоговорочно вызывает код конфигурации при импорте, что мне не подходит. Как правило, регистрация кода конфигурации должна выполняться в одном месте и не должна являться побочным эффектом импорта, за исключением случаев, когда вы импортируете __main__.if __name__ == '__main__'
? (это не упоминается явно в вопросе, если это так)Ответы:
В каждом модуле рекомендуется использовать регистратор, определяемый следующим образом:
в верхней части модуля, а затем в другом коде в модуле, например,
Если вам нужно подразделить действия по регистрации внутри модуля, используйте, например,
и войдите
loggerA
иloggerB
при необходимости.В вашей основной программе или программах, например:
или
Смотрите здесь для входа из нескольких модулей, и здесь для регистрации конфигурации для кода, который будет использоваться в качестве модуля библиотеки другим кодом.
Обновление: при вызове
fileConfig()
вы можете указать, используетеdisable_existing_loggers=False
ли вы Python 2.6 или более позднюю версию ( дополнительную информацию см. В документации ). Значение по умолчаниюTrue
для обратной совместимости, которая приводит к отключению всех существующих регистраторов,fileConfig()
если только они или их предки не указаны явно в конфигурации. Если установлено значениеFalse
, существующие регистраторы остаются одни. Если вы используете Python 2.7 / Python 3.2 или более позднюю версию, вы можете рассмотретьdictConfig()
API, который лучше, чемfileConfig()
тот, который дает больший контроль над конфигурацией.источник
disable_existing_loggers
флаг, которыйTrue
по умолчанию установлен, но может быть установлен вFalse
.Фактически каждый регистратор является дочерним по отношению к родительскому регистратору пакетов (то есть
package.subpackage.module
наследует конфигурацию отpackage.subpackage)
, поэтому все, что вам нужно сделать, это просто настроить корневой регистратор. Это может быть достигнуто с помощьюlogging.config.fileConfig
(вашей собственной конфигурации для регистраторов) илиlogging.basicConfig
(устанавливает корневой регистратор) Настройка регистрации в вашем модуле ввода (__main__.py
или что вы хотите запустить, напримерmain_script.py
.__init__.py
Работает также)используя basicConfig:
используя fileConfig:
и затем создайте каждый регистратор, используя:
Для получения дополнительной информации см. Advanced Logging Tutorial .
источник
__main__.py
(например, если я хочу использовать модуль в сценарии, в котором нет регистратора), всеlogging.getLogger(__name__)
равно будет выполнено какое-либо вход в модуль, или это вызовет исключение?Я всегда делаю это, как показано ниже.
Используйте один файл python для настройки моего журнала как одноэлементного шаблона с именем '
log_conf.py
'В другом модуле просто импортируйте конфиг.
Это единый шаблон для регистрации, просто и эффективно.
источник
Некоторые из этих ответов предполагают, что в верхней части модуля вы делаете
Насколько я понимаю, это считается очень плохой практикой . Причина в том, что файл config отключит все существующие регистраторы по умолчанию. Например
И в вашем основном модуле:
Теперь журнал, указанный в logging.ini, будет пустым, поскольку существующий регистратор был отключен вызовом fileconfig.
Хотя, безусловно, можно обойти это (disable_existing_Loggers = False), реально многие клиенты вашей библиотеки не будут знать об этом и не будут получать ваши журналы. Сделайте это легким для ваших клиентов, всегда вызывая logging.getLogger локально. Шляпа Совет: я узнал об этом поведении с сайта Виктора Лин .
Поэтому хорошей практикой является всегда вызывать logging.getLogger локально. Например
Кроме того, если вы используете fileconfig в своем основном файле, установите disable_existing_loggers = False, на тот случай, если ваши разработчики библиотеки используют экземпляры логгера уровня модуля.
источник
logging.config.fileConfig('logging.ini')
раньшеimport my_module
? Как предлагается в этом ответе .logger = logging.getLogger(__name__)
»Простым способом использования одного экземпляра библиотеки журналов в нескольких модулях для меня было следующее решение:
base_logger.py
Другие файлы
источник
Бросив в другое решение.
В init .py моего модуля у меня есть что-то вроде:
Затем в каждом модуле мне нужен регистратор, я делаю:
Когда пропущены журналы, вы можете различать их источник по модулю, из которого они пришли.
источник
Вы также можете придумать что-то вроде этого!
Теперь вы можете использовать несколько регистраторов в одном модуле и в рамках всего проекта, если вышеперечисленное определено в отдельном модуле и импортировано в другие модули, где требуется ведение журнала.
источник
Решение @ Ярки казалось лучше. Я хотел бы добавить еще к этому -
Таким образом, LoggerManager может быть подключен ко всему приложению. Надеюсь, что это имеет смысл и ценность.
источник
Есть несколько ответов. я получил похожее, но другое решение, которое имеет смысл для меня, может быть, оно будет иметь смысл и для вас. Моя главная цель состояла в том, чтобы иметь возможность передавать журналы обработчикам по их уровню (журналы уровня отладки на консоль, предупреждения и выше в файлы):
создал хороший утилитный файл с именем logger.py:
the flask.app - это жестко закодированное значение в колбе. регистратор приложений всегда начинается с flask.app в качестве имени модуля.
Теперь в каждом модуле я могу использовать его в следующем режиме:
Это создаст новый журнал для "app.flask.MODULE_NAME" с минимальными усилиями.
источник
Лучше всего было бы создать модуль отдельно, у которого есть только один метод, задача которого состоит в том, чтобы предоставить обработчик логгера вызывающему методу. Сохраните этот файл как m_logger.py
Теперь вызывайте метод getlogger () всякий раз, когда необходим обработчик логгера.
источник
--debug
опция в приложении и вы хотите установить уровень ведения журнала во всех регистраторах в вашем приложении на основе этого параметра ...get_logger(level=logging.INFO)
для возврата какой-то синглтон, поэтому, когда он вызывается первый раз из основного приложения, он инициализирует регистратор и обработчики с надлежащим уровнем, а затем возвращает тот жеlogger
объект всем другим методам.Новичок в python, поэтому я не знаю, рекомендуется ли это, но он отлично работает, чтобы не переписывать шаблон.
Ваш проект должен иметь init .py, чтобы его можно было загрузить как модуль
sys._getframe(1)
предложение приходит отсюдаЗатем использовать ваш регистратор в любом другом файле:
Предостережения:
import [your module]
они не будут работать:python -m [your module name].[your filename without .py]
__main__
, но у любого решения, использующего это,__name__
будет эта проблема.источник