Тепер, коли наш бот активно взаємодіє з користувачами і, можливо, вже жартує, настав час додати важливий компонент — логування. Воно допоможе нам відстежувати поведінку бота, знаходити помилки і бути справжнім "Шерлоком Холмсом" свого коду.
Уяви, ти розробив чудового Telegram-бота. Усе добре, але раптом якийсь користувач каже, що бот надіслав йому дивну, безглузду відповідь. Без логів твої спроби знайти причину помилки будуть схожі на пошук голки в сіні. Логи — це твоя карта, яка допоможе зрозуміти, що сталося, де і чому.
Основні завдання логування:
- Діагностика помилок: відстеження помилок і проблем у боті.
- Моніторинг: отримання інформації про те, як бот працює в реальному часі.
- Аналітика: розуміння, які команди і функції бота використовуються найчастіше.
- Налагодження: усунення помилок під час розробки.
У Python стандартним інструментом для логування є модуль logging із стандартної бібліотеки. Хороша новина в тому, що він легко інтегрується в наші боти!
Вступ у Python Logging
Перед тим як застосовувати логування в нашому Telegram-боті, давай розберемо основи роботи з модулем logging.
Базовий приклад логування
import logging
# Налаштування базового логування
logging.basicConfig(level=logging.INFO)
# Приклади логування повідомлень
logging.debug("Це повідомлення для налагодження.")
logging.info("Це інформаційне повідомлення.")
logging.warning("Це попередження!")
logging.error("Сталася помилка!")
logging.critical("Критична помилка!")
Рівні логування
Логування передбачає поділ повідомлень за рівнями критичності:
DEBUG: Детальна інформація, корисна для налагодження.INFO: Інформаційні повідомлення про нормальну роботу.WARNING: Попередження про потенційні проблеми.ERROR: Інформація про виниклу помилку.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("Це повідомлення буде логуватися асинхронно")
Тепер твоєму боту не страшні помилки: їх можна швидко виявити і виправити, аналізуючи логи. Ти став не тільки розробником, а й справжнім "детективом" у світі програмування.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