Рассмотрим пример применения этого приема в исходном коде библиотеки Requests ( https://github.com/kennethreitz/requests) — разместите это в файле верхнего уровня __init__.py вашего проекта:
# Установить дескриптор журналирования по умолчанию для того, чтобы
# избежать появления предупреждений, которые гласят «Обработчик не найден».
import logging
try: # Python 2.7+
····from logging import NullHandler
except ImportError:
····class NullHandler(logging.Handler):
········def emit(self, record):
············pass
logging.getLogger(__name__). addHandler(NullHandler())
Журналирование для приложения
Twelve-Factor App ( http://12factor.net/) (авторитетный источник, где перечислены правила хорошего тона, применяемые при разработке приложений) содержит раздел, в котором рассказывается о подобных правилах журналирования ( http://12factor.net/logs). В нем предложено рассматривать события журнала как поток событий, для отправки этого потока в стандартный поток вывода нужно использовать среду приложения.
Существует минимум три способа конфигурирования средств ведения журнала (табл. 4.4).
Таблица 4.4.Способы конфигурирования средств ведения журнала
Способ |
Плюсы |
Минусы |
Использование файла в формате INI |
Вы можете обновлять конфигурацию при запуске функции logging.config.listen(), которая будет слушать изменения в сокете |
У вас будет не такой полный контроль (например, пользовательские фильтры или средства ведения журнала, созданные как подклассы), чем это возможно при конфигурировании средств ведения журнала в коде |
Использование словаря или файла в формате JSON |
В дополнение к обновлению во время работы вы также можете загружать конфигурацию из файла с помощью модуля json, который находится в стандартной библиотеке, начиная с Python 2.6 |
У вас будет не такой полный контроль, чем это возможно при конфигурировании средств ведения журнала в коде |
Использование кода |
Вы имеете полный контроль над конфигурированием |
Любые модификации потребуют внесения изменений в исходный код |
Пример конфигурации с помощью файла в формате INI
Более подробная информация о формате INI содержится в разделе руководства журналирования, посвященном журналированию конфигурации ( https://docs.python.org/howto/logging.html#configuring-logging). Минимальный файл конфигурации будет выглядеть так:
[loggers]
keys=root
[handlers]
keys=stream_handler
[formatters]
keys=formatter
[logger_root]
level=DEBUG
handlers=stream_handler
[handler_stream_handler]
class=StreamHandler
level=DEBUG
formatter=formatter
args=(sys.stderr,)
[formatter_formatter]
format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s
asctime, name, levelname и message являются необязательными атрибутами библиотеки журналирования. Полный список доступных вариантов и их описание смотрите в документации Pytho ( http://bit.ly/logrecord-attributes). Предположим, что наша конфигурация журналирования называется logging_conf.ini. Для того чтобы настроить средства ведения журнала с помощью этой конфигурации в коде, используем функцию logging.config.fileconfig():
import logging
from logging.config import fileConfig
fileConfig('logging_config.ini')
logger = logging.getLogger()
logger.debug('often makes a very good meal of %s', 'visiting tourists')
Пример конфигурирования с помощью словаря
В версии Python 2.7 вы можете использовать словарь с деталями конфигурации. В PEP 391 ( https://www.python.org/dev/peps/pep-0391) содержится список обязательных и необязательных элементов словаря конфигурации. Рассмотрим минимальную реализацию:
import logging
from logging.config dictConfig
·
logging_config = dict(
····version = 1,
····formatters = {
········'f': {'format':
············'%(asctime)s %(name)-12s %(levelname)-8s %(message)s' }
········},
····handlers = {
········'h': {'class': 'logging.StreamHandler',
············'formatter': 'f',
············'level': logging.DEBUG}
····loggers = {
········'root': {'handlers': ['h'],
············'level': logging.DEBUG}
········}
)
dictConfig(logging_config)
·
logger = debugging.getLogger()
logger.debug('often makes a very good meal of %s', 'visiting tourists')
Пример конфигурирования непосредственно в коде
Наконец, рассмотрим минимальную конфигурацию журналирования, расположенную непосредственно в коде:
import logging
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
Читать дальше