Простое протоколирование в Python с помощью daiquiri

daiquiri, logging

Card image cap

Автор статьи: Жульен Данжу (Julien Danjou). Оригинал: https://julien.danjou.info/python-logging-easy-with-daiquiri/


За 10 с лишним лет, именно столько я пишу программы на Python, меня всегда раздражала одна вещь в нем — его протоколирование.


Не поймите меня неправильно, мне нравится подсистема протоколирования Python. Ею легко пользоваться и она замечательно работает во многих случаях. Наверное, если вы никогда не пользовались ею, то вначале может даже показаться, что протоколирование в Python это очень просто:

import logging
logger = logging.getLogger()
logger.info("Something useful")

Вряд ли ведь что-то может быть еще проще! Но что меня расстраивает, это то, что если вы запустите этот пример, произойдет ошибка. Смотрите сами:

>>> import logging
>>> logger = logging.getLogger()
>>> logger.error("Something useful")
No handlers could be found for logger "root"

Ничего не выводится, только ошибка. Файл протокола (журнала с сообщениями, лога) не записался. «По умолчанию» это не работает. Мне это совсем не нравится.

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

Снова и снова, мне приходится выполнять одни и те же действия, когда я настраиваю протоколирование.

А вот и она, daiquiri

Недавно я, наконец-то, нашел свободное время и написал крошечную библиотеку, которая бы делала эту работу за меня. Она называется daiquiri и служит только для одного: настройки встроенной подсистемы Python для протоколирования сообщений в современных программах.

Она небольшая.  Версия 1.0.0, которую я выпустил, содержит всего 228 строк кода и 79 строк тестов. И это все!

Она обещает полностью настроить стандартную систему протоколирования Python за вызов всего лишь одной функции. Ни больше и ни меньше. Самые интересные ее особенности, это:

  • запись протокола в stderr по умолчанию;

  • при протоколировании сообщений в терминал можно использовать разные цвета;

  • поддерживается запись протокола в файл;

  • можно использовать имя программы в качестве имени файла протокола, при этом достаточно указать каталог, куда будут записываться файлы;

  • поддерживается запись в syslog или journald;

  • поддерживается вывод в формат JSON;

  • поддерживается использование произвольных пар «ключ-значение» при обмене контекстной информацией;

  • отлов предупреждений, выпущенные модулем warnings;

  • собственная система протоколирования любых исключений.

Давайте посмотрим, как же она это все делает без настройки!

Основная работа библиотеки

Вот, что нужно написать, чтобы начать работать с daiquiri:

import daiquiri
daiquiri.setup()

Как я вам уже сказал, хочу, чтобы все было легко. Просто, если делать это с ее помощью, то это намного лучше, чем мучиться с logging.basicConfig. И что-то полезное печатается сразу, как и должно быть:

>>> import daiquiri
>>> daiquiri.setup()
>>> logger = daiquiri.getLogger()
>>> logger.error("something wrong happened")
2017-07-04 18:03:04,929 [16876] ERROR root: something wrong happened

Она выводит сообщения в поток stderr, применяя для этого необходимое форматирование и временную метку по умолчанию. Ведь это, как раз то, что все хотят, не так ли? Если вы запустите это в терминале, строка будет красной, так как это ошибка, и она будет зарегистрирована. Для разных уровней критичности сообщений будут использоваться другие цвета (например, зеленый для debug и т. п.).


Кроме этого, daiquiri зарегистрирует любое исключение, произошедшее в вашей программе:

>>> import daiquiri
>>> daiquiri.setup()
>>> raise Exception("boom!")
2017-07-04 18:05:43,378 [16959] CRITICAL root: Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
Exception: boom!


Если по какой-то причине исключение не получается обработать, тогда в журнале появится предупреждающее сообщение.

Другие возможности библиотеки

Если хотите изменить запись сообщений в протокол по умолчанию, вы можете сделать это, просто передав некоторые аргументы в функцию daiquiri.setup. Она принимает аргумент outputs, который должен быть перечислением объектов типа daiquiri.Output. Как правило, в этот список включаются, следующие объекты: daiquiri.File для протоколирования в файл, daiquiri.Syslog — в syslog или daiquiri.Stream — в любой другой поток (например: открытый файл, stdout или stderr).

Если вы хотите протоколировать непосредственно в syslog или же в stderr, то вот, как это сделать:

daiquiri.setup(outputs=(
   daiquiri.output.Syslog(),
   daiquiri.output.STDERR,
))

А если желаете записать протокол в файл, достаточно просто указать каталог, и daiquiri создаст в нем одноименный файл для вашей программы:

# Если имя вашей программы foobar-server, тогда файл протокола
# будет создан в /var/log/foobar-server.log
daiquiri.setup(outputs=(
    daiquiri.output.File(directory="/var/log"),))

Соглашусь, что это слишком простые примеры. Так, давайте же запишем протокол в journald, а также на сетевой сервер, используя для этого вывод в JSON:

import socket
import daiquiri
# Давайте сначала подключимся к серверу
s = socket.socket()
# Вы можете запустить простой сервер, написав в терминале: `nc -l 2333`
s.connect(("localhost", 2333))
f = s.makefile()
daiquiri.setup(outputs=(
    daiquiri.output.Journal(),
    daiquiri.output.Stream(f, formatter=daiquiri.formatter.JSON_FORMATTER),
))
daiquiri.getLogger().error("oops", somekey=42, anotherkey="foobar")
# Сервер получит:
# {"message": "oops", "somekey": 42, "anotherkey": "foobar"}

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

Вы можете свободно установить библиотеку с помощью pip или клонировать с помощью git! Она доступна на PyPI, ее исходники находятся на GitHub, а документация опубликована в Интернете.

1 264 просмотра

Комментарии