Logging (журналирование) является важной частью разработки программного обеспечения. Он позволяет записывать сообщения об ошибках, предупреждениях, информационных и отладочных данных для последующего анализа и отладки.
В языке Python для журналирования используется стандартный модуль logging.
Для использования модуля logging в Python необходимо его импортировать с помощью команды import logging
.
Далее необходимо настроить журналирование, определить уровень логирования и задать обработчики сообщений. Наиболее часто используемый способ настройки журналирования - использование файла конфигурации.
Пример файла конфигурации logging.conf:
[loggers]
keys=root,sampleLogger
[handlers]
keys=consoleHandler, fileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler,fileHandler
[logger_sampleLogger]
level=DEBUG
handlers=consoleHandler,fileHandler
qualname=sampleLogger
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('app.log','w')
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S
В данном примере определена конфигурация с двумя логгерами - root
и sampleLogger
, двумя обработчиками - consoleHandler
и fileHandler
, и одним форматтером - simpleFormatter
. Каждая секция в файле конфигурации соответствует определенному объекту logging.
После настройки журналирования необходимо импортировать модуль logging.config
и вызвать метод fileConfig()
или dictConfig()
, передав ему путь к файлу конфигурации или словарь с настройками.
Пример использования файла конфигурации:
import logging
logging.config.fileConfig('logging.conf')
logger = logging.getLogger('sampleLogger')
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')
logger.critical('This is a critical message')
В данном примере мы импортируем модуль logging.config
и вызываем метод fileConfig()
, передавая ему путь к файлу конфигурации. Затем мы создаем логгер с именем sampleLogger
и вызываем методы для записи сообщений разного уровня.
После выполнения этого кода сообщения будут записаны в файл app.log
и выведены на консоль в соответствии с настройками в файле конфигурации.
Уровни логирования являются важным аспектом при разработке программного обеспечения. Они позволяют указать, насколько подробными могут быть сообщения, записываемые в журнал приложения. Уровни логирования помогают разработчикам контролировать количество информации, отображаемой в журнале, и облегчают поиск и анализ проблем, возникающих в процессе работы программы.
В программировании существуют различные уровни логирования, но наиболее распространенные из них следующие:
CRITICAL
: Самый высокий уровень логирования. Используется для сообщений, указывающих на критическую ситуацию, которая требует мгновенного вмешательства разработчика. Примеры: сбой приложения, неожиданная ошибка.ERROR
: Уровень ошибки. Используется для сообщений об ошибках, которые приводят к невозможности выполнения определенной операции или имеют серьезные последствия. Примеры: некорректные входные данные, ошибки базы данных.WARNING
: Уровень предупреждений. Используется для сообщений о потенциальных проблемах или неправильном использовании функций. Примеры: несовпадение версий библиотек, недостаточная память.INFO
: Уровень информации. Используется для отчетов о нормальной работе приложения. Примеры: статистика выполненных операций, успешное подключение к базе данных.DEBUG
: Самый низкий уровень логирования. Используется для подробной отладочной информации, которая помогает разработчику исследовать проблемы и проверять работу программы шаг за шагом. Примеры: значения переменных, вызовы функций.Модуль logging
поддерживает следующие уровни логирования:
DEBUG
: наиболее детальная информация для отладкиINFO
: информационные сообщенияWARNING
: предупрежденияERROR
: сообщения об ошибкахCRITICAL
: критические ошибки, которые могут привести к остановке программыВот несколько доступных переменных для форматирования логов:
asctime
: Дата и время создания сообщения лога. Формат может быть сконфигурирован с помощью метода Formatter
в объекте logging
.levelname
: Уровень сообщения лога (например, DEBUG
, INFO
, WARNING
, ERROR
, CRITICAL
).name
: Имя логгера, который создал запись лога.message
: Текст сообщения лога.pathname
: Полный путь к файлу, в котором произошло запись лога.filename
: Имя файла, в котором произошло запись лога.module
: Имя модуля, в котором произошло запись лога.lineno
: Номер строки, в которой произошло запись лога.funcName
: Имя функции, которая вызвала запись лога.process
: Идентификатор процесса, в котором произошло запись лога.thread
: Идентификатор потока, в котором произошло запись лога.Для форматирования сообщений лога можно использовать строку с плейсхолдерами %([имя_переменной])s
. Переменная будет заменена на соответствующее значение при записи сообщения в лог. Например, для записи сообщения с указанием даты и времени можно использовать следующий формат:
import logging
logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO)
logger = logging.getLogger()
logger.info('Сообщение для записи в лог')
В результате выполнения данного кода будет создана запись в лог с указанием текущей даты и времени перед текстом сообщения.
Также можно использовать другие переменные, указанные выше, для создания более информативных записей в логе. Например, можно добавить имя логгера, имя файла и номер строки в формат записи лога:
import logging
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(name)s - %(filename)s:%(lineno)d - %(message)s', level=logging.INFO)
logger = logging.getLogger('my_logger')
logger.info('Сообщение для записи в лог')
В результате выполнения данного кода будет создана запись в лог с указанием даты и времени, уровня сообщения лога, имени логгера, имени файла и номера строки перед текстом сообщения.
Форматирование сообщений лога в модуле logging
позволяет создавать информативные и разнообразные записи в лог, которые могут быть использованы для анализа и отладки приложения.
Класс FileHandler
в модуле logging
предоставляет возможность записи логов в файл. Он является одним из множества классов обработчиков, которые могут быть использованы для направления логов в различные источники, такие как файлы, консоль, сеть, база данных и другие.
Преимущества использования FileHandler
для логирования:
Пример использования класса FileHandler
:
import logging
# Создание объекта логгера
logger = logging.getLogger("my_logger")
logger.setLevel(logging.DEBUG)
# Создание объекта обработчика файла
file_handler = logging.FileHandler("my_logs.log")
# Настройка формата вывода логов
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
# Установка уровня логирования
file_handler.setLevel(logging.ERROR)
# Добавление обработчика файла к логгеру
logger.addHandler(file_handler)
# Запись логов
logger.debug("Debug message")
logger.info("Info message")
logger.warning("Warning message")
logger.error("Error message")
logger.critical("Critical message")
Код выше создает логгер с именем "my_logger" и устанавливает его уровень логирования на DEBUG
. Затем создается объект FileHandler
с именем файла "my_logs.log" для записи логов.
Настраивается формат вывода логов и устанавливается уровень логирования для файлового обработчика. В данном примере установлен уровень ERROR
, что означает, что будут записываться только сообщения об ошибках и критические сообщения.
Обработчик файла file_handler
добавляется к логгеру logger
. Затем можно использовать методы логгера, такие как debug()
, info()
, warning()
, error()
и critical()
, чтобы записать соответствующую категорию логов в файл "my_logs.log".
После выполнения кода в файле "my_logs.log" будут записаны только сообщения об ошибках и критические сообщения.
Использование класса FileHandler
позволяет эффективно логировать информацию в файле, что может быть полезным для отладки и анализа работы программы на более поздних этапах разработки.
Модуль logging
в языке Python предоставляет возможности для логгирования (записи) сообщений во время выполнения программы. Он предлагает различные классы для настройки и управления выводом сообщений лога.
Один из таких классов - StreamHandler
, который позволяет записывать сообщения лога в любой поток (например, в поток вывода данных sys.stdout
). Это может быть полезно, когда необходимо выводить логи в консоль или в другое место, доступное через поток.
Пример использования класса StreamHandler
вместе с модулем logging
:
import logging
# Создаем экземпляр объекта логгера
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)
# Создаем экземпляр объекта StreamHandler и устанавливаем уровень логирования
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
# Создаем форматирование для сообщений лога
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# Применяем форматирование к обработчику
handler.setFormatter(formatter)
# Добавляем обработчик к логгеру
logger.addHandler(handler)
# Примеры записи сообщений в лог
logger.debug('Отладочное сообщение')
logger.info('Информационное сообщение')
logger.warning('Предупреждение')
logger.error('Ошибка')
logger.critical('Критическая ошибка')
В данном примере мы сначала создаем экземпляр объекта logger
с именем "my_logger" и устанавливаем уровень логирования на DEBUG
. Затем мы создаем экземпляр объекта StreamHandler
, устанавливаем уровень логирования на DEBUG
и добавляем созданное форматирование. Затем мы добавляем созданный обработчик handler
к нашему логгеру logger
.
Далее мы можем использовать наш логгер logger
для записи различных уровней сообщений лога. В данном примере используются уровни DEBUG
, INFO
, WARNING
, ERROR
и CRITICAL
. Каждое сообщение лога будет отформатировано с использованием заданного в форматировании шаблона и выведено в поток вывода данных (в данном случае - в стандартный поток вывода).
Обратите внимание, что метод debug()
применим только если уровень логирования логгера установлен на DEBUG
или на более низкий уровень. Аналогично, методы info()
, warning()
, error()
и critical()
будут работать в зависимости от уровня логирования.
Вы можете настроить класс StreamHandler
для записи в любой другой поток, указав его в качестве аргумента при создании объекта StreamHandler
. Например, вместо потока вывода данных (sys.stdout
) вы можете использовать файловый поток или любой другой поддерживаемый поток.
Использование класса StreamHandler
вместе с модулем logging
предоставляет мощные возможности для контроля и анализа работы программы через запись сообщений лога в желаемый поток вывода. Это может быть важным инструментом при разработке и отладке программного обеспечения.
Для создания пользовательского обработчика логов необходимо унаследовать класс от базового обработчика logging.Handler
. В пользовательском обработчике можно определить, какую информацию записывать и куда её записывать.
Пример кода пользовательского обработчика CustomHandler
:
import logging
class CustomHandler(logging.Handler):
def __init__(self, filename):
super().__init__()
self.filename = filename
def emit(self, record):
log_entry = self.format(record)
# Здесь можно определить, куда и как записывать логи
with open(self.filename, 'a') as f:
f.write(log_entry + '\n')
В приведенном примере пользовательский обработчик CustomHandler
наследуется от logging.Handler
. В методе emit
определено, что записывать логи будем в файл, указанный в конструкторе обработчика.
После создания пользовательского обработчика логов, его можно добавить в логгер, чтобы начать записывать логи в указанное место.
Пример кода, добавляющего пользовательский обработчик в логгер:
import logging
# Создание экземпляра пользовательского обработчика
custom_handler = CustomHandler('app.log')
# Создание логгера
logger = logging.getLogger('my_logger')
# Установка уровня логгирования
logger.setLevel(logging.DEBUG)
# Добавление обработчика логов
logger.addHandler(custom_handler)
# Пример записи логов
logger.debug('Debug message')
logger.info('Info message')
logger.warning('Warning message')
logger.error('Error message')
logger.critical('Critical message')
В приведенном примере пользовательский обработчик custom_handler
создается с указанием имени файла, в который будут записываться логи. Затем создается логгер logger
, устанавливается уровень логгирования и добавляется обработчик логов custom_handler
.
После этого можно начинать записывать логи с помощью методов логгера, таких как debug()
, info()
, warning()
, error()
и critical()
.
Использование пользовательского обработчика логов в модуле logging
позволяет настроить запись логов по своим предпочтениям и в нужное место. Создавая собственный обработчик, можно определить, какую информацию записывать и куда ее записывать, что сделает логгирование более гибким и адаптированным под конкретные потребности приложения.
Класс Filter
в модуле logging
языка Python предоставляет возможность выполнять фильтрацию записей журнала на основе определенных условий. Фильтры позволяют выбирать только нужные записи для вывода или сохранения.
Для использования класса Filter
необходимо создать пользовательский класс, который будет наследоваться от класса Filter
. В этом классе нужно определить метод filter(record)
, который будет выполнять фильтрацию. Метод filter(record)
должен принимать один параметр - объект LogRecord
, который содержит информацию о текущей записи журнала.
В методе filter(record)
необходимо реализовать логику фильтрации и возвращать True
или False
в зависимости от результата. Если метод возвращает True
, то запись будет сохранена или выведена в журнал. Если метод возвращает False
, то запись будет проигнорирована.
Пример создания фильтра с использованием класса Filter
:
import logging
class CustomFilter(logging.Filter):
def filter(self, record):
# Фильтрация записей по уровню логирования
if record.levelname == 'ERROR':
return True
else:
return False
# Создание объекта логгера
logger = logging.getLogger()
# Создание объекта фильтра
custom_filter = CustomFilter()
# Добавление фильтра в логгер
logger.addFilter(custom_filter)
# Логирование
logger.error('Это сообщение об ошибке')
logger.warning('Это предупреждение')
logger.info('Это информационное сообщение')
В данном примере создается пользовательский класс CustomFilter
, который наследуется от класса Filter
. В методе filter(record)
определена фильтрация записей по уровню логирования. Если уровень логирования равен "ERROR", то метод возвращает True
и запись сохраняется или выводится в журнал.
Затем создается объект логгера и объект фильтра. Фильтр добавляется в логгер с помощью метода addFilter()
. В результате, только записи с уровнем логирования "ERROR" будут сохранены или выведены в журнал.
Вывод программы:
ERROR:root:Это сообщение об ошибке
Один из ключевых классов модуля logging
- Formatter
. Этот класс позволяет настраивать формат вывода логов, т.е. указывать, какая информация будет содержаться в каждой записи лога и как она будет отформатирована.
Пример использования класса Formatter
:
import logging
# Создаем объект логгера
logger = logging.getLogger('my_logger')
logger.setLevel(logging.INFO)
# Создаем объект форматирования
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# Создаем объект потока вывода
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
# Добавляем поток вывода к логгеру
logger.addHandler(stream_handler)
# Логирование сообщений
logger.debug('Отладочное сообщение')
logger.info('Информационное сообщение')
logger.warning('Предупреждающее сообщение')
logger.error('Ошибка')
logger.critical('Критическая ошибка')
В данном примере мы создаем логгер с именем my_logger
и устанавливаем уровень логирования INFO
. Затем мы создаем объект форматирования Formatter
, указывая нужный нам формат записей лога - в данном случае '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
.
После этого мы создаем объект потока вывода StreamHandler
и устанавливаем для него созданный объект форматирования. Затем мы добавляем этот поток вывода к нашему логгеру с помощью метода addHandler()
.
В конечном итоге, при вызове методов логгера (debug()
, info()
, warning()
, error()
, critical()
) записи логов будут выводиться на консоль в нужном формате, заранее указанном с помощью объекта Formatter
.
Вывод программы:
2022-06-01 10:15:30,123 - my_logger - INFO - Информационное сообщение
2022-06-01 10:15:30,123 - my_logger - WARNING - Предупреждающее сообщение
2022-06-01 10:15:30,123 - my_logger - ERROR - Ошибка
2022-06-01 10:15:30,123 - my_logger - CRITICAL - Критическая ошибка
В языке Python есть модуль logging
, который предоставляет возможность логгирования (записи журнала) различных событий во время работы программы. Он позволяет сохранять информацию о происходящих событиях в различных местах, включая файлы, консоль, базы данных и даже отправлять уведомления на почту.
В этой статье мы рассмотрим, как настроить логгирование на email с помощью модуля logging
. Давайте начнем с импорта необходимых модулей:
import logging
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
Первым делом нам необходимо настроить объект logging
в соответствии с нашими потребностями. Для этого мы можем воспользоваться функцией basicConfig()
, указав необходимые параметры, такие как уровень логирования (level
) и формат сообщения (format
).
Добавим следующий код в начало нашей программы:
logging.basicConfig(filename='app.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
В данном примере мы настроили логгирование, чтобы записывать все сообщения в файл app.log
с уровнем логирования DEBUG
. Также мы задали формат вывода сообщения, который включает дату и время записи, уровень логирования и текст сообщения.
Теперь нам нужно создать функцию для отправки логов на email. Она будет принимать список адресов электронной почты, тему письма и текст сообщения. Эту функцию можно использовать внутри обработчика логов:
def send_email(emails, subject, message):
smtp_server = 'mail.example.com'
smtp_port = 587
smtp_username = 'your@email.com'
smtp_password = 'your_password'
sender = 'your@email.com'
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = ', '.join(emails)
msg['Subject'] = subject
msg.attach(MIMEText(message, 'plain'))
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls()
server.login(smtp_username, smtp_password)
server.send_message(msg)
server.quit()
В этом примере мы создали функцию send_email
, которая подключается к SMTP-серверу, отправляет пустое сообщение с указанными заголовками и содержимым.
Осталось только настроить обработчик логов для отправки сообщений на email. Для этого мы можем использовать класс logging.handlers.SMTPHandler
:
smtp_handler = logging.handlers.SMTPHandler(mailhost='mail.example.com',
fromaddr='your@email.com',
toaddrs=['recipient@email.com'],
subject='Error',
credentials=('your@email.com', 'your_password'))
smtp_handler.setLevel(logging.ERROR)
logging.getLogger('').addHandler(smtp_handler)
В данном примере мы создали обработчик SMTPHandler
, который будет отправлять сообщения об ошибках (ERROR
уровень логирования). Указанные параметры mailhost
, fromaddr
, toaddrs
, subject
, credentials
должны быть заменены на реальные значения.
Теперь каждый раз, когда будет сгенерировано сообщение с уровнем логирования ERROR
, оно будет отправлено на указанный email адрес.
Полный пример кода:
import logging
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import logging.handlers
# Настройка логгирования
logging.basicConfig(filename='app.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
# Функция для отправки email
def send_email(emails, subject, message):
smtp_server = 'mail.example.com'
smtp_port = 587
smtp_username = 'your@email.com'
smtp_password = 'your_password'
sender = 'your@email.com'
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = ', '.join(emails)
msg['Subject'] = subject
msg.attach(MIMEText(message, 'plain'))
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls()
server.login(smtp_username, smtp_password)
server.send_message(msg)
server.quit()
# Настройка обработчика логов для отправки email
smtp_handler = logging.handlers.SMTPHandler(mailhost='mail.example.com',
fromaddr='your@email.com',
toaddrs=['recipient@email.com'],
subject='Error',
credentials=('your@email.com', 'your_password'))
smtp_handler.setLevel(logging.ERROR)
logging.getLogger('').addHandler(smtp_handler)
# Пример использования логгирования
logging.debug('Отладочное сообщение')
logging.info('Информационное сообщение')
logging.warning('Предупреждающее сообщение')
logging.error('Ошибка')
logging.critical('Критическая ошибка')
В этой абзаце мы рассмотрим пример логирования в Telegram с помощью модуля logging
и пользовательского обработчика, унаследованного от logging.Handler
. Для этого мы будем использовать библиотеку requests
для взаимодействия с API Telegram.
Прежде чем приступить к примеру, убедитесь, что у вас установлены модуль requests
и настроены необходимые доступы для работы с API Telegram.
Предполагается, что у вас уже установлен Python на вашей системе. Чтобы начать использовать модуль logging
и отправлять логи в Telegram, вам также понадобятся следующие модули:
Вы можете установить модули с помощью команды pip
, выполнив следующие команды в командной строке:
pip install requests
Для начала создадим пользовательский обработчик TelegramHandler
, который будет отправлять логи в Telegram. Для этого нам понадобится получить токен бота и идентификатор чата в Telegram:
import logging
import requests
class TelegramHandler(logging.Handler):
def __init__(self, token, chat_id):
super().__init__()
self.token = token
self.chat_id = chat_id
def emit(self, record):
log_entry = self.format(record)
url = f"https://api.telegram.org/bot{self.token}/sendMessage"
params = {
"chat_id": self.chat_id,
"text": log_entry
}
response = requests.get(url, params=params)
if response.status_code != 200:
raise ValueError("Failed to send log entry to Telegram")
self.close()
В приведенном коде мы создаем класс TelegramHandler
, унаследованный от logging.Handler
. В конструкторе класса мы принимаем токен бота token
и идентификатор чата chat_id
, которые будут использоваться для отправки логов.
В методе emit()
класса мы форматируем запись лога с помощью метода self.format(record)
и отправляем ее через API Telegram с помощью библиотеки requests
. Если возникает ошибка при отправке, мы выбрасываем исключение.
Теперь создадим и настроим логгер с использованием нашего обработчика:
# Устанавливаем уровень логирования
logging.basicConfig(level=logging.WARNING)
# Создаем логгер
logger = logging.getLogger(__name__)
# Создаем обработчик TelegramHandler
telegram_handler = TelegramHandler("YOUR_BOT_TOKEN", "YOUR_CHAT_ID")
# Устанавливаем уровень логирования для обработчика
telegram_handler.setLevel(logging.ERROR)
# Создаем форматировщик и устанавливаем его для обработчика
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
telegram_handler.setFormatter(formatter)
# Добавляем обработчик в логгер
logger.addHandler(telegram_handler)
# Пример записи логов
logger.error("This is an error message")
logger.warning("This is a warning message")
В приведенном примере мы настраиваем логгер таким образом, чтобы он записывал только сообщения с уровнем ERROR и более высоким. Мы также создаем форматировщик с помощью класса logging.Formatter
и указываем его для нашего обработчика с помощью метода setFormatter()
.
Для отправки логов в Telegram мы создаем экземпляр TelegramHandler
с указанием токена бота и идентификатора чата. Затем мы устанавливаем его уровень логирования и добавляем в логгер с помощью метода addHandler()
.
В результате при вызове методов logger.error()
и logger.warning()
логи будут отправлены в Telegram.