JavaRush /Курсы /Модуль 4: FastAPI /Логирование событий и ошибок в боте

Логирование событий и ошибок в боте

Модуль 4: FastAPI
18 уровень , 7 лекция
Открыта

Теперь, когда наш бот активно взаимодействует с пользователями и, возможно, уже шутит, настало время добавить важный компонент — логирование. Оно поможет нам отслеживать поведение бота, находить ошибки и быть настоящим "Шерлоком Холмсом" своего кода.

Представь, ты разработал замечательного Telegram-бота. Всё отлично, но вдруг какой-то пользователь говорит, что бот отправил ему странный, бессмысленный ответ. Без логов твои попытки найти причину ошибки будут похожи на попытку найти иголку в стоге сена. Логи — это твоя карта, которая поможет понять, что произошло, где и почему.

Основные задачи логирования:

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

В Python стандартным инструментом для логирования является модуль logging из стандартной библиотеки. Хорошая новость в том, что он легко интегрируется в наши боты!


Введение в Python Logging

Перед тем как применять логирование в нашем Telegram-боте, давай разберем основы работы с модулем logging.

Базовый пример логирования


import logging

# Настройка базового логирования
logging.basicConfig(level=logging.INFO)

# Примеры логирования сообщений
logging.debug("Это сообщение для отладки.")
logging.info("Это информационное сообщение.")
logging.warning("Это предупреждение!")
logging.error("Произошла ошибка!")
logging.critical("Критическая ошибка!")

Уровни логирования

Логирование подразумевает разделение сообщений на уровни критичности:

  1. DEBUG: Подробная информация, полезная для отладки.
  2. INFO: Информационные сообщения о нормальной работе.
  3. WARNING: Предупреждения о потенциальных проблемах.
  4. ERROR: Информация о произошедшей ошибке.
  5. CRITICAL: Сообщения о критических ошибках.

Когда ты устанавливаешь уровень логирования, например, INFO, сообщения уровнем ниже (например, DEBUG) не будут отображаться.


Настройка логирования в Telegram-боте

Шаг 1: Импортируем и настраиваем logging

Давайте добавим logging в наш бот. Настроим базовое логирование и будем записывать события, такие как входящие сообщения, команды пользователей и ошибки.


import logging
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters

# Настраиваем базовый конфиг для логирования
logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    level=logging.INFO
)

# Получаем объект логгера
logger = logging.getLogger(__name__)

# Обработчики команд
async def start(update: Update, context):
    logger.info("Получена команда /start от пользователя %s", update.effective_user.username)
    await update.message.reply_text("Привет! Я твой бот. Чем могу помочь?")

async def help(update: Update, context):
    logger.info("Получена команда /help от пользователя %s", update.effective_user.username)
    await update.message.reply_text("Вот список доступных команд: /start, /help")

async def echo(update: Update, context):
    logger.info("Пользователь %s сказал: '%s'", update.effective_user.username, update.message.text)
    await update.message.reply_text(update.message.text)

# Основной код приложения
if __name__ == '__main__':
    app = ApplicationBuilder().token("YOUR_TELEGRAM_BOT_TOKEN").build()

    app.add_handler(CommandHandler("start", start))
    app.add_handler(CommandHandler("help", help))
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))

    logger.info("Бот запущен и готов к работе!")
    app.run_polling()
  • %(asctime)s: Время выполнения (в формате даты и времени).
  • %(name)s: Имя логгера.
  • %(levelname)s: Уровень логирования (INFO, DEBUG и т.д.).
  • %(message)s: Само сообщение.

Шаг 2: Логирование ошибок

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


from telegram.error import TelegramError

# Обработчик ошибок
async def error_handler(update: object, context):
    logger.error("Произошла ошибка: %s", context.error)

# Добавляем обработчик ошибок в приложение
app.add_error_handler(error_handler)

Теперь любые ошибки, возникшие в процессе обработки запросов бота, будут логироваться.


Логирование в файлы

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


import logging

# Настройка логирования в файл
logging.basicConfig(
    filename='bot.log',  # Имя файла
    filemode='a',        # Режим записи (a - append, w - overwrite)
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    level=logging.INFO
)

# Пример логирования
logging.info("Логирование настроено на запись в файл.")

Теперь все логи будут сохраняться в файл bot.log.


Логирование с ротацией файлов

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

Рассмотрим пример с использованием TimedRotatingFileHandler из модуля logging.


from logging.handlers import TimedRotatingFileHandler

# Создаем обработчик ротации логов
handler = TimedRotatingFileHandler("bot.log", when="midnight", interval=1)
handler.suffix = "%Y-%m-%d"

# Настраиваем формат логирования
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)

# Добавляем обработчик к логгеру
logger.addHandler(handler)
logger.setLevel(logging.INFO)

logger.info("Лог с ротацией готов!")

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


Отслеживание пользователей и их ошибок

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


async def save_user_data(update: Update, context):
    try:
        user_id = update.effective_user.id
        logger.info("Сохранение данных пользователя %s", user_id)
        # Пример работы с базой данных
        # db.save(user_id, some_data)
    except Exception as e:
        logger.error("Ошибка сохранения данных пользователя %s: %s", user_id, str(e))
        await update.message.reply_text("Произошла ошибка. Попробуйте позже.")

Логирование в асинхронных контекстах

FastAPI и асинхронная обработка сообщений требуют немного внимания при работе с логами. Чтобы упростить работу, можно использовать библиотеку aiologger.

Установим её:


pip install aiologger

И используем:


from aiologger import Logger

# Создаем асинхронный логгер
async_logger = Logger.with_default_handlers()

# Пример асинхронного логирования
await async_logger.info("Это сообщение будет логироваться асинхронно")

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

1
Задача
Модуль 4: FastAPI, 18 уровень, 7 лекция
Недоступна
Настройка базового логирования в Telegram-боте
Настройка базового логирования в Telegram-боте
1
Задача
Модуль 4: FastAPI, 18 уровень, 7 лекция
Недоступна
Логирование ошибок и успешности обработки запросов
Логирование ошибок и успешности обработки запросов
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