Перейти до вмісту
На сайт

Спостережуваність

Railhook експортує метрики Prometheus, містить готові правила сповіщень і дашборди Grafana та пише структуровані логи.

Prometheus збирає /actuator/prometheus з порту керування, окремого від порту застосунку:

Сервіс Порт застосунку Порт керування
API 8080 8082
Worker немає 8081

У Kubernetes усе це налаштовує Helm-чарт: його ServiceMonitor збирає метрики з порту з назвою management, а PrometheusRule містить правила сповіщень. Див. Kubernetes.

Запуск стеку моніторингу через Docker Compose

Section titled “Запуск стеку моніторингу через Docker Compose”

Каталог monitoring/ у репозиторії містить Grafana, Prometheus, Alertmanager, Loki і Promtail, node-exporter, cAdvisor та blackbox-exporter, уже налаштовані для Railhook.

  1. Додайте пароль Grafana в .env. Типового пароля немає, і без нього Grafana не запуститься:

    Terminal window
    echo "GRAFANA_ADMIN_PASSWORD=$(openssl rand -base64 24)" >> .env
  2. Вкажіть, куди надсилати сповіщення: ALERTMANAGER_EMAIL_TO (листи йдуть через ваш SMTP-релей SMTP_*), ALERTMANAGER_SLACK_WEBHOOK_URL, ALERTMANAGER_WEBHOOK_URL або ALERTMANAGER_TELEGRAM_BOT_TOKEN і ALERTMANAGER_TELEGRAM_CHAT_ID. Якщо жодну змінну не задано, сповіщення видно лише в Grafana.

  3. Запустіть стек: make monitoring-up у клоні репозиторію або, на сервері, де Railhook встановлено через install.sh, команду docker compose -p railhook-monitoring зі сторінки Моніторинг.

Компонент Адреса Примітки
Grafana 127.0.0.1:3001 (GRAFANA_PORT) Overview, Alerts, Errors, Logs, Host, Containers, Uptime, Worker & Circuit Breaker, JVM & Micrometer
Prometheus Лише всередині стеку Зберігає дані протягом PROMETHEUS_RETENTION, типово 15d
Alertmanager Лише всередині стеку Сповіщення CRITICAL надходять швидше за попередження; критичне сповіщення, що спрацювало, приглушує відповідне попередження
Loki Лише всередині стеку Зберігає логи протягом LOKI_RETENTION_PERIOD, типово 168h (7 днів)

На сторінці Моніторинг описано, як відкрити Grafana на окремому домені, а також сповіщення про стан хоста, контейнерів, доступність і логи.

Показники, які справді важливі

Section titled “Показники, які справді важливі”
Метрика Як читати
events_ingested_total Прийняті події з міткою direction (outgoing з /api/v1/events, incoming з /ingress)
deliveries_total Доставки, створені розгалуженням. Якщо поділити на кількість подій, вийде середня кількість підписок на подію.
webhook_delivery_attempts_total Спроби. Якщо спроб набагато більше, ніж доставок, на повторні спроби припадає багато роботи.
webhook_delivery_latency_ms Скільки часу ендпоінт відповідав. Зростання p95 означає проблему на боці ендпоінта.
incoming_events_received_total, incoming_forward_attempts_total Та сама пара метрик для вхідних вебхуків
Метрика Як читати
delivery_oldest_pending_age_seconds Найкращий окремий показник стану: вік найстарішої незавершеної доставки. Тут видно і ендпоінт, що не відповідає, і завислий воркер. forward_oldest_pending_age_seconds є такою самою метрикою для вхідного напрямку.
delivery_queue_depth, incoming_forward_queue_depth Скільки роботи чекає. Стабільне значення нормальне, постійне зростання ні.
webhook_dlq_depth, incoming_forward_dlq_depth Недоставлені повідомлення, що чекають на рішення людини
delivery_escalated_to_dlq_total Доставки, що потрапили до недоставлених повідомлень через жорсткий ліміт у 96 годин, а не тому, що вичерпали повторні спроби. Ненульове значення означає, що щось працювало погано кілька днів.

