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

Ведение журнала Python
Хотя ведение журнала необходимо, не все разработчики знают, как правильно его использовать. Я видел, как некоторые разработчики вставляли операторы печати при разработке и удаляли эти операторы по завершении.
Это работает, когда программа представляет собой простой скрипт, но для сложных систем вам лучше не использовать этот подход к печати.
Во-первых, вы не можете оставлять в логе только важные сообщения, вы можете увидеть там множество мусорных сообщений, но не сможете найти ничего полезного.
Вы также не можете управлять этими операторами печати без изменения кода, и вы можете забыть удалить эти неиспользуемые отпечатки, и все напечатанные сообщения попадают в стандартный вывод, что ужасно, когда у вас есть данные для вывода в стандартный вывод.
Ведение журнала — удобный инструмент в наборе инструментов программиста. Это может помочь вам развить поток программы и обнаружить сценарии, о которых вы, возможно, даже не думали при разработке приложения.
Журналы предоставляют разработчикам дополнительный набор глаз, которые всегда смотрят на поток, через который проходит приложение.
Они могут хранить информацию, например, какой пользователь или IP-адрес обращались к приложению.
Если возникает ошибка, они могут дать больше информации, чем трассировка стека, сообщая вам, в каком состоянии была программа до того, как она достигла строки кода, где произошла ошибка.
Регистрируя полезные данные из нужных мест, вы можете не только легко отлаживать ошибки, но и использовать данные для анализа производительности приложения, чтобы планировать масштабирование, или просматривать шаблоны использования, чтобы планировать маркетинг.
#Logging в Python
Модуль logging в Python — это готовый к использованию и мощный модуль, разработанный для удовлетворения потребностей как начинающих, так и корпоративных групп.
Вы можете импортировать модуль Logging, используя следующую строку кода.
|
1 |
import logging |
После импорта модуля ведения журнала вы можете использовать нечто, называемое «регистратором», для регистрации сообщений, которые вы хотите видеть. По умолчанию существует пять стандартных уровней, указывающих серьезность событий.
У каждого есть соответствующий метод, который можно использовать для регистрации событий на этом уровне серьезности. Определенные уровни следующие:
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
Модуль ведения журнала предоставляет вам регистратор по умолчанию, который позволяет вам начать работу без необходимости выполнять множество конфигураций.
|
1 2 3 4 5 6 7 8 9 |
# app.py import logging logging.debug('This is a debug message') logging.info('This is an info message') logging.warning('This is a warning message') logging.error('This is an error message') logging.critical('This is a critical message') |
Теперь запустите указанный выше файл в терминале, и вы увидите следующий вывод.

Из приведенного выше вывода вы можете заметить одну вещь: мы получили только три вывода, а не пять.
Приведенный выше вывод показывает, что уровень серьезности перед каждым сообщением вместе с корнем, который является именем, модуль ведения журнала присваивает своему регистратору по умолчанию.(Регистраторы подробно обсуждаются в следующих разделах.)
В этом формате, который показывает уровень, имя и сообщение, разделенные двоеточием(:), это формат вывода по умолчанию, который можно настроить для включения таких вещей, как метка времени, номер строки и другие детали.
Обратите внимание, что сообщения debug() и info() не регистрируются. Это связано с тем, что по умолчанию модуль регистрации регистрирует сообщения с уровнем серьезности WARNING или выше.
Вы можете изменить это, настроив модуль ведения журнала для регистрации событий всех уровней, если хотите. Вы также можете определить свои уровни серьезности, изменив конфигурации, но обычно это не рекомендуется, поскольку это может привести к путанице с журналами некоторых сторонних библиотек, которые вы можете использовать.
#Logging Basic Configurations
Вы можете использовать метод basicConfig(args) для настройки ведения журнала.
Обычно используемые параметры для basicConfig() следующие.
- level: корневой регистратор будет установлен на указанный уровень серьезности.
- filename: указывает файл.
- filemode: если указано имя файла, файл открывается в этом режиме. По умолчанию используется a, что означает добавление.
- form: это формат сообщения журнала.
Теперь посмотрите на следующий пример ведения журнала Python.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# app.py import logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) logger.info('Start reading database') # read database here records = {'krunal': 26, 'ankit': 24} logger.debug('Records: %s', records) logger.info('Updating records ...') records = {'krunal': 27, 'ankit': 25} # update records here logger.info('Finish updating records') |
Теперь запустите указанный выше файл и посмотрите результат.

