ведение журнала с одинаковыми уровнями ведения журнала между модулями

1

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

Я пишу приложение командной строки, и я хотел бы иметь одну функцию (я называю ее argpconf), которая будет анализировать аргументы командной строки и соответственно устанавливать уровень журнала. Самое главное, я бы хотел, чтобы уровень журнала был установлен один раз в этой функции и был одинаковым во всех модулях с минимальными накладными расходами при создании своих регистраторов. Кроме того, я хотел бы иметь возможность идентифицировать модуль, с которого было получено сообщение, используя общий форматтер:

logging.Formatter("%(levelname)s : %(name)s : %(message)s")

Частично основанный на шаблоне cookiecutter, я создал следующие файлы:

├── api
│   ├── __init__.py
│   └── some_functionality.py
├── cli.py
├── core
│   ├── argpconf.py
│   ├── __init__.py
│   ├── logger.py
│   └── __version__.py
├── __init__.py
└── __main__.py

core/logger.py имеет следующий контент:

from logging import Formatter, Logger as _Logger, NullHandler, StreamHandler

class Logger(_Logger):
    def __init__(self, name=None):
        super(Logger, self).__init__(name or __name__.split(".")[0])
        self.addHandler(NullHandler())  # default to no output
    def start(self, level="WARN", stream=None,
              fmt="%(levelname)s : %(name)s : %(message)s"):
        handler = StreamHandler(stream)
        handler.setFormatter(Formatter(fmt))
        self.addHandler(handler)
        self.setLevel(level.upper())
    def stop(self):
        for handler in self.handlers[1:]:
            # Remove everything but the NullHandler.
            self.removeHandler(handler)

logger = Logger()

По сравнению с идеями, предложенными в ответах на эти вопросы:

Мне очень нравится подход, примененный в шаблоне cookiecutter с регистратором, поскольку он позволяет вам просто import logger журнал и иметь объект logger который он регистрирует на всех модулях одинаково. Тем не менее, я не полностью этому доволен, потому что в моем случае argpconf.py является первым модулем, который запускает logger поэтому все сообщения журнала из всех модулей имеют их %(name)s замененное core поскольку это argpconf.py __name__.split(".")[0].

Как я могу улучшить модуль logger чтобы он обнаружил модуль, который вызывал его, и печатал сообщения журнала с модулем как %(name)s и, возможно, даже функцию, которая их печатает?

  • 1
    Разве logging.basicConfig(level=LOGLEVEL) вашим потребностям?
  • 0
    Я обновил свой ответ ссылкой на пример кода ( слишком много кода, чтобы добавить встроенный ответ).
Теги:
logging

1 ответ

2
Лучший ответ

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

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

то самый простой подход - импортировать argparse и logging в вашем главном скрипте, аргументы командной строки процесса и соответственно установить уровень ведения журнала, вызвать basicConfig() (как это предлагается в комментарии Брайана М. Шелдона), а затем отправить в конечную точку приложения, как определено аргументы командной строки. Каждый модуль, который вы используете, должен регистрировать что-то, просто нужно import logging и logger = logging.getLogger(__name__) а затем logger.debug(...) или что угодно, где это необходимо в этом модуле. Если вы придерживаетесь этого, все модули будут использовать уровень ведения журнала, установленный в basicConfig() автоматически, и если вы используете фрагмент %(name)s в аргументе format= для basicConfig(), то вы увидите полное имя модуля в это место в занесенных в журнал сообщениях, как полностью квалифицированное пунктирное имя (например, api.some_functionality). Такой подход, безусловно, будет иметь меньшие накладные расходы при создании регистраторов, чем это делает шаблон cookiecutter.

Обновление: я приведу пример Pookon Logging Cookbook. На данный момент, здесь Gist с только кодом.

  • 0
    Звучит хорошо, но я не уверен, что полностью понимаю. Не могли бы вы добавить, пожалуйста, примерный код, пожалуйста?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню