ops: monitor database and object storage growth

This commit is contained in:
ik
2026-09-07 18:46:34 +07:00
parent 0f9c255596
commit 6477681e41
6 changed files with 29 additions and 8 deletions
+2
View File
@@ -42,4 +42,6 @@ BACKUP_ROOT=/srv/rf4-backups
MONITOR_DISK_MAX_PERCENT=85 MONITOR_DISK_MAX_PERCENT=85
MONITOR_TLS_MIN_DAYS=14 MONITOR_TLS_MIN_DAYS=14
MONITOR_BACKUP_MAX_HOURS=26 MONITOR_BACKUP_MAX_HOURS=26
MONITOR_DB_MAX_MB=2048
MONITOR_MINIO_MAX_MB=10240
LOG_LEVEL=INFO LOG_LEVEL=INFO
+1 -1
View File
@@ -26,7 +26,7 @@ Production-контур для домена `rf4spotter.ru`, TLS, секреты
Политика минимизации данных и ежедневная dry-run-first очистка описаны в [`docs/data-retention.md`](docs/data-retention.md). Политика минимизации данных и ежедневная dry-run-first очистка описаны в [`docs/data-retention.md`](docs/data-retention.md).
Host-side мониторинг контейнеров, readiness, диска, резервных копий и TLS описан в [`docs/production-monitoring.md`](docs/production-monitoring.md). Host-side мониторинг контейнеров, readiness, диска, объёма PostgreSQL/MinIO, резервных копий и TLS описан в [`docs/production-monitoring.md`](docs/production-monitoring.md).
Ежедневный systemd timer создаёт проверяемую копию до retention-очистки, а production Compose ограничивает рост JSON-логов контейнеров. Ежедневный systemd timer создаёт проверяемую копию до retention-очистки, а production Compose ограничивает рост JSON-логов контейнеров.
Фактическое состояние DNS/TLS домена и серверный чек-лист ведутся в [`docs/deployment-status.md`](docs/deployment-status.md). Фактическое состояние DNS/TLS домена и серверный чек-лист ведутся в [`docs/deployment-status.md`](docs/deployment-status.md).
+1 -1
View File
@@ -145,7 +145,7 @@ systemctl list-timers rf4spotter-maintenance.timer
./deploy/monitor.sh ./deploy/monitor.sh
``` ```
Проверка контролирует контейнеры, `/ready`, диск, свежесть backup и срок TLS. Установка systemd timer, пороги и порядок реакции описаны в [`docs/production-monitoring.md`](../docs/production-monitoring.md). До подключения реального канала уведомлений одного журнала systemd недостаточно. Проверка контролирует контейнеры, `/ready`, диск, объём PostgreSQL/MinIO, свежесть backup и срок TLS. Установка systemd timer, пороги и порядок реакции описаны в [`docs/production-monitoring.md`](../docs/production-monitoring.md). До подключения реального канала уведомлений одного журнала systemd недостаточно.
## 9. Что ещё блокирует публичное открытие альфы ## 9. Что ещё блокирует публичное открытие альфы
+18 -2
View File
@@ -20,10 +20,14 @@ backup_root=${BACKUP_ROOT:-$(read_env BACKUP_ROOT)}
disk_max=${MONITOR_DISK_MAX_PERCENT:-$(read_env MONITOR_DISK_MAX_PERCENT)} disk_max=${MONITOR_DISK_MAX_PERCENT:-$(read_env MONITOR_DISK_MAX_PERCENT)}
tls_days=${MONITOR_TLS_MIN_DAYS:-$(read_env MONITOR_TLS_MIN_DAYS)} tls_days=${MONITOR_TLS_MIN_DAYS:-$(read_env MONITOR_TLS_MIN_DAYS)}
backup_hours=${MONITOR_BACKUP_MAX_HOURS:-$(read_env MONITOR_BACKUP_MAX_HOURS)} backup_hours=${MONITOR_BACKUP_MAX_HOURS:-$(read_env MONITOR_BACKUP_MAX_HOURS)}
db_max_mb=${MONITOR_DB_MAX_MB:-$(read_env MONITOR_DB_MAX_MB)}
minio_max_mb=${MONITOR_MINIO_MAX_MB:-$(read_env MONITOR_MINIO_MAX_MB)}
disk_max=${disk_max:-85} disk_max=${disk_max:-85}
tls_days=${tls_days:-14} tls_days=${tls_days:-14}
backup_hours=${backup_hours:-26} backup_hours=${backup_hours:-26}
for value in "$disk_max" "$tls_days" "$backup_hours"; do db_max_mb=${db_max_mb:-2048}
minio_max_mb=${minio_max_mb:-10240}
for value in "$disk_max" "$tls_days" "$backup_hours" "$db_max_mb" "$minio_max_mb"; do
case "$value" in ''|*[!0-9]*) printf 'CRITICAL rf4spotter failures="monitor-threshold-invalid"\n'; exit 2 ;; esac case "$value" in ''|*[!0-9]*) printf 'CRITICAL rf4spotter failures="monitor-threshold-invalid"\n'; exit 2 ;; esac
done done
base_url=${MONITOR_BASE_URL:-https://$site_domain} base_url=${MONITOR_BASE_URL:-https://$site_domain}
@@ -48,6 +52,18 @@ case "$disk_used" in
*) [ "$disk_used" -lt "$disk_max" ] || fail "disk:${disk_used}%" ;; *) [ "$disk_used" -lt "$disk_max" ] || fail "disk:${disk_used}%" ;;
esac esac
db_bytes=$($compose exec -T db sh -c 'psql -At -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "select pg_database_size(current_database())"' 2>/dev/null) || db_bytes=""
case "$db_bytes" in
''|*[!0-9]*) db_mb="unknown"; fail "postgresql-size:unknown" ;;
*) db_mb=$(((db_bytes + 1048575) / 1048576)); [ "$db_mb" -lt "$db_max_mb" ] || fail "postgresql-size:${db_mb}MB" ;;
esac
minio_kb=$($compose exec -T minio du -sk /data 2>/dev/null | awk 'NR==1 {print $1}')
case "$minio_kb" in
''|*[!0-9]*) minio_mb="unknown"; fail "minio-size:unknown" ;;
*) minio_mb=$(((minio_kb + 1023) / 1024)); [ "$minio_mb" -lt "$minio_max_mb" ] || fail "minio-size:${minio_mb}MB" ;;
esac
if [ -z "$backup_root" ] || [ ! -d "$backup_root" ]; then if [ -z "$backup_root" ] || [ ! -d "$backup_root" ]; then
fail "backup:directory" fail "backup:directory"
else else
@@ -77,4 +93,4 @@ if [ -n "$failures" ]; then
exit 1 exit 1
fi fi
printf 'OK rf4spotter timestamp=%s disk_used=%s%% backup_max_age=%sh tls_min=%sd\n' "$timestamp" "$disk_used" "$backup_hours" "$tls_days" printf 'OK rf4spotter timestamp=%s disk_used=%s%% postgresql=%sMB minio=%sMB backup_max_age=%sh tls_min=%sd\n' "$timestamp" "$disk_used" "$db_mb" "$minio_mb" "$backup_hours" "$tls_days"
+1 -1
View File
@@ -144,7 +144,7 @@
- [x] Добавить серверное «Показать ещё» для публичной ленты полевых сигналов с сохранением фильтров и пределом 48 записей (7 сентября 2026). - [x] Добавить серверное «Показать ещё» для публичной ленты полевых сигналов с сохранением фильтров и пределом 48 записей (7 сентября 2026).
- [x] Объединять одинаковые полевые сигналы в сюжеты без потери уникальных ссылок provenance и показывать число совпадений (7 сентября 2026). - [x] Объединять одинаковые полевые сигналы в сюжеты без потери уникальных ссылок provenance и показывать число совпадений (7 сентября 2026).
- [ ] Добавить безопасный административный экспорт диагностики без персональных данных. - [ ] Добавить безопасный административный экспорт диагностики без персональных данных.
- [ ] Контролировать рост PostgreSQL и MinIO с порогами предупреждений. - [x] Контролировать рост PostgreSQL и MinIO host-monitor'ом с настраиваемыми порогами и runbook реакции (7 сентября 2026).
- [ ] Добавить фоновую проверку битых исходных ссылок с соблюдением лимитов источников. - [ ] Добавить фоновую проверку битых исходных ссылок с соблюдением лимитов источников.
- [x] Показывать версию и commit SHA в readiness и защищённой административной диагностике (7 сентября 2026). - [x] Показывать версию и commit SHA в readiness и защищённой административной диагностике (7 сентября 2026).
- [x] Добавить публичную `/status` без внутренних адресов, секретов и текстов ошибок (7 сентября 2026). - [x] Добавить публичную `/status` без внутренних адресов, секретов и текстов ошибок (7 сентября 2026).
+6 -3
View File
@@ -7,10 +7,11 @@
- контейнеры `proxy`, `db`, `minio`, `api`, `web` находятся в running; - контейнеры `proxy`, `db`, `minio`, `api`, `web` находятся в running;
- публичный `https://rf4spotter.ru/ready` сообщает `ready`; - публичный `https://rf4spotter.ru/ready` сообщает `ready`;
- файловая система проекта заполнена менее чем на 85%; - файловая система проекта заполнена менее чем на 85%;
- база PostgreSQL занимает менее 2 ГБ, а данные MinIO — менее 10 ГБ;
- последняя полная резервная копия не старше 26 часов и проходит проверку `SHA256SUMS`; - последняя полная резервная копия не старше 26 часов и проходит проверку `SHA256SUMS`;
- TLS-сертификат домена действует ещё минимум 14 дней. - TLS-сертификат домена действует ещё минимум 14 дней.
Пороги задаются в `.env.production`: `BACKUP_ROOT`, `MONITOR_DISK_MAX_PERCENT`, `MONITOR_BACKUP_MAX_HOURS`, `MONITOR_TLS_MIN_DAYS`. Проверка TLS использует SNI и поэтому обнаруживает как истечение, так и выдачу сертификата для неверного домена. Пороги задаются в `.env.production`: `BACKUP_ROOT`, `MONITOR_DISK_MAX_PERCENT`, `MONITOR_DB_MAX_MB`, `MONITOR_MINIO_MAX_MB`, `MONITOR_BACKUP_MAX_HOURS`, `MONITOR_TLS_MIN_DAYS`. Значения объёма задаются в МБ и для открытой альфы по умолчанию равны 2048/10240. Проверка TLS использует SNI и поэтому обнаруживает как истечение, так и выдачу сертификата для неверного домена.
## Ручная проверка ## Ручная проверка
@@ -43,5 +44,7 @@ Monitor timer записывает результат в journal. Maintenance ti
1. `service:*` — посмотреть `docker compose ... ps` и логи конкретного контейнера; не выполнять `down -v`. 1. `service:*` — посмотреть `docker compose ... ps` и логи конкретного контейнера; не выполнять `down -v`.
2. `readiness` — проверить `/ready`, PostgreSQL и MinIO; на время сбоя остановить приём пользовательских заявок. 2. `readiness` — проверить `/ready`, PostgreSQL и MinIO; на время сбоя остановить приём пользовательских заявок.
3. `disk:*` — сначала перенести старые backup во внешнее хранилище; не удалять Docker volumes вслепую. 3. `disk:*` — сначала перенести старые backup во внешнее хранилище; не удалять Docker volumes вслепую.
4. `backup:*` — запустить `deploy/backup.sh`, проверить `SHA256SUMS` и устранить причину пропуска расписания. 4. `postgresql-size:*` — проверить рост таблиц и выполнение retention; перед очисткой сделать backup и не выполнять ручное удаление строк без плана.
5. `tls:*`проверить DNS, доступность портов 80/443 и логи Caddy; не отключать проверку сертификата. 5. `minio-size:*`сверить объекты с заявками и политикой retention; не удалять volume или бакет целиком.
6. `backup:*` — запустить `deploy/backup.sh`, проверить `SHA256SUMS` и устранить причину пропуска расписания.
7. `tls:*` — проверить DNS, доступность портов 80/443 и логи Caddy; не отключать проверку сертификата.