Модуль протоколирования Python: Как обнаружить ошибки в сценарии

Python — это популярный объектно-ориентированный язык программирования. Многие разработчики являются поклонниками Python, потому что язык сценариев позволяет разрабатывать программы быстрее, чем компилируемые языки, такие как Java. По сравнению с «традиционными» процедурными языками программирования, такими как Perl, Python имеет то преимущество, что его легко читать и поддерживать. Будь то искусственный интеллект, графический пользовательский интерфейс или системное администрирование: Python можно использовать для решения самых разных задач. Но чем чаще используется язык программирования, тем важнее следить за ошибками. Ведение журнала должно происходить с первой стадии разработки и до того момента, когда он используется пользователем.

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

Что такое протоколирование?

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

Если вы изучаете новый язык программирования, вы неизбежно совершите несколько ошибок. Даже если Python понятен тем, кто уже знает такие языки программирования, как C++ или Java, благодаря схожим структурам (например, форме циклов), каждый язык имеет свои особенности. Python, например, представляет иерархии с помощью отступов. Если в запале вы не заметите пропущенный пробел, даже самое простое приложение не будет работать. В журнале ошибок указывается соответствующая строка, а неопытным разработчикам при отладке показывается ошибка «неожиданный отступ». В данном случае логирование Python регистрирует простые ошибки сценария и выдает сообщение. Но протоколирование может делать не только это. Разработчики используют протоколирование в программах для совершенно разных областей применения:

  • Отладка: Весь исходный код проверяется на наличие ошибок, чтобы убедиться, что готовая программа работает без ошибок.
  • Поиск и устранение уязвимостей безопасности: Выявляются и устраняются возможные риски.
  • IT-криминалистика: Позволяет определить причину критических инцидентов, таких как хакерские атаки, по файлу журнала.
  • ИТ-аудит: Этот аудит определяет, обеспечивается ли безопасность и целостность данных, сравнивает цели компании с существующими ИТ-структурами на предмет их совместимости, анализирует эффективность программ и операционных систем.
  • Сравнение различных версий наборов данных: Сравнение возможно путем создания отдельного файла журнала для каждого прогона.

Ведение журнала может генерировать большое количество данных, особенно при написании сложного приложения на Python. Для сбора этих данных разработчики используют Python logging to file (файл журнала, создаваемый модулем Python logging и заполняемый информацией журнала через обработчик). Важно, чтобы файл журнала работал асинхронно. В противном случае ведение журнала в Python может заблокировать выполнение сценария.

Анализ ошибок с помощью протоколирования в Python: 5 уровней приоритета журнала

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

Простое протоколирование избавляет вас от дополнительной работы и обеспечивает более элегантное решение для анализа ошибок. В Python существует пять различных уровней серьезности протоколирования. Если вы хотите создать собственные фильтры журналов, вы, конечно, можете это сделать. Модуль регистрации Python, входящий в комплект поставки Vinay Sajip, предлагает градацию уровней серьезности, что кажется разумным:

Имя уровня протоколирования Использование Возможный вывод сообщения
Отладка Диагностика проблемы, очень подробная Неожиданный отступ в строке XY
Информация Выдает сообщение о том, что система работает правильно Функция 1*1 выполнена
Предупреждение Приложение работает правильно в максимально возможной степени, но возникла непредвиденная ситуация или выдано предупреждение о будущей проблеме Нехватка места для хранения данных
Ошибка Функция не может быть выполнена из-за возникшей проблемы Произошла ошибка, и действие было отменено
Критический Возникла серьезная проблема, и может потребоваться остановка всего приложения Серьезная ошибка: Программа не может получить доступ к этой службе и должна быть завершена

