Перейти к содержанию

Мониторинг и логи

Что наблюдать у работающей платформы DataHUB, какие healthcheck-эндпоинты доступны, как устроены логи и какие алерты стоит настроить в системе мониторинга. Конкретный стек мониторинга (Prometheus, Zabbix, Grafana, Loki, ELK) — на стороне инфраструктуры заказчика; здесь — что именно ему отдавать.

Healthcheck-эндпоинты

Сводно — все точки, по которым можно судить о состоянии платформы.

Эндпоинт Источник Что проверяет
https://lk.<your-domain>/healthz nginx nginx жив и отвечает
https://lk.<your-domain>/api/actuator/health backend (через nginx) backend жив, состояние БД, RabbitMQ
https://lk.<your-domain>/api/actuator/health/liveness backend (Spring Actuator) приложение запущено
https://lk.<your-domain>/api/actuator/health/readiness backend (Spring Actuator) приложение готово принимать трафик
Docker (healthy) status в docker ps контейнеры внутренний HEALTHCHECK каждого блока

nginx /healthz

Возвращает 200 OK\n. Не зависит от состояния backend — это «жив ли сам reverse proxy». Если nginx не работает (контейнер упал, неверный конфиг) — этот эндпоинт недоступен.

Базовая проба:

curl -fkS https://lk.<your-domain>/healthz

Spring Actuator /api/actuator/health

Возвращает JSON с агрегированным статусом backend и подсистем (БД, RabbitMQ):

{
  "status": "UP",
  "components": {
    "db": { "status": "UP", "details": { "database": "PostgreSQL", "validationQuery": "isValid()" } },
    "diskSpace": { "status": "UP", "details": { "total": ..., "free": ..., "threshold": ... } },
    "ping": { "status": "UP" }
  }
}

Health-индикатор rabbit отключён конфигурацией (management.health.rabbit.enabled: false) — слишком чувствителен к коротким обрывам и приводит к ложным DOWN при штатной работе. Состояние брокера наблюдается через сам RabbitMQ Management API.

Если хотя бы один компонент DOWN — общий status: "DOWN", HTTP 503. Если всё OK — status: "UP", HTTP 200.

Базовая проба:

curl -fkS https://lk.<your-domain>/api/actuator/health | jq .

Spring Actuator liveness/readiness

Отдельные эндпоинты для kubernetes-style проб (даже без k8s полезны для мониторинга):

  • /api/actuator/health/liveness — приложение запущено и не зависло. Если DOWN — backend нужно перезапустить.
  • /api/actuator/health/readiness — приложение готово принимать трафик (стартовая инициализация завершена, БД доступна). Если DOWN сразу после старта — норма, идёт инициализация. Если DOWN долго — проблема.

Docker HEALTHCHECK

У большинства блоков платформы внутри образа определён HEALTHCHECK, который Docker опрашивает с заданным интервалом и помечает контейнер (healthy) / (unhealthy) / (starting).

Блок Что проверяет Интервал Что значит unhealthy
postgres pg_isready 10s БД не отвечает на подключения
rabbitmq GET /api/healthchecks/node 30s Management API брокера недоступен
frontend GET http://localhost:3000/healthz 30s Next.js не отдаёт healthz
backend — (нет HEALTHCHECK) (используйте /api/actuator/health)
nginx (используйте /healthz)
flyway — (одноразовый контейнер) (после Exited (0) — успех)
dh_initializer — (одноразовый контейнер) (после Exited (0) — успех)

Сводка состояния:

sudo docker ps --format "table {{.Names}}\t{{.Status}}"

В колонке STATUS должно быть Up <время> (healthy) для всех «живых» блоков. Up <время> без (healthy) — у блоков без HEALTHCHECK (это нормально).


Что должен мониторить production

Минимальный набор алертов:

1. Доступность платформы

  • https://lk.<your-domain>/healthz не возвращает 200 более 1 минуты → CRITICAL.
  • https://lk.<your-domain>/api/actuator/health возвращает не 200 более 5 минут → CRITICAL.
  • https://exchange.<your-domain>/api/exchange/... возвращает 5xx более X% за окно → WARN.

