| 2026-10-10 |

feat: метрики — дайджест бакета при разряжении (крайности и простои не теряются)
...
Прореживание оставляло одну реальную точку на бакет, поэтому всплеск CPU под
98% две минуты или падение, пришедшееся ровно на удалённую точку, исчезали с
графика навсегда. Теперь вместе с выжившей точкой пишется дайджест интервала
в metrics.agg_json: n/exp (пришло замеров против ожидаемых — n < exp значит
простой), min/max по cpu/ram/swap/load/сеть и по каждому маунту диска.
Пишется только там, где бакет реально схлопывается (n > 1), поэтому сырые
сутки остаются сырыми, а повторный прогон ничего не перезаписывает.
- metrics_retention: _Bucket копит крайности; границы бакета для DELETE
собираются через datetime (корректный перенос через час/сутки), удаление —
по индексу, без списка id в памяти.
- схема + ALTER: metrics.agg_json.
- API /servers/{id}/metrics и MCP server_history отдают точку с полем agg;
прореживание внутри тула сливает дайджесты выкинутых точек, а не
выбрасывает их вместе с крайностями.
Eugene Sukhodolskiy
committed
7 hours ago
|

perf: метрики — тяжёлые JSON в server_state, разряжение истории по возрасту
...
Строка метрик худеет с ~5 КБ JSON до ~0.1 КБ: net_json (сырые счётчики),
docker_json, processes_json и extra нужны только от ПОСЛЕДНЕГО пакета, в
истории они были мёртвым грузом (~89% объёма). Теперь они живут в одной
строке server_state на сервер:
- ingest читает предыдущий пакет из server_state (fallback на последнюю
строку метрик — плавный апгрейд на живом деплое), пишет состояние UPSERT;
- GET /servers/{id} берёт процессы/docker/extra из состояния через
LEFT JOIN — контракт API для фронта не менялся;
- в history остаются числа и disks_json (нужны графикам на всю глубину).
Разряжение (app/metrics_retention.py) по возрасту точки: 0–24 ч — всё,
24 ч–3 сут — 1/мин, 3–7 сут — 1/5 мин, 7–365 сут — 1/час, старше года —
удаление. В бакете остаётся реальная последняя точка (бакеты считаются
срезом строки ISO-8601, без парсинга дат). Петля — при старте и каждые
15 минут, затем PRAGMA incremental_vacuum.
Чтобы удалённое возвращалось файлу: auto_vacuum=INCREMENTAL, а на БД,
созданных до этого — разовый VACUUM при старте панели.
Eugene Sukhodolskiy
committed
7 hours ago
|
| 2026-10-05 |
feat: сервисы — favicon и title с главной страницы origin (ttl 24 ч)
Eugene Sukhodolskiy
committed
5 days ago
|
| 2026-10-04 |
feat: персональные MCP-ключи (канон handbook mcp.md)
...
- таблица mcp_tokens: sha256-хэш (unique) + хвост-хинт, снейпшот roles
владельца на момент выпуска; миграции users.system_role/users.blocked
- выдача только из cookie-сессии: GET/POST /me/mcp_tokens (plaintext
ровно один раз, ≥10 активных → 409), ревок вместо архива; админ-роуты
для всех ключей; rate-limit на выдачу (5 за 10 мин)
- гард /mcp — require_mcp: Bearer mcp_* | статический GHARD_ADMIN_TOKEN |
cookie; отозванный/заблокированный — тот же 401 (причина не раскрывается)
- вебхуки user.blocked/deleted/archived → users.blocked=1 + ревок ключей
владельца; разблокировка — при следующем успешном логине; SSO-логаут
ключи не трогает
Eugene Sukhodolskiy
committed
6 days ago
|
feat: парсер самосвидетельства health-ответов (handbook spec §5)
...
Панель читает расширенное тело health: identity (service/version/build/
environment/uptime|since), mode из белого списка {maintenance, readonly,
draining} — нейтральный бейдж в карточке, gauges — числа чипами.
Белый список известных полей: сырое тело не хранится и не логируется
(эндпоинт без авторизации), bool/вложенные значения в gauges отбрасываются,
неизвестный mode игнорируется (mode ≠ лайвность).
service_samples.report (JSON, NULL = нет самосвидетельства); колонка
добавляется к живым БД guarded ALTER в db.init_db (паттерн будущих
миграций). В API — report в списке сервисов и в истории проб.
Карточка «Сервисы»: v+environment+аптайм (fmtUptime), бейдж mode
(тексты i18n en/uk/ru), чипы gauges; пустые строки не рисуются.
Eugene Sukhodolskiy
committed
6 days ago
|
| 2026-09-10 |
feat: stage 1 — panel skeleton (FastAPI + SQLite) and ingest API
...
- FastAPI backend: config (pydantic-settings, GHARD_* env), aiosqlite + WAL
- SQLite schema: servers, metrics, events
- POST /api/v1/ingest: auth by X-Server-Key (sha256 hash), net rates in MB/s
computed on panel from raw counter deltas, server card upsert
- Servers API: create (key shown once), list with dashboard summary,
detail, PATCH name/note, delete, metrics history
- Dockerfile + docker-compose with persistent volume
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 10 Sep
|