Чи не заважають механізми захисту?

Section titled “Чи не заважають механізми захисту?”

Коли ліміт або circuit breaker притримує доставку, нічого не надсилається і жодна повторна спроба не витрачається. Високі значення тут означають, що платформа захищає ендпоінт, а не що сталася помилка.

Метрика Як читати
circuit_breaker_rejected_total Спроби, які притримав circuit breaker
circuit_breaker_state_transitions_total, circuit_breaker_slow_trips_total Як часто він спрацьовував і через що: помилки чи повільні відповіді
circuit_breaker_degraded_total Redis був недоступний, і circuit breaker пропускав виклики без захисту. Ненульове значення означає, що один із запобіжних механізмів не працює.
webhook_concurrency_rejected_total, webhook_rate_limit_exceeded_total, webhook_project_rate_limit_exceeded_total Який саме ліміт притримує доставки

Чи справляються повторні спроби й порядок доставки?

Section titled “Чи справляються повторні спроби й порядок доставки?”
Метрика Як читати
webhook_ordering_buffered_total Доставки, що чекають, поки завершаться попередні доставки на той самий ендпоінт
webhook_ordering_gap_timeout_total Попередня доставка так і не завершилася, тож наступну пропустили, щоб ендпоінт не простоював. Порядок свідомо порушено. Зрідка це нормально, часто ні.
transform_failed_total Трансформація завершилася помилкою
events_duplicate_total, events_fanout_limited_total Повтори, відсіяні за ключем ідемпотентності; події, відхилені через надто широке розгалуження

Якщо налаштовувати лише три сповіщення

Section titled “Якщо налаштовувати лише три сповіщення”
  1. delivery_oldest_pending_age_seconds понад кілька годин. Помічає майже все.
  2. circuit_breaker_degraded_total зростає. Помічає механізми захисту, які перестали захищати.
  3. forward_oldest_pending_age_seconds понад кілька годин. Помічає вхідні пересилання, які перестали рухатися. Метрика доставок їх не бачить.

Ті самі правила є в monitoring/prometheus/alerts.yml для Compose і в PrometheusRule Helm-чарта для Kubernetes. Тест у збірці стежить, щоб вони були однаковими.

Що означає Сповіщення
Черга зростає DeliveryPendingBacklogGrowing, DeliveryPendingBacklogHigh, DeliveryPendingBacklogCritical, IncomingForwardPendingBacklogHigh, OldestPendingDeliveryStale, OldestPendingDeliveryCritical, OldestPendingForwardStale
Доставки полишають DlqDepthGrowing, DlqRateHigh, IncomingForwardFailureRateHigh, DlqActionableBacklog, IncomingForwardDlqActionableBacklog
Механізм захисту спрацьовує або вийшов з ладу CircuitBreakerTripsHigh, CircuitBreakerRejectionsHigh, CircuitBreakerDegraded
Платформа не справляється ApiErrorRateHigh
Процес не працює ApiDown, WorkerDown

DlqActionableBacklog і IncomingForwardDlqActionableBacklog вимагають втручання людини: вони зникають, коли хтось повторює або очищає недоставлені повідомлення. CircuitBreakerDegraded відрізняється від інших сповіщень про circuit breaker: воно означає, що circuit breaker не працює.

У продакшні API і воркер пишуть логи однорядковим JSON з ідентифікатором кореляції, а для автентифікованих запитів і з ідентифікатором організації. У рядках логу доставок воркер вказує ідентифікатор доставки, за ним можна перейти від панелі Grafana до доставки в панелі керування Railhook. Стек моніторингу для Compose передає в Loki лише логи api і worker, а єдина мітка там — level. Фільтруйте за іншими ідентифікаторами через | json у Grafana; дашборд Logs має змінні для ідентифікатора кореляції та ідентифікатора організації.

Його немає. Railhook не експортує дані в OpenTelemetry, тож повільну доставку не вдасться простежити як один трейс від приймання до спроби.