Различные уровни представляют информацию о событиях с возрастающей важностью. Уровни протоколирования Python — это статические функции. В объектно-ориентированном программировании эти функции являются содержимым класса. Для каждого экземпляра класса внутри объекта статические функции всегда одинаковы. Они не изменяются и присутствуют, если ни один экземпляр не вызывается. Если сообщение «Ошибка» вызывается в одном и том же объекте выполнения, связанное с ним сообщение об ошибке остается неизменным. Для других действий может быть указано другое сообщение об ошибке.

«Отладка» — это самый низкий уровень, поэтому информация с низким приоритетом также отображается. Однако это не означает, что серьезность ошибки выше, чем при «Critical». Debug включает в себя все остальные уровни и поэтому отображает все сообщения вплоть до критической ошибки.

Модуль протоколирования Python

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

  • Логгер
  • Обработчик
  • Фильтры
  • Форматировщик

Эти компоненты объединяются в экземпляр LogRecord и обмениваются информацией внутри него.

Логгер

Логгеры записывают действия во время выполнения программы. Они не отображаются непосредственно как экземпляр, но к ним можно получить доступ с помощью функции logging.getLogger(имя логгера). Вы можете присвоить имя логгеру, например, для структурированного отображения иерархий. В Python для обозначения дочерних пакетов, отделенных от пакетов, используется точка. Поэтому пакет log может иметь подчиненные пакеты log.bam или log.bar.loco. Аналогично, логгеры работают таким образом, что объект «log» получает дочерние «log.bam» и «log.bar.loco».

Обработчик

Обработчики получают информацию от регистраторов и отправляют ее дальше. Обработчик — это базовый класс, который определяет, как действует интерфейс экземпляров обработчика. Вы определяете цель с помощью соответствующего класса обработчика. StreamHandler отправляет информацию в потоки, FileHandler — в файлы. Для одной программы вы можете использовать несколько обработчиков, отправляющих сообщения от одного и того же регистратора. Это полезно, если, например, вы хотите выводить отладочную информацию в консоль, а важные сообщения об ошибках — в отдельный файл.

Вы используете метод setLevel(), чтобы указать наименьшую степень серьезности сообщения журнала, которое должно быть передано этому обработчику. Вместо logger.setLevel (который определяет уровень протоколирования) метод называется [имя обработчика].setLevel (см. строку 5 шаблона кода: fh.setLevel).

Форматировщик

В отличие от обработчиков, форматеры (объекты форматирования) можно использовать непосредственно как экземпляры в коде приложения. Вы используете эти экземпляры для указания формата, в котором ваше уведомление будет выведено в файл журнала. Если вы не используете никакого форматирования, отображается только определенное сообщение журнала. Используйте следующую функцию для доступа к форматеру и определения формата сообщения и даты:

logging.Formatter.__init__(fmt=[message format], datefmt=[date format])
#or also:
logging.Formatter.__init__(fmt=None, datefmt=None)

Если в атрибуте не указан формат даты, форматтер задает американскую форму и время: «Год-Месяц-День-Часы:Минуты:Секунды».

Фильтры

Фильтры позволяют задать еще более точные характеристики для выходных сообщений. Сначала определите фильтры, а затем добавьте их в соответствующий обработчик или регистратор с помощью метода addFilter(). Если значение фильтра равно false из-за свойств сообщения, сообщение не будет передано. Используйте функцию logging.filter(name=fh), где атрибут «fh» обозначает любое имя логгера, чтобы разрешить запись данных конкретного логгера и заблокировать все остальные логгеры.

Модуль протоколирования в Python на примере

Python предоставляет разработчикам инструмент рисования Turtle для тестирования основных команд. Пример пользователя использует Turtle в следующем коде. Инструмент рисования должен бежать прямо вперед на зеленом фоне, повернуть влево, продолжить бег, а затем описать круг. В пример включены команды протоколирования Python «Info» и «Error»:

# -*- coding: UTF-8 -*-
import turtle
import logging
turtle.bgcolor("green")
turtle.fd(30)
turtle.lt(90)
turtle.fd(50)
logging.info('It is going well.')
turtle.circle(50)
logging.error('Oops, looks like you are running in circles.')

