Вступление
Ведение журнала помогает отслеживать события, происходящие во время выполнения кода, которые затем можно использовать в будущем для целей отладки. Он обеспечивает лучшее представление о потоке приложения и помогает разработчикам отслеживать источник ошибок, возникающих во время выполнения вашего кода, тем самым повышая ремонтопригодность приложения.
В Python большинство основных функций ведения журнала предоставляется стандартной библиотекой Python. Следовательно, вы можете легко добавить ведение журнала в свое приложение без каких-либо дополнительных настроек. Стандартный модуль ведения журнала позволяет разработчику записывать сообщения о состоянии в файл или любой другой выходной поток.
Модуль регистрации
Модуль logging
по умолчанию доступен в средах Python и предоставляет
средство ведения журнала по умолчанию с именем «root». Он определяет
функции и классы, реализующие функции ведения журнала.
API ведения журналов, предоставляемый стандартной библиотекой, позволяет вам включать собственные сообщения в журнал приложения, а также осуществлять интеграцию с сообщениями из сторонних модулей. Он также предоставляет механизм для аннотирования сообщений журнала с указанием источника, отметки времени, серьезности и других метаданных, что помогает в анализе журнала.
Типы ведения журнала (уровни журнала)
Каждое сообщение журнала связано с уровнем серьезности, который представляет собой целое число, используемое для обозначения важности зарегистрированного события (событий). Модуль ведения журнала имеет вспомогательную функцию для каждого уровня журнала - они названы в соответствии с уровнем журнала. Ниже приведен список уровней ведения журнала с указанием их рекомендуемого использования.
-
Отладка (
logger.debug
): очень подробный вывод. Используется для диагностики проблем. -
Информация (
logger.info
): предоставляет информацию об успешном выполнении. Подтверждает, что все работает должным образом. -
Предупреждение (
logger.warn
илиlogger.warning
): выдать предупреждение о проблеме, которая может возникнуть в будущем, или о неисправимой ошибке. -
Ошибка (logger.error): указывает на проблему в программном обеспечении, поскольку оно не выполняется
logger.error
-
Критический (
logger.critical
): указывает на серьезную ошибку, которая может остановить выполнение программы.
По умолчанию корневой регистратор настроен так, чтобы сообщать обо всех сообщениях на уровне предупреждения или выше - любые сообщения ниже этого уровня фильтруются. Однако можно явно настроить модуль на более или менее избирательную фильтрацию.
Чтобы добавить ведение журнала в сценарий Python, просто импортируйте
модуль, используя import logging
, и после успешного импорта сценарий
может регистрировать сообщения, используя logging.*
, Такие как
logging.debug()
.
Здесь вы можете увидеть простой пример работы модуля логирования:
import logging
logging.warning("Caution: This is the root logger!")
Выход:
WARNING:root:Caution: This is the root logger!
Объекты регистратора
Модуль logging
позволяет пользователю создавать несколько объектов
регистратора. Для получения детального контроля над тем, как разные
части приложения Python регистрируют свои сообщения, можно использовать
различные типы объектов регистратора - например, основное приложение
Python может использовать root
средство ведения журнала, тогда как
сторонние библиотеки, используемые в этом приложении, могут использовать
свои собственные объекты регистратора со своими собственными
конфигурациями.
Используя функции root
регистратора по умолчанию, мы можем вызывать
функции напрямую, например, logging.debug()
. Можно настроить свой
собственный регистратор, создав объект Logger
, и это может быть
полезно, если ваше приложение имеет несколько модулей.
Давайте посмотрим на некоторые классы и функции в модуле logging
Основные классы и их функции следующие:
-
Регистраторы - предоставляет интерфейс, который использует приложение. Объекты этого класса используются непосредственно для вызова функций в приложении.
-
Обработчики - отправляет сообщения журнала в соответствующее место в программном обеспечении, например в стандартную консоль вывода, в файл, через HTTP или даже по электронной почте (через SMTP).
-
Фильтры - дает детальный контроль над выбором записей журнала для отображения.
-
Средства форматирования - определяют окончательный формат записей журнала, указывая атрибуты, которые должен содержать вывод.
Из них наиболее часто используются Logger
Чтобы создать новый регистратор, мы можем использовать метод
logging.getLogger()
. В следующем скрипте мы регистрируем ошибки с
помощью root
регистратора, а также нашего настраиваемого регистратора
my_logger
.
import logging
my_logger = logging.getLogger("My Logger")
logging.error("Error: Root Log")
my_logger.error("Error: My Logger log")
Выход:
ERROR:root:Error: Root Log
ERROR:My Logger:Error: My Logger log
Каждое сообщение журнала будет не только указывать источник - объект регистратора, через который оно было зарегистрировано, но и отображать сообщение, основанное на конфигурации этого объекта регистратора.
В следующих разделах мы рассмотрим различные параметры конфигурации объектов регистратора.
Регистрация в файл по сравнению со стандартным выводом
По умолчанию объекты регистратора выводят журналы на стандартный вывод.
Вы можете использовать basicConfig()
для изменения этого и других
параметров. Ниже приведен список параметров метода basicConfig
- level: установите уровень важности для регистратора. Любые сообщения ниже этого уровня серьезности не будут регистрироваться.
- filename: Имя файла, в который записываются журналы.
- filemode: режим, в котором указанный файл, если он есть, должен быть открыт.
- формат: Задает формат сообщения журнала. Это строка с атрибутами
LogRecord
LogRecord
содержит информацию о регистрируемых событиях, такую как
номер строки, время, имя регистратора и т. Д. Обсуждение объекта
LogRecord выходит за рамки этой статьи, но дополнительная информация
доступна
здесь
.
Ниже приводится сводка шагов, которые необходимо выполнить для записи событий журнала в файл:
- Импортируйте модуль регистрации.
- Настройте регистратор с
basicConfig
метода basicConfig - Создание объекта регистратора.
- Установка порогового значения логгера.
- Используйте методы ведения журнала.
Это можно лучше понять на примере:
# Filename: test_logger.py
import logging
# Create a logger object
logger = logging.getLogger()
# Configure logger
logging.basicConfig(filename="test.log", format='%(filename)s: %(message)s', filemode='w')
# Setting threshold level
logger.setLevel(logging.DEBUG)
# Use the logging methods
logger.debug("This is a debug message")
logger.info("For your info")
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")
Приведенный выше сценарий создаст файл test.log. Файл будет содержать следующую информацию журнала:
test_logger.py: This is a debug message
test_logger.py: For your info
test_logger.py: This is a warning message
test_logger.py: This is an error message
test_logger.py: This is a critical message
Дата / время в сообщениях журнала
Чтобы отобразить дату и время возникновения события, вы можете
использовать %(asctime)s
в строке формата в функции basicConfig()
.
Например:
import logging
logging.basicConfig(format='%(asctime)s %(message)s')
logging.warning('is the time the Admin logged out.')
Выход:
2018-12-17 10:52:15,463 is the time the Admin logged out.
Если вы хотите изменить способ отображения даты и времени, вы можете
настроить его с datefmt
параметра basicConfig
метода basicConfig.
Регистрируемые переменные
В реальных приложениях нам необходимо выводить журналы в соответствии с динамическими изменениями, происходящими в нашем приложении. Как видно из приведенного выше примера, методы ведения журнала принимают строку в качестве аргумента. Кроме того, мы можем включать переменные и форматировать строку с помощью заполнителей, а затем передавать ее методу журнала. Во время выполнения значение переменных будет выводиться в сообщениях журнала.
Вот пример этого с использованием форматирования строк:
import logging
status = "connection unavailable"
logging.error("System reported: %s", status)
Выход:
ERROR:root:System reported: connection unavailable
Начиная с Python 3.6 f-Strings можно использовать в качестве альтернативы спецификаторам строкового формата, тем самым сохраняя код легко читаемым при наличии нескольких параметров. Используя f-строки, вы можете указать любое выражение Python как часть сообщения, и они будут оцениваться во время выполнения, и результат будет встроен в сообщения журнала.
Приведенный выше пример можно переписать, используя f-строку, как:
import logging
status = "connection unavailable"
logging.error(f'System reported: {status}')
Регистрация трассировок стека
Захват трассировки стека в вашем приложении также поддерживается модулем
ведения журнала. Установка для параметра exc_info
True
при вызове
функций ведения журнала позволяет нам фиксировать информацию об
исключении. Используя эту функцию, мы можем получить информацию об
исключении, которое в настоящее время обрабатывается. Информация зависит
от текущего потока и текущего кадра стека.
import logging
my_list = [1, 2]
try:
print(my_list[3]) # Index out of range
except Exception as e:
logging.error("Caught Exception!", exc_info=True)
Выход:
ERROR:root:Caught Exception!
Traceback (most recent call last):
File "index.py", line 5, in <module>
print(my_list[3]) # Index out of range
IndexError: list index out of range
В случае, если текущий кадр стека не обрабатывает исключения, информация затем получается от его вызывающего (т. Е. Вызывающего кадра стека) и так далее, пока он не найдет кадр стека для обработки исключения. Кадр стека содержит информацию о последнем обработанном исключении.
Если в стеке нет обрабатываемых исключений, возвращается None
В
противном случае функция возвращает значение type
(тип обрабатываемого
исключения), значение (параметр исключения) и трассировку (объект
трассировки, который инкапсулирует стек вызовов, в котором изначально
возникло исключение).
Заключение
Модуль ведения журнала очень практичен, он предоставляет готовые к использованию функции ведения журнала, которые могут добавить базовое ведение журнала в небольшой проект. Его можно легко расширить, используя объекты регистратора и их широкие возможности конфигурации для поддержки потребностей даже самых требовательных приложений. В дополнение к сообщениям, модуль регистрации может также использоваться для регистрации исключений и трассировки стека. На этом заканчивается базовое руководство по реализации ведения журнала в Python.