2. Состояние контейнеров

  • Любой контейнер платформы (postgres, rabbitmq, backend, frontend, nginx, pg-admin) не в состоянии running → CRITICAL.
  • Любой контейнер с HEALTHCHECK в состоянии unhealthy более 5 минут → CRITICAL.
  • Контейнер перезапускался N раз за последний час → WARN (признак нестабильности).

Сбор статусов:

sudo docker inspect --format '{{.Name}} {{.State.Status}} {{.State.Health.Status}}' $(docker ps -aq)

3. Дисковое пространство

  • /etc/datahub/postgres/data/ — свободно менее 10 GB → WARN, менее 1 GB → CRITICAL. При исчерпании PostgreSQL перестаёт принимать write-операции.
  • /etc/datahub/rabbitmq/data/ — то же по принципу. При нехватке RabbitMQ блокирует приём сообщений (free disk space alarm).
  • /var/lib/docker/ — общее место под образы и логи контейнеров. Свободно менее 20% → WARN.

4. RabbitMQ

  • Длина любой очереди растёт без снижения более 30 минут → WARN (потребитель отстаёт или упал).
  • Алармы RabbitMQ (memory/disk) активны → CRITICAL. Проверяются через Management API: GET /api/aliveness-test/%2F.
  • Число коннекшенов резко выросло → WARN (возможна утечка).

Метрики достаются через RabbitMQ Management API (/api/overview, /api/queues).

5. PostgreSQL

  • Подключения близки к max_connections → WARN.
  • Долгие запросы (> 30 сек) → WARN.
  • Размер БД растёт неожиданно быстро → WARN.

Доступно через pg_stat_activity, pg_stat_database.

6. TLS-сертификаты

  • Срок действия сертификата < 30 дней → WARN, < 7 дней → CRITICAL.

Проверка:

echo | openssl s_client -servername lk.<your-domain> -connect lk.<your-domain>:443 2>/dev/null \
  | openssl x509 -noout -enddate

7. Backend-метрики (через Spring Actuator)

Spring Actuator выставляет метрики Micrometer на /actuator/metrics и в формате Prometheus — на /actuator/prometheus (если включён micrometer-registry-prometheus).

Полезные метрики для алертов:

  • hikaricp_connections_active / hikaricp_connections_max — насыщение пула БД
  • http_server_requests_seconds_count + tag status — счётчики ответов 4xx/5xx
  • jvm_memory_used_bytes — использование heap
  • process_cpu_usage — CPU контейнера
  • cache_size для именованных кэшей Caffeine

Логи: где, что, как читать

Логи контейнеров (Docker json-file)

Все блоки логируют через Docker json-file driver с ротацией 100 МБ × 10 файлов на сервис (~1 GB на блок). Логи доступны через docker logs:

sudo docker logs -f --tail 200 backend
sudo docker logs -f --tail 200 frontend
sudo docker logs --since 1h --until now nginx

Физическое расположение на хосте — /var/lib/docker/containers/<id>/<id>-json.log. При централизованном сборе логов агенты (Promtail, Filebeat, Vector) подхватывают эти файлы напрямую.

Логи nginx (отдельный том)

Nginx, в отличие от остальных, дополнительно пишет логи в bind-mount /etc/datahub/nginx/log/:

/etc/datahub/nginx/log/
├── access.log                       # общий access-лог
├── error.log                        # error-лог
├── access_api.log                   # обращения к /api/* на личном кабинете
├── access_auth.log                  # обращения к /api/auth/*
├── access_auth_session.log          # обращения к /api/auth/session*
├── access_docs.log                  # обращения к документации backend
├── access_exchange_log.log          # обращения к exchange API
├── access_log_80.log                # запросы на порт 80 до редиректа
└── access_log_15432.log             # обращения к pgAdmin и RabbitMQ Management

Формат datahub_format — единый для всех виртуальных серверов:

