Язык программирования Python

Логирование. Создание логов с помощью Python.

Введение

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

Эти файлы помогают нам проверить, как выполнилась программа.

Здесь обычно сохраняется информация о результатах операций, предупреждения, которые необходимо учесть, и ошибки в запуске, который нужны для получения причин сбоя.

В Python у нас есть модуль, который упрощает создание лога. Модуль ” logging”, который мы рассмотрим ниже.

Logging

Для его установки мы можем использовать инструмент pip.

pip install logging

Всякий раз, когда мы хотим использовать его, мы должны импортировать модуль:

Import logging

Чтобы использовать этот модуль, первое, что нужно сделать, это настроить систему протоколирования так, как нам нужно.

Эта конфигурация определяет, как будут отображаться сообщения журнала.

Для создания базовой конфигурации мы должны использовать функцию “basicConfig”следующим образом:

Logging.basicConfig( filename, filemode, format, datefmt, style, level, stream, handlers)
Code language: CSS (css)

Где каждый из параметров:

  • filename -> Имя файла, создаваемого вместе с журналом. Если имя файла не указано, лог будет выведен на экран.
  • filemode -> Если указано имя файла, этот параметр указывает способ открытия файла. По умолчанию – ‘a’.
    • ‘r’ -> Только чтение
    • ‘w’ -> Write. Удаляет файл, если он существовал ранее
    • ‘x’ -> Открыть исключительный режим. Отказ, если файл ранее существовал.
    • ‘a’ -> Запись, добавление в конец файла, если он уже существует.
  • format -> Указать конкретный формат для каждой строки журнала.
  • datefmt -> Указать конкретный формат для дат, которые выводятся в формате time.strftime().
  • style -> Если указан format, то style используется для задания формата строки. ‘%’, ‘{‘ или ‘$’ для стиля printf, str.format() или string.Template соответственно. По умолчанию имеет значение ‘%’.
  • level -> Устанавливает уровень корневого регистратора на определенный уровень. Выводит только уровни, равные или превышающие указанный. Уровень:
    • 50 -> CRITICAL
    • 40 -> ERROR
    • 30 -> WARNING
    • 20 -> INFO
    • 10 -> DEBUG
    • 0 -> NOTSET
  • stream -> Используйте определенный поток для инициализации StreamHandler. Обратите внимание, что этот аргумент несовместим с filename. Если встречаются оба варианта, будет выдана ошибка ValueError.
  • handlers -> Если указано, то это должен быть итератор уже созданных обработчиков для добавления в корневой логгер. Обработчикам, у которых еще нет набора форматеров, будет назначен форматер по умолчанию, созданный в этой функции. Обратите внимание, что этот аргумент несовместим с именем файла или последовательностью; если оба аргумента присутствуют, генерируется ошибка ValueError.

Когда журнал настроен, нам остается только писать в него. Это делается следующим образом в зависимости от уровня сообщения:

logging.info(‘текст info’) logging.warning(‘текст warning’) logging.error(‘текст error’) logging.critical(‘текст critico’) logging.log(lvl, ‘текст’)
Code language: CSS (css)

Работа

Лучше всего понять, как работает протоколирование, можно на нескольких примерах. Здесь мы собираемся
с некоторыми из них.

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

import logging logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s') logging.warning('Эта программа ничего не сделала')
Code language: JavaScript (javascript)

Как вы можете видеть, сообщение журнала выходит прямо на экран и печатается с форматом, который мы указали в “basicConfig”.

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

В дополнение к этому мы можем указать “filemode”. В примере он установлен на “w”, так что
при каждом выполнении журнал будет затирать информацию, которая уже была у него ранее.

import logging logging.basicConfig(filename='log.log', format='%(asctime)s : %(levelname)s : %(message)s', filemode='w') logging.warning('Эта программа ничего не сделала')
Code language: JavaScript (javascript)

Убеждаемся, что на экране ничего не отображается. Вместо этого создается новый файл, в содержимом которого мы видим лог.

2021-06-19 11:52:59,784 : WARNING : Эта программа ничего не сделала
Code language: CSS (css)

Если запуск производится без опции “filemode”, по умолчанию будет использован режим “a”.

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

2021-06-19 11:55:48,047 : WARNING : Эта программа ничего не сделала 2021-06-19 11:56:01,746 : WARNING : Эта программа ничего не сделала 2021-06-19 12:00:06,422 : WARNING : Эта программа ничего не сделала
Code language: CSS (css)

Теперь давайте рассмотрим более полный пример.

Мы собираемся придать определенный формат дате, которую мы выводим в каждой строке.

Также мы установим “level” на INFO.

То есть, он будет печатать только те сообщения, которые имеют уровень “INFO” или выше (debug не печатает).

import logging logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s' , datefmt='%d/%m/%y %H:%M:%S' , level=logging.INFO) logging.info('Базовый тест на ведение журнала') logging.debug('Эта линия не будет показана.') logging.warning('Эта программа ничего не сделала')
Code language: JavaScript (javascript)
python logging.py 19/06/21 12:15:06 : INFO : Базовый тест на ведение журнала 19/06/21 12:15:06 : WARNING : Эта программа ничего не сделала

Полный пример использования логов

Давайте разберём более полный пример, чтобы наглядно рассмотреть представленные в статье понятия.

Для этого примера мы создадим программу, которая делит два числа, которые пользователь запрашивает на экране.

Очевидно, что интересна не сама программа, а протоколирование, которое мы собираемся вести на ней.

С помощью этого журнала мы сможем после завершения работы проверить, что делала программа.

Код выглядит следующим образом:

import logging try: logging.basicConfig(filename='division.log', filemode='a',format='%(asctime)s : %(levelname)s : %(message)s', datefmt='%d/%m/%y %H:%M:%S', level=logging.INFO ) logging.info('Программа, которая делит два числа') first_num=int(input('Введите первое число:')) logging.info('Первое число: '+str(first_num)) second_num=int(input('Ведите второе число:')) logging.info('Второе число: '+str(second_num)) if second_num==0: result=0 logging.warning('Деление на 0') else: result=first_num/second_num print('Результат -> '+str(result)) logging.info('Результат -> '+str(result)) except : print('Непредвиденная ошибка') logging.fatal('Непредвиденная ошибка')
Code language: PHP (php)

Как вы видите, мы поместили несколько строк “logging.info”, которые дадут нам информацию о том, что происходит в программе.

Поскольку деление на 0 невозможно, мы поместили предупреждение, чтобы сообщить об этой ситуации, но продолжить программу с результатом 0.

Наконец, мы использовали “fatal”, чтобы указать, если произойдет ошибка, которую мы не предусмотрели.

1) Правильные входные данные.