Итак, используя параметр уровня, вы можете установить, какой уровень сообщений журнала вы хотите записывать.
Это можно сделать, передав одну из констант, доступных в классе, и это позволит регистрировать все вызовы на этом уровне или выше.
Функции debug(), info(), warning(), error() и Critical() также автоматически вызывают без аргументов функцию basicConfig(), если она не была вызвана ранее. Это означает, что после первого вызова одной из вышеперечисленных функций вы больше не можете настраивать корневой регистратор, потому что он вызвал бы внутреннюю функцию basicConfig().
Вы можете использовать FileHandler для записи записей в файл. См. следующий пример кода.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# app.py import logging logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) # create a file handler handler = logging.FileHandler('info.log') handler.setLevel(logging.INFO) # create a logging format formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) # add the handlers to the logger logger.addHandler(handler) logger.info('See the info.log file') |
Теперь запустите файл, и один файл будет создан в том же каталоге, что и ваш файл app.py, с именем info.log. Вывод будет следующим:
|
1 |
2019-06-07 23:02:03,617 - __main__ - INFO - See the info.log file |
Таким образом, вы можете создавать файлы журналов в своей файловой системе, чтобы отслеживать изменения в ваших приложениях.
Большинство веб-фреймворков и CMS следуют этому подходу, поэтому, когда приложение выйдет из строя, они увидят такой файл журнала, чтобы выяснить, что пошло не так.
#Formatting — вывод журнала в Python
Строка формата в Python не требует усилий. Аналогично модулю регистрации. Вы можете передать переменную, которая может быть представлена в виде строки, из вашей программы в качестве сообщения в ваши журналы, а некоторые важные элементы уже являются частью LogRecord и могут быть легко добавлены в формат вывода.
Если вы хотите зарегистрировать идентификатор процесса вместе с уровнем и сообщением, см. следующий пример кода.
|
1 2 3 4 5 6 |
# app.py import logging logging.basicConfig(format='%(process)d-%(levelname)s-%(message)s') logging.warning('This statement is a Warning') |
Вывод:

Вот еще один пример, где вы можете добавить информацию о текущей дате и времени.
|
1 2 3 4 |
import logging logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO) logging.info('Krunal has logged in') |
Вывод:

%(asctime) добавляет время создания LogRecord.
Формат можно изменить с помощью атрибута datefmt, который использует тот же язык форматирования, что и функции форматирования в модуле даты и времени Python, например, time.strftime().
#Logging Variable Data
Методы ведения журнала принимают строку в качестве аргумента, и может показаться естественным отформатировать строку с переменными данными в отдельной строке и передать ее методу журнала.
Но это можно сделать напрямую, используя строку формата для сообщения и добавляя переменные данные в качестве аргументов. См. следующий пример.
|
1 2 3 4 5 6 7 |
# app.py import logging name = 'Krunal' logging.warning('%s raised a warning', name) |
См. следующий вывод.

Аргументы, переданные методу, будут включены в сообщение как переменные данные.
Хотя вы можете использовать любой стиль форматирования, который вы хотите, f-строки, представленные в Python 3.6, являются отличным способом форматирования строк, поскольку они могут помочь сделать форматирование коротким и легко читаемым.
|
1 2 3 4 5 6 7 |
# app.py import logging name = 'Krunal' logging.warning(f'{name} raised an warning') |

#Классы и функции
Вы можете(и должны) определить свой регистратор, создав объект класса Logger, особенно если ваше приложение имеет несколько модулей.
Давайте посмотрим на некоторые классы и функции в модуле Python.
Ниже перечислены наиболее распространенные классы, определенные в модуле регистрации.
- Logger: это класс, объекты которого будут использоваться в коде приложения непосредственно для вызова функций.
- LogRecord: регистраторы автоматически создают объекты LogRecord, которые содержат всю информацию, относящуюся к регистрируемому событию, например имя регистратора, функцию и номер строки, сообщение и т. д.
- Handler: обработчики отправляют LogRecord в требуемое место назначения вывода, например, на консоль или в файл. Обработчик является основой для подклассов, таких как StreamHandler, FileHandler, SMTPHandler, HTTPHandler и других. Эти подклассы отправляют выходные данные журнала в соответствующие места назначения, такие как sys.stdout или файл на диске.
- Formatter: здесь вы указываете формат вывода, указав формат строки, в котором перечислены атрибуты, которые должен содержать вывод.
В основном мы имеем дело с объектами класса Logger, экземпляры которых создаются с помощью функции уровня модуля logging.getLogger().
Несколько вызовов getLogger() с одним и тем же именем вернут ссылку на один и тот же объект Logger, что избавит нас от передачи объектов logger в каждую часть, где это необходимо.
Пример:
|
1 2 3 4 5 6 |
# app.py import logging logger = logging.getLogger('demo logger') logger.error('This is an error') |
Вывод:

Итак, в этом руководстве мы обсудили модуль Logging Python, основные конфигурации ведения журнала, классов и функций, переменную и данные ведения журнала, а также форматирование вывода журнала в Python.