<ISO-время> status=<код> request="<метод> <URL>" http_referer="<...>" body_bytes_sent=<N> ip=<IP> ua="<...>" http_x_forwarded_for="<...>"

Раздельные логи по серверам помогают быстро локализовать проблему: «5xx на exchange API» → access_exchange_log.log, «brute-force на login» → access_auth.log.

Ротация nginx-логов

Nginx не делает ротацию сам. На production надо настроить logrotate:

sudo tee /etc/logrotate.d/datahub-nginx >/dev/null <<'EOF'
/etc/datahub/nginx/log/*.log {
    daily
    rotate 30
    compress
    missingok
    notifempty
    sharedscripts
    postrotate
        docker exec nginx nginx -s reopen
    endscript
}
EOF

nginx -s reopen переоткрывает дескрипторы логов после ротации, иначе nginx продолжит писать в уже переименованный файл.

Логи backend (прикладные)

Backend пишет логи через стандартный logback Spring Boot — в stdout/stderr контейнера. Дополнительно том ./log/:/var/log/nginx/:rw (путь исторический), но в дефолтной конфигурации Spring туда не пишет.

Уровни логирования по умолчанию — INFO. Уровни на профиле devDEBUG для com.datahub. Подробнее — в Сервер DataHUB / Логирование.

Логи PostgreSQL и RabbitMQ

Эти блоки пишут только в stdout/stderr своих контейнеров (доступно через docker logs postgres и docker logs rabbitmq). Отдельных томов для логов на хосте нет — это упрощает развертывание и снимает заботу о ротации.

При диагностике через docker logs можно фильтровать:

sudo docker logs postgres 2>&1 | grep -i error
sudo docker logs rabbitmq 2>&1 | grep -i 'error\|alarm'

Централизованный сбор логов

При наличии в инфраструктуре заказчика централизованной системы сбора логов (Loki, Elasticsearch, Splunk, Vector → S3) — настроить отправку из двух источников:

  1. Docker контейнеры через файлы /var/lib/docker/containers/<id>/<id>-json.log или через docker logging driver (fluentd, gelf, syslog).
  2. Nginx-логи через файлы /etc/datahub/nginx/log/*.log.

Готовых интеграций «из коробки» в платформе нет — конфигурация агентов на стороне заказчика.

При наличии Loki:

  • Лейблы — container_name, compose_project, compose_service (Docker logging driver их сам добавит).
  • Парсинг nginx — через готовый pipeline для combined-формата плюс кастомные поля из datahub_format.

Метрики уровня платформы (Prometheus)

Backend не выставляет endpoint /actuator/prometheus в дефолтной поставке (нет зависимости micrometer-registry-prometheus). При необходимости — собрать backend с этой зависимостью и включить:

management:
  endpoints:
    web:
      exposure:
        include: [health, info, metrics, prometheus]

Альтернатива — снимать стандартные метрики /actuator/metrics периодически своими средствами (exporter, скрипт), но это менее удобно.

Метрики RabbitMQ Management — доступны напрямую: GET https://lk.<your-domain>:15672/api/.... Существуют готовые Prometheus-exporters для RabbitMQ.

Метрики PostgreSQL — снимаются postgres_exporter, подключается отдельным контейнером в dh_network.


Тонкие моменты

  • Backend не выставляет HEALTHCHECK в docker-compose — это сделано осознанно, статус определяется через Spring Actuator. Если ваша система мониторинга ожидает (healthy) в docker ps для backend — придётся добавить custom HEALTHCHECK в локальную копию docker-compose.yml.
  • Frontend HEALTHCHECK строгий — при недоступности /healthz 5 минут (5 проб × 30s × 1 retry) контейнер уходит в unhealthy. Это может ложно срабатывать при тяжёлых server-side операциях.
  • Логи RabbitMQ содержат много WARN-сообщений в штатном режиме (соединения коннектятся-дисконнектятся, каналы открываются-закрываются). Не реагируйте на каждый WARN — алерты ставьте только на ERROR и алармы.

Что дальше