Вводим два числа, например, 5 и 4.

Запуск:

python logging.py Введите первое число:5 Ведите второе число:4 Результат -> 1.25
Code language: CSS (css)

Лог:

16/06/21 12:16:09 : INFO : Программа, которая делит два числа 16/06/21 12:16:10 : INFO : Первое число: 5 16/06/21 12:16:11 : INFO : Второе число: 4 16/06/21 12:16:11 : INFO : Результат -> 1.25

2) Деление на 0

Запуск:

python logging.py Введите первое число:8 Ведите второе число:0 Результат -> 0
Code language: CSS (css)

Лог:

16/06/21 12:30:54 : INFO : Программа, которая делит два числа 16/06/21 12:30:57 : INFO : Первое число: 8 16/06/21 12:30:58 : INFO : Второе число: 0 16/06/21 12:30:58 : WARNING : Деление на 0 16/06/21 12:30:58 : INFO : Результат -> 0

3) Фатальная ошибка

Запуск:

python logging.py Введите первое число:8 Ведите второе число:текст Непредвиденная ошибка
Code language: CSS (css)

Лог:

16/06/21 12:32:12 : INFO : Программа, которая делит два числа 16/06/21 12:32:15 : INFO : Первое число: 8 16/06/21 12:32:16 : CRITICAL : Непредвиденная ошибка

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *