Логирование в Python. Модуль logging. Часть 1
moderator E7
В данной статье разберем модуль в Python logging , а также узнаем зачем он используется в 90% модулей .
1.Модуль Logging
Итак , для каких целей нам нужен этот модуль:
- Форматирование логов
- Фильтрация логов
- Отправка логов в разные цели
Большинство людей не знают, что писать в логи, поэтому решают логировать все, что угодно, думая, что все подряд – это в любом случае лучше, чем ничего, и, в конечном итоге, просто создают шум. А шум – это информация, которая никак не помогает вашей команде понять, в чем дело и как решить проблему.
Цель статьи - решить данную проблему и объяснить на практических примерах как работает логирование.
Теперь перейдем к практике:
Для начала добавим модуль logging в нашу программу на Python , сделать это довольно просто :
import logging
С импортированным модулем logging вы можете использовать то, что называется «logger», для логирования сообщений, которые вы хотите видеть. По умолчанию существует 5 стандартных уровней severity, указывающих на важность событий. У каждого есть соответствующий метод, который можно использовать для логирования событий на выбранном уровне severity. Список уровней в порядке увеличения важности:
- DEBUG(10)
- INFO(20)
- WARNING(30)
- ERROR(40)
- CRITICAL(50)
Модуль logging предоставляет вам логер по умолчанию, который позволяет вам начать работу без дополнительных настроек. Соответствующие методы для каждого уровня можно вызвать, как показано в следующем примере:
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')
WARNING:root:This is a warning message ERROR:root:This is an error message CRITICAL:root:This is a critical message
Вывод показывают уровень важности перед каждым сообщением вместе с root, который является именем, которое модуль logging дает своему логеру по умолчанию. Этот формат, который показывает уровень, имя и сообщение, разделенные двоеточием (:), является форматом вывода по умолчанию, и его можно изменить для включения таких вещей, как отметка времени, номер строки и других деталей.
Обратите внимание, что сообщения debug() и info() не были отображены. Это связано с тем, что по умолчанию модуль ведения журнала регистрирует сообщения только с уровнем WARNING(30) или выше. Вы можете изменить это, сконфигурировав модуль logging для регистрации событий всех уровней. Вы также можете определить свои собственные уровни, изменив конфигурации, но, как правило, это не рекомендуется, так как это может привести к путанице с журналами некоторых сторонних библиотек, которые вы можете использовать.
2.Форматирование логов
Базовая конфигурация
Этот метод модуля logging мы будем использовать для конфигурации логов:
basicConfig(**kwargs)
Если вы внимательный читатель , вы могли заметить что метод написан в стиле camelCase , а не в snake_case как по правилам PEP8. Все это из-за того , что пакет был адаптирован из другого ЯП . Этим языком является Java , а адаптированная утилита - Log4j
У метода есть следующие параметры:
level: Корневой логер с установленным указанным уровнем важности (severity).filename: Указание файла логовfilemode: Режим открытия файла. По умолчанию это a, что означает добавление.format: Формат сообщений.
Это основные параметры . Разберем каждый по порядку:
Используя параметр level, вы можете установить, какой уровень сообщений журнала вы хотите записать. Это можно сделать, передав одну из констант, доступных в классе, и это позволило бы регистрировать все вызовы logging на этом уровне или выше. Вот пример:
import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug('This will get logged')
DEBUG:root:This will get logged
Теперь будут регистрироваться все события на уровне DEBUG или выше.
Аналогично, для записи логов в файл, а не в консоль, можно использовать filename и filemode, и вы можете выбрать формат сообщения, используя format. В следующем примере показано использование всех трех переменных:
import logging
logging.basicConfig(filename='app.log', filemode='w',
format='%(name)s - %(levelname)s - %(message)s')
logging.warning('This will get logged to a file')
root - ERROR - This will get logged to a file
Сообщение будет записано в файл с именем app.log вместо вывода в консоль. Для filemode значение w означает, что файл журнала открывается в «режиме записи» каждый раз, когда вызывается basicConfig(), и при каждом запуске программы файл перезаписывается. Конфигурацией по умолчанию для filemode является a, которое является добавлением.
Вы можете настроить корневой logger еще больше, используя дополнительные параметры для basicConfig(), которые можно найти в конце статьи.
Следует отметить, что вызов basicConfig() для настройки корневого logger работает, только если корневой logger не был настроен ранее. По сути, эта функция может быть вызвана только один раз.
debug(), info(), warning(), error() и crit() также автоматически вызывают basicConfig() без аргументов, если он ранее не вызывался.
Это означает, что после первого вызова одной из вышеперечисленных функций вы больше не сможете изменить настройки корневого logger.
Формат вывода
В этом разделе разберем , как оформить все красиво и главное понятно для разработчиков.
Можно передавать любую переменную, которая может быть представлена в виде строки из вашей программы в виде сообщения в ваши журналы, есть некоторые базовые элементы, которые уже являются частью LogRecord (такие как в примере - process , levelname и message) и могут быть легко добавлены в выходной формат.
Если вы хотите записать идентификатор процесса ID вместе с уровнем и сообщением, вы можете сделать что-то вроде этого:
import logging
logging.basicConfig(format='%(process)d-%(levelname)s-%(message)s')
logging.warning('This is a Warning')
18472-WARNING-This is a Warning
Можно добавить время создания логов с помощью %(asctime)s .
Формат можно изменить с помощью атрибута datefmt, который использует тот же язык форматирования, что и функции форматирования в модуле datetime, например time.strftime():
import logging
logging.basicConfig(format='%(asctime)s - %(message)s',
datefmt='%d-%b-%y %H:%M:%S')
logging.warning('Admin logged out')
24-Aug-22 20:53:19 - Admin logged out
Вы можете найти больше информации о формате datetime в руководстве в конце статьи.
3.Заключение
На этом закончим первую часть статьи , а в следующей продолжим с:
Логирование переменных
Вывод стека
Свой класс logger
И многое другое , что позволит полностью познать логирование в Python
По всем вопросам пишите в комментарии , вам с радостью ответят ;)
С любовью от #E7TEAM
Ссылки на доп. материалы: