Как сделать лог файл в python

Добавил пользователь Евгений Кузнецов
Обновлено: 10.09.2024

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

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

Перед тем, как использовать модуль logging, необходимо его импортировать стандартным способом, через ключевое слово import.

import logging

Концепции Python Logging

Здесь вы найдете описание некоторых концепций, используемых в этом модуле.

Уровни Python Logging

Чтобы задать значимость лога, обозначается его уровень. Проще говоря, лог ERROR имеет выше приоритетность по сравнению с WARNING . Есть еще один уровень – DEBUG , который применяется исключительно во время отладки программы.

В арсенале Python таких уровней шесть:

NOTSET=0, DEBUG=10, INFO=20, WARNING=30, ERROR=40 и CRITICAL=50.

В целом, можно приоритетность понять интуитивно. То есть, информирующий лог имеет выше приоритетность, чем отладочный. Единственное исключение, о котором надо поговорить отдельно – NOTSET .

Форматирование лога в Python

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

Такой формат лога в записи будет выглядеть следующим образом:

2019-01-16 10:35:12,468 — keyboards — ERROR — :1 — привет мир

Обработчик ведения лога в Python

В Python есть отдельный компонент, который называется обработчиком лога. Он – главный, поскольку отвечает как за отображение, так и за запись его данных. Отображение лога осуществляется через StreamHandler ( в консоли), в файле (через FileHandler) . Также для этого может использоваться электронная почта (SMTPHandler) или другие методы.

Каждый обработчик состоит из двух важных полей.

  1. Форматировщик. С его помощью происходит добавление контекстной информации в лог.
  2. Степень значимости лога. Здесь как раз и задаются уровни Python Logging, о которых мы говорили ранее. Вернее, с какими из них будет работать обработчик (а также теми, которые выше). Если он отвечает за работу с уровнем WARNING, он не будет ничего делать с уровнем INFO. То есть, если уровень находится ниже, с ним обработчик ничего не делает. Если выше – обрабатывает его.

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

Наиболее часто используются StreamHandler и FileHandler . Работают они следующим образом.

console_handler = logging.StreamHandler()

Python Logger

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

Логгер включает три поля:

Для определение логгера используется имя. То есть, при создании лога, называющегося foo , все остальные вызовы logging.getLogger (“foo”) , будут возвращать одинаковый объект.

Еще одна характеристика корневого логгера в том, что обработчик создается при первичном входе в лог с уровнем, который превышает WARNING . Корневой логгер может не рекомендуется, если применять методы logging.debug() .

Что подразумевается под эффективным уровнем логгера?

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

В большинстве случаев эффективный уровень и уровень логгера – это одно и то же. Единственное исключение – если уровень не равен NOTSET. При этом, если уровень логгера равен этому, то тогда эффективным будет первый уровень родителя, у которого уровень важности не равняется NOTSET.

При стандартных параметрах, любой новый логгер будет иметь этот уровень. Так, как корневой логгер имеет уровень WARNING, эффективный уровень также будет таким.

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

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

Советы по работе с этим модулем

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

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

В этом посте мы покажем вам, как:

  • Настроить приоритет и расположение журналов.
    Создать пользовательские настройки, включающие несколько логгеров и адресатов.
  • Добавить трассировку исключений в логи.
  • Отформатировать логи в JSON и централизовать их.

Основы

Модуль logging включен в стандартную библиотеку Python. Метод basicConfig() — самый быстрый способ настройки. Тем не менее в документации рекомендуется создавать логгер для каждого модуля приложения, а значит, может быть сложно конфигурировать логгер для каждого модуля, используя только basicConfig(). Поэтому большинство приложений (включая веб-фреймворки, например, Django) автоматически ведут журналы на основе файлов или словаря. Если вы хотите начать с одного из этих методов, мы рекомендуем сразу перейти к нужному разделу.

У basicConfig() три основных параметра:

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

Поскольку по умолчанию пишутся только журналы WARNING и более высокого уровня, вам может не хватать логов с низким приоритетом. Кроме того, вместо StreamHandler или SocketHandler для потоковой передачи непосредственно на консоль или во внешнюю службу по сети, вам лучше использовать FileHandler, чтобы писать в один или несколько файлов на диске.

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

Базовый пример

В следующем примере используется basicConfig(), чтобы сконфигурировать приложение для логирования DEBUG и выше на диск, и указывается на наличие даты, времени и серьёзности в строке лога:

В Python существует встроенный модуль logging, который позволяет журналировать этапы выполнения программы. Логирование полезно когда, например, нужно оставить большой скрипт сбора / обработки данных на длительное время, а в случае возникновения непредвиденных ошибок выяснить, с чем они могут быть связаны. Анализ логов позволяет быстро и эффективно выявлять проблемные места в коде, но для удобного использования модуля следует написать несколько функций по взаимодействию с ним и вынести их в отдельный файл — сегодня мы этим и займёмся.

Пишем логгер

Создадим файл loggers.py. Для начала импортируем модули и задаём пару значений по умолчанию — директорию для файла с логом и наименование конфигурационного файла, содержащего шаблоны логирования. Его мы опишем следом.

Теперь опишем функцию создания нового логгера по заданному шаблону. Функция должна создать директорию для логирования, открыть конфигурационный файл и достать нужный шаблон. Затем по шаблону при помощи модуля logging создаём новый логгер:

Для удобства опишем ещё одну функцию — получение стандартного лога. Она ничего не принимает и нужна только для инициализации лога с шаблоном default:

Описываем конфигурационный файл

Создадим по соседству файл loggers.json — он будет содержать настройки логгера. Внутри указываем такие настройки, как версию логгера, форматы логирования для разных уровней, наименование выходного файла и его максимальный размер:

Использование логгера

logging vs loguru

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

Loguru же наоборот, позиционирует себя как максимально простая библиотека для логирования в Python.

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

Базовое применение

Сравним код для самого базового логирования. Будем записывать лог в файл.

Разберем немножко код. basicConfig — создаёт базовую конфигурацию для нашего логирования, filename — путь к файлу лога, level — уровень логирования. При logging.DEBUG он будет пропускать все записи в лог.

Думаю тут всё понятно и код выглядит весьма похоже. Но посмотрим на результат в файле и консоли.

Результат Loguru

Результат Loguru

И в консоли и в файле Loguru выглядит поинформативней сразу по умолчанию.

Форматирование

Давайте теперь попробуем сделать форматирование в Logger. Для этого есть метод .setFormatter Будем выводить время события, тип и само событие как в Loguru.

Ох ты ж! Кода стало гораздо больше. Давайте разберем новые классы и методы. Для начала у нас есть класс Handler . FileHandler для записи в файл и StreamHandler для запись в консоль. Затем нужно с помощью метода addHandler передать их в наш logger. В документации вы найдете еще несколько Handler .

В Loguru тоже есть форматирование. Делается это так: logger.add('logs/logs.log', level='DEBUG', format=" ")

Ротация / очистка / архивирование

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

Тут используется RotatingFileHandler . maxBytes — максимальный размер файла, backupCount — сколько файлов хранить.

Посмотрим как это можно сделать в Loguru:

Опять всё выглядит попроще и удобнее.

Обработка исключений

В Logging есть отдельный метод — exception . Это достаточно удобно и нужно применять его в блоке try except.

Лог будет выгледеть так:

В Loguru нам будет нужно использовать декоратор @logger.catch :

Вау! Лог выглядит круто. Даже показывает значение переменных:

Loguru обработка исключений

Loguru обработка исключений

Заключение

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

Читайте также: