Настройка мониторинга и алертов на сбои граббинга

Парсер упал ночью, а вы узнали об этом только утром — потерянные данные и упущенная выгода. Мы настраиваем мониторинг и алерты на сбои граббинга, чтобы вы всегда были в курсе. Наша команда реализует систему оповещений под ключ — от heartbeat-метрик до уведомлений в Telegram, с многолетним опытом и последующей поддержкой.

Настройка мониторинга и алертов на сбои граббинга

Блокчейн инфраструктураПростойот 1 дня до 3 дней
Часто задаваемые вопросы

Парсер упал в 3 ночи, данные перестали обновляться — и никто не узнал до утра. Для крипто-проекта каждый час простоя парсера ценовых данных с Binance или CoinGecko — это потерянные сделки, устаревшие ордера и slippage в DeFi-протоколах. Средняя стоимость такого даунтайма может превышать $500 в час. Для проекта с ликвидным пулом на $10 млн каждый час простоя — $500–$1000 убытков. Даже один незамеченный сбой способен обернуться тысячами долларов упущенной ликвидности. Мониторинг граббинга мы не сводим к установке Prometheus и забыванию. Это продуманная система сигналов: что именно сломалось, насколько критично, кому сообщить и в какой форме. За 5 лет работы мы настроили мониторинг для 30+ парсеров в крипто- и финтех-проектах. Ниже — конкретная архитектура, которую мы используем в продакшене.

Почему стандартный мониторинг не спасает?

Типичная ошибка — мониторить только доступность HTTP-эндпоинта. Парсер может висеть в бесконечном цикле, получать пустые ответы или падать с rate limit, но эндпоинт будет отвечать 200. Нужна heartbeat-метрика от каждого запуска и детекция трёх классов проблем. Два из трёх сбоев — частичные, и их не видит мониторинг доступности. 75% ложных алертов можно отсечь настройкой порогов.

Класс сбоя Пример Обнаружение Критичность
Полный Парсер не запустился Нет heartbeat > порога Critical
Частичный Данные неполные records_fetched < minExpected Warning
Деградация Медленная работа Duration > maxDurationMs Warning

Как отличить частичный сбой от полного?

Полный сбой — парсер не запустился или упал (проверка по timestamp последнего успешного запуска). Частичный — парсер работает, но данные неполные (число записей ниже порога) или есть ошибки. Частичный сбой опаснее, так как проходит незамеченным без метрик количества записей. Heartbeat-мониторинг в 3 раза надёжнее простой проверки статуса, поскольку фиксирует качество данных, а не только факт запуска.

Heartbeat метрика: основа мониторинга

Каждый запуск парсера должен фиксировать результат. Пример на TypeScript:

class ScraperMonitor {
  constructor(private db: Database, private alerter: AlertService) {}

  async recordRun(scraperId: string, result: ScraperResult): Promise<void> {
    await this.db('scraper_runs').insert({
      scraper_id: scraperId,
      started_at: result.startedAt,
      finished_at: result.finishedAt,
      duration_ms: result.finishedAt.getTime() - result.startedAt.getTime(),
      records_fetched: result.recordsFetched,
      records_saved: result.recordsSaved,
      errors_count: result.errors.length,
      status: result.errors.length === 0 ? 'success' : 'partial_failure',
      error_details: result.errors.length > 0 ? JSON.stringify(result.errors) : null,
    })
    await this.checkThresholds(scraperId, result)
  }

  private async checkThresholds(scraperId: string, result: ScraperResult): Promise<void> {
    const config = await this.getScraperConfig(scraperId)
    if (result.recordsFetched < config.minExpectedRecords) {
      await this.alerter.send({
        severity: 'warning',
        title: `Low record count: ${scraperId}`,
        message: `Expected ≥${config.minExpectedRecords}, got ${result.recordsFetched}`,
      })
    }
    if (result.finishedAt.getTime() - result.startedAt.getTime() > config.maxDurationMs) {
      await this.alerter.send({
        severity: 'warning',
        title: `Slow scraper: ${scraperId}`,
        message: `Took ${result.finishedAt.getTime() - result.startedAt.getTime()}ms, threshold ${config.maxDurationMs}ms`,
      })
    }
  }
}

Heartbeat-метрики — стандарт мониторинга распределенных систем. Документация Prometheus.

Детекция staleness: данные устарели

Основная проверка — когда последний раз успешно обновлялись данные. SQL-запрос для выявления парсеров, зависших более чем на 1.5 ожидаемых интервала:

SELECT sc.id, sc.name, sc.expected_interval_minutes,
       MAX(sr.finished_at) AS last_success,
       EXTRACT(EPOCH FROM (NOW() - MAX(sr.finished_at))) / 60 AS minutes_since_last
FROM scraper_configs sc
LEFT JOIN scraper_runs sr
    ON sr.scraper_id = sc.id AND sr.status = 'success'
GROUP BY sc.id, sc.name, sc.expected_interval_minutes
HAVING EXTRACT(EPOCH FROM (NOW() - MAX(sr.finished_at))) / 60 > sc.expected_interval_minutes * 1.5
ORDER BY minutes_since_last DESC;

Этот запрос мы запускаем каждые 5 минут через отдельный watchdog-процесс. Важно: watchdog должен быть независимым — если парсер упадёт, watchdog продолжит мониторинг.

Почему watchdog должен быть независимым?

Watchdog — это внешний процесс (например, cron-задача на отдельном сервере), который проверяет staleness. Если парсер завис, watchdog увидит, что last_success_timestamp не обновляется, и отправит алерт. Если watchdog запускать внутри парсера, при падении парсера watchdog тоже упадёт — и алерт не придёт. Это классическая проблема single point of failure. По опыту, 30% инцидентов связаны именно с тем, что мониторинг не пережил падения основного сервиса.

Алертинг: каналы и приоритеты

Каналы оповещения выбираем по severity:

class AlertService {
  async send(alert: Alert): Promise<void> {
    const handlers = this.getHandlersForSeverity(alert.severity)
    await Promise.all(handlers.map(h => h.send(alert)))
  }

  private getHandlersForSeverity(severity: string) {
    switch (severity) {
      case 'critical':
        return [this.telegram, this.pagerDuty] // будит людей
      case 'warning':
        return [this.telegram] // в рабочее время
      case 'info':
        return [this.slackChannel] // для логов
    }
  }
}

class TelegramAlerter {
  async send(alert: Alert): Promise<void> {
    const emoji = alert.severity === 'critical' ? '🔴' : '🟡'
    const text = `${emoji} *${alert.title}*\n\n${alert.message}\n\n_${new Date().toISOString()}_`
    await fetch(`https://api.telegram.org/bot${this.token}/sendMessage`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        chat_id: this.chatId,
        text,
        parse_mode: 'Markdown',
      }),
    })
  }
}

Grafana дашборд для визуального мониторинга

Ключевые панели на дашборде:

  • Success rate по скраперам — процент успешных запусков за последние 24h. Если падает ниже 95% — предупреждение.
  • Records per run — временной ряд количества собранных записей. Аномальный провал хорошо виден на графике.
  • Duration heatmap — распределение времени выполнения. Медленные outlier-ы сигнализируют о проблемах с источником.

Prometheus-метрики из парсера:

# Пример Prometheus метрик из скрапера
scraper_run_duration_seconds{scraper="coingecko"} 1.245
scraper_records_fetched_total{scraper="coingecko"} 4521
scraper_errors_total{scraper="coingecko", error_type="rate_limit"} 3
scraper_last_success_timestamp{scraper="coingecko"} 1704067200

Alerting-правила для Prometheus / Grafana:

groups:
  - name: scraper_alerts
    rules:
      - alert: ScraperDown
        expr: time() - scraper_last_success_timestamp > 600 # 10 минут
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Scraper {{ $labels.scraper }} has not run successfully for 10+ minutes"
      - alert: ScraperLowRecords
        expr: scraper_records_fetched_total < 100
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Scraper {{ $labels.scraper }} fetching unusually few records"

Как мы настраиваем мониторинг: процесс работы

  1. Аудит текущих парсеров: выявляем точки интеграции метрик, определяем ожидаемые интервалы и пороги.
  2. Интеграция heartbeat-метрик: добавляем в код парсера вызовы recordRun с нужными параметрами.
  3. Развёртывание стека мониторинга: настраиваем Prometheus exporter, конфигурируем сбор метрик.
  4. Создание дашборда в Grafana: визуализация ключевых метрик, настройка оповещений.
  5. Настройка алертов: интеграция с Telegram, PagerDuty, определение severity.
  6. Документация и обучение: передаём шаблоны и обучаем команду реагировать на алерты.

Дополнительные метрики для крипто-парсеров

Для проектов, работающих с DeFi-данными, кроме базовых метрик стоит добавить:

Метрика Описание Почему важна
oracle_price_spread Отклонение цены от Chainlink оракула Выявляет устаревшие данные
cross_chain_lag Задержка между L1 и L2 rollup Критично для bridge-парсеров
slippage_impact Потери от проскальзывания при сделках Отслеживает качество данных

Что входит в настройку мониторинга под ключ

Мы предоставляем:

  • Интеграция heartbeat-метрик в код парсеров (TypeScript/Python/Rust)
  • Watchdog-процесс с SQL-запросами staleness
  • Prometheus exporter + custom метрики
  • Grafana дашборд (Success rate, Records per run, Duration heatmap)
  • Telegram-бота для алертов (критические — с PagerDuty)
  • Письменную документацию и доступ к репозиторию с шаблонами
  • Обучение команды работе с дашбордом и реагированию на алерты
  • Гарантию SLA 99.9% uptime системы мониторинга

Свяжитесь с нами для консультации — подберём оптимальную конфигурацию под ваш парсер. Базовый мониторинг ставим за 1 день, полный — за 2–3 дня, в зависимости от числа парсеров и кастомных порогов. Средняя экономия от предотвращённого даунтайма окупает настройку мониторинга за 2 дня. Закажите настройку мониторинга с гарантией SLA 99.9% — получите детальный расчёт для вашего проекта, напишите нам.

Направления блокчейн-разработки

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1543
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1395
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1374
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1142