JavaRush /Курси /Модуль 4: FastAPI /Логування помилок в асинхронних системах з Celery

Логування помилок в асинхронних системах з Celery

Модуль 4: FastAPI
Рівень 15 , Лекція 5
Відкрита

Логування — це ваш погляд у минуле і інструмент для аналізу поточних процесів. Уявіть, що ваша асинхронна система — це величезний потяг з безліччю вагонів (черг повідомлень), що мчить з великою швидкістю. Логи в цьому випадку — ваш провідник, бінокль і карта, які дозволяють розібратися, чому вагон зійшов з рейок або чому один з пасажирів (задач) вирішив вийти не на своїй зупинці.

Причини, чому варто налаштувати логування в асинхронних системах:

  1. Виявлення багів і точок відмови.
  2. Аналіз продуктивності системи.
  3. Легка діагностика проблем у продакшн-оточенні.
  4. Можливість ретроспективного аналізу і покращення роботи системи.

Конфігурація логерів для задач Celery

Celery підтримує стандартну бібліотеку логування Python. Це означає, що ви можете використовувати ті ж механізми, що вже вивчали для базового логування в Python, але з урахуванням специфіки асинхронної обробки.

Налаштуємо базовий логер для нашої асинхронної системи. На даний момент у нашому застосунку, створеному з використанням FastAPI і Celery, вже є базова обробка задач. Тепер ми додамо в нього логування.

Приклад базового логера


import logging
from celery import Celery

# Налаштування базового логера
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Налаштування Celery
app = Celery('tasks', broker='redis://localhost:6379/0')

@app.task(bind=True)
def example_task(self, x, y):
    try:
        result = x / y
        logger.info(f"Task executed successfully: {result}")
        return result
    except ZeroDivisionError as e:
        logger.error(f"Division by zero error: {e}")
        raise

Зверніть увагу на використання logger.info і logger.error. Ми реєструємо успішне виконання задачі і фіксуємо помилку, якщо раптом користувач вирішить поділити на цю саму легендарну одиницю з нулем у знаменнику.


Удосконалення логування

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

Логування з додатковою інформацією


import logging
from celery import Celery

# Налаштовуємо формат логів
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)

app = Celery('tasks', broker='redis://localhost:6379/0')

@app.task(bind=True)
def example_task(self, x, y):
    logger.info(f"Executing task {self.request.id} with arguments: x={x}, y={y}")
    try:
        result = x / y
        logger.info(f"Task {self.request.id} result: {result}")
        return result
    except ZeroDivisionError as e:
        logger.error(f"Task {self.request.id} failed: {e}")
        raise

Тепер у виводі логів ми будемо бачити унікальний ID задачі, вхідні параметри і часові мітки.


Інтеграція з зовнішніми інструментами для збору логів

Коли проєкт росте, а задач стає більше (а це обов'язково станеться, повірте), вам знадобиться щось потужніше, ніж консольний вивід логів. На допомогу приходять спеціалізовані інструменти, такі як Sentry, Logstash або весь могутній ELK-стек (Elasticsearch, Logstash, Kibana).

Інтеграція з Sentry

Sentry — це популярний інструмент для збору і аналізу помилок застосунків. Він чудово працює з Python (і Celery зокрема), надаючи зручний веб-інтерфейс для перегляду помилок.

Встановимо клієнт Sentry для Python:


pip install sentry-sdk[celery]

Тепер додамо інтеграцію в наш проєкт:


import sentry_sdk
from sentry_sdk.integrations.celery import CeleryIntegration

# Ініціалізуємо SDK
sentry_sdk.init(
    dsn="ВАШ_DSN",  # Замініть на ваш DSN з налаштувань проєкту в Sentry
    integrations=[CeleryIntegration()],
    traces_sample_rate=1.0, # Налаштування рівня відстеження трас
)

from celery import Celery

app = Celery('tasks', broker='redis://localhost:6379/0')

@app.task(bind=True)
def example_task(self, x, y):
    try:
        return x / y
    except ZeroDivisionError:
        # Помилка автоматично потрапить у Sentry
        raise

Тепер кожна помилка в задачі буде автоматично відправлятися в Sentry. У веб-інтерфейсі ви зможете побачити повний контекст, включаючи трасування стеку і навіть дані про продуктивність.


Використання ELK-стеку

Якщо ваш застосунок генерує дуже велику кількість логів, ELK-стек може виявитися відмінним рішенням. Базові концепти:

  • Logstash опрацьовує і маршрутизує логи.
  • Elasticsearch зберігає і індексує логи.
  • Kibana дозволяє візуалізувати дані і створювати зручні дашборди.

Налаштування може бути трохи складне, але в результаті ви отримаєте потужне сховище логів з інструментами аналізу продуктивності і помилок.


Моніторинг трендів і частоти помилок

Логування — це не лише спосіб зловити баг у системі, а й можливість зрозуміти, наскільки ефективно вона працює.

Приклад аналізу трендів

Припустимо, ви бачите сплеск помилок ZeroDivisionError на сервері. Замість того, щоб просто підвищувати таймаути або "глушити" помилки, перевірте:

  1. Хто викликає задачі з такими аргументами?
  2. Чи випадково користувачі не тестують ваш API на міцність?

Інтеграція з зовнішніми інструментами допомагає відстежувати такі аномалії і реагувати швидко.


Краща практика роботи з логуванням в Celery

  1. Не займайтеся "логоспамом".
    Намагайтеся логувати лише те, що дійсно корисно. Навіщо спамити розробників успіхами кожної задачі, якщо вони всім задоволені?
  2. Запис критичних помилок.
    Використовуйте рівні логування (ERROR, WARNING, INFO, DEBUG) для фільтрації записів. Наприклад:
    • INFO для інформації про запуск і успішне завершення задач.
    • ERROR для будь-яких виключень.
    • DEBUG для детального відлагодження.
  3. Використовуйте сторонні інструменти для централізованого зберігання логів.
    Сервіси на кшталт Sentry або ELK витримають навіть велику кількість логів і допоможуть швидко зорієнтуватися в проблемах.
  4. Регулярно аналізуйте логи.
    Навіть якщо ваш продукт працює стабільно, корисно дивитися на логи, щоб покращити продуктивність.

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

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