На изображении выше вы можете увидеть, как выглядит результат. Модуль Turtle (левое окно) принял команды и работает как нужно. В правом окне код включает команды Turtle, а также команды ведения журнала с уровней INFO и ERROR. Типичная форма вывода сообщения журнала выглядит следующим образом: [Severity]:[Origin of message]:[Notification message].

Однако консоль (Console 1/A) в примере определяет только сообщение журнала Python ERROR: Error:root:Oops, похоже, вы бегаете по кругу.

Это происходит потому, что по умолчанию модуль протоколирования Python устанавливает значение «WARNING». Модуль опускает всю более подробную информацию до тех пор, пока эти настройки не будут изменены.

Изменение уровня протоколирования Python

Используйте следующую команду, чтобы изменить настройку на уровень DEBUG:

import logging
logging.basicConfig(level=logging.DEBUG)

На рисунке выше консоль отображает запись журнала для каждого нового звонка. Если вы останавливаете программу, консоль удаляет все записи. Чтобы отслеживать данные журнала, следует использовать файл журнала. Такая практика называется logging to file, то есть хранение записей журнала в файле.

Хранение журналов Python в файле

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

Чтобы создать файл для ведения журнала Python:

import logging
logging.basicConfig( level=logging.DEBUG, filename='example.log')

FileHandler является экземпляром класса logging. Он действует вместе с экземпляром ведения журнала. Он отвечает за то, куда и в каком виде отправляются данные протоколирования. Кроме FileHandler, в модуле logging библиотеки Python есть и другие LoggingHandler — например, StreamHandler и NullHandler. Однако для последующей оценки данных протоколирования рекомендуется использовать файл журнала.

Чтобы создать FileHandler, который сохраняет отладочные сообщения в файл:

На изображении выше функция logging.getLogger() вызывает модуль протоколирования Python. «fh» определяется как FileHandler с атрибутом «debug.log». С его помощью fh может создать файл журнала «debug.log» и отправить сообщения журнала вам. Метод addHandler() присваивает соответствующий обработчик логгеру. Вы можете назвать файл журнала в соответствии с вашими пожеланиями.

Вы можете использовать следующие функции, чтобы опробовать это на практике:

import logging
logger = logging.getLogger('Example_Log')
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler('debug.log')
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)
logger.debug('Debug Message')
logger.info('Info Message')
logger.warning('Warning')
logger.error('An Error Occured')
logger.critical('Critical error shutdown')

Если файл журнала, который вы создаете с помощью Python logging to file, должен содержать полезную информацию для определенных задач, простых сообщений может быть недостаточно. Временная метка и имя регистратора помогают лучше классифицировать информацию. На следующем снимке экрана показан пример того, как можно задать формат с помощью атрибутов форматера. В окне Notepad debug.log текстовый вывод указывает сообщения журнала с датой, временем, именем регистратора, уровнем журнала и сообщением.

Приведем код еще раз, чтобы вы могли попробовать сами:

import logging
logger = logging.getLogger('Example_Log')
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler('debug.log')
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.debug('Debug Message')
logger.info('Info Message')
logger.warning('Warning')
logger.error('Error Occured')
logger.critical('Critical Error')

Резюме

Логирование в Python — это практический инструмент для предотвращения ошибок, восстановления контроля после хакерских атак и просто для анализа. В то время как другие языки программирования добавляют логирование из вторых рук, модуль логирования Python является частью стандартной библиотеки. Если вы вставите этот метод в свой код, будут созданы сообщения журнала разных уровней: как в файлы, так и на консоль. Форматирование и фильтры, а также обработчики обеспечивают удобство настройки. Убедитесь, что у вас есть имена для ваших логгеров и их дочерних элементов, которые можно быстро присвоить, чтобы облегчить работу с лог-файлами под Python.

Оцените статью
cdelat.ru
Добавить комментарий