Добавлены новые возможности для управления файловыми логами в Docker-сервисах: - Обновлены конфигурации для поддержки логов, включая переменные окружения и монтирование директорий. - Документация обновлена для описания новых эндпоинтов и параметров, связанных с логами. - Упрощен доступ к логам через API и интерфейс пользователя. Co-authored-by: Cursor <[email protected]>
14 KiB
Memory Bank: Tasks
Current Task
settings-ui-and-runtime-logs
| Поле | Значение |
|---|---|
| Task ID | settings-ui-and-runtime-logs |
| Complexity | Level 4 |
| Status | BUILD Phase 5 complete → Phase 6 |
| Дата VAN | 2026-06-12 |
| Дата PLAN | 2026-06-12 |
Resolved Decisions (от заказчика)
| # | Вопрос | Решение |
|---|---|---|
| 1 | /settings vs tenant |
/settings — только frontend (токен, тема, localStorage). Tenant-настройки — отдельный модуль (новый route + nav). |
| 2 | Очистка больших логов | Синхронно (HTTP 200/4xx/5xx), без jobs.Registry / 202. |
| 3 | Где FS API | Только evobgp-all с bind-mount volume на runtime-logs. На evobgp-api — 503 или отсутствие маршрута. |
| 4 | Audit очистки | Да — персистентный audit в PostgreSQL (и sqlite для паритета). |
Requirements Summary
A. Web UI — два независимых модуля
| Модуль | Route (план) | Данные | Роль |
|---|---|---|---|
| Frontend settings | /settings (существует) |
localStorage, theme | любой пользователь UI |
| Tenant settings | /tenant-settings (новый) |
GET/PATCH /v1/settings → global_settings |
viewer read / operator write |
Tenant module объединяет сейчас разрозненное:
OperationsSystemSettingsTab→ revision + custom KV (убрать из Operations)BirdSettingsForm→ BIRD keys (убрать с/networkили оставить read-only summary + ссылка)
/settings не трогать семантически — только polish (заголовки, пояснения что это настройки браузера).
B. Runtime logs — FS
- Корень:
EVOBGP_RUNTIME_LOGS_DIR(prod default:/opt/evobgp/runtime-logs) - Источник файлов: sidecar
stack-runtime-logs(без изменений) - API: list / stat / tail / cleanup (sync)
- Audit: каждая операция cleanup → запись в БД
Technology Validation
| Технология | Версия / статус | Примечание |
|---|---|---|
Go stdlib os, path/filepath |
1.24 | FS read/truncate; без новых deps |
| PostgreSQL + sqlite миграции | 000026 | audit table |
| OpenAPI 3.1 | docs/openapi.yaml |
новые paths под tag RuntimeLogs |
| SvelteKit 5 + shadcn | web/ | новые routes/components |
| Compose bind mount | deploy/compose/* |
volume на evobgp-all |
PoC не требуется — паттерны audit и settings уже в репозитории.
Architecture Overview
flowchart TB
subgraph web [Web UI]
FS["/settings<br>frontend only"]
TS["/tenant-settings<br>BIRD + revision + KV"]
MON["/monitoring?tab=runtime-logs"]
end
subgraph api [evobgp-all only]
H[httpapi handlers]
RL[internal/runtimelogs]
ST[store.Backend]
end
subgraph data [Data]
PG[(global_settings)]
AUD[(runtime_log_cleanup_audit)]
VOL["/opt/evobgp/runtime-logs/*.log"]
end
FS --> localStorage
TS --> H
MON --> H
H --> ST
H --> RL
ST --> PG
ST --> AUD
RL --> VOL
Phased Implementation Plan
Phase 0 — Creative (обязательно перед BUILD)
Документы в memory-bank/creative/:
| ID | Тип | Тема | Вопросы |
|---|---|---|---|
| CP-1 | uiux | Tenant settings module | Структура вкладок: BIRD / Ревизии / Дополнительно; nav label |
| CP-2 | uiux | Runtime logs UI | Вкладка в Monitoring vs отдельный route |
| CP-3 | algorithm | Cleanup semantics | truncate (обнулить файл) vs delete; max tail bytes/lines |
| CP-4 | architecture | Path safety | Allowlist имён файлов *.log, запрет .., symlink policy |
Уже решено (не обсуждать в creative): sync cleanup, evobgp-all only, audit yes, settings split.
Phase 1 — Contract & persistence (OpenAPI + migrations + store)
Цель: контракт и audit до FS-логики.
| # | Действие | Файлы |
|---|---|---|
| 1.1 | OpenAPI: RuntimeLogs tag |
docs/openapi.yaml |
| 1.2 | Схемы: RuntimeLogFile, RuntimeLogTail, RuntimeLogCleanupAudit |
docs/openapi.yaml |
| 1.3 | Paths (см. ниже) | docs/openapi.yaml |
| 1.4 | Миграция 000026_runtime_log_cleanup_audit |
migrations/postgres/, migrations/sqlite/ |
| 1.5 | Типы + store.Backend методы |
internal/store/runtime_logs.go, backend.go |
| 1.6 | Postgres + Memory реализации | internal/repository/postgres_runtime_logs.go, internal/store/memory_runtime_logs.go |
OpenAPI paths (черновик):
GET /v1/runtime-logs/files # list + size/mtime
GET /v1/runtime-logs/files/{filename} # tail (?lines= | ?bytes=, ?grep=)
DELETE /v1/runtime-logs/files/{filename} # cleanup (?mode=truncate|delete), operator+, sync 200
GET /v1/runtime-logs/cleanup-audit # cursor/limit, viewer+
Audit table runtime_log_cleanup_audit:
| Column | Type | Note |
|---|---|---|
| id | TEXT PK | UUID |
| tenant_id | TEXT | из auth |
| actor_prefix | TEXT | API key prefix |
| filename | TEXT | basename only |
| action | TEXT | truncate | delete |
| size_before | BIGINT | bytes |
| size_after | BIGINT | nullable |
| detail_json | JSONB | optional (grep stats, error) |
| created_at | TIMESTAMPTZ |
Checklist Phase 1:
npx @redocly/cli lint docs/openapi.yaml- миграции
000026postgres + sqlite (пары up/down) - store interface + memory tests (
TestMemoryRuntimeLogCleanupAudit)
Phase 2 — FS layer & config (evobgp-all only)
Цель: безопасное чтение/очистка файлов.
| # | Действие | Файлы |
|---|---|---|
| 2.1 | EVOBGP_RUNTIME_LOGS_DIR в config |
internal/config/config.go, docs/access.md |
| 2.2 | Guard: FS enabled iff dir non-empty and EVOBGP_SERVICE=evobgp-all |
internal/runtimelogs/guard.go |
| 2.3 | ListDir, Stat, Tail, Cleanup | internal/runtimelogs/fs.go |
| 2.4 | Path hardening: basename allowlist [a-z0-9_.-]+\.log |
internal/runtimelogs/safe.go |
| 2.5 | Unit tests (temp dir) | internal/runtimelogs/*_test.go |
Поведение при отключённом FS:
GET→503problem+jsonruntime_logs_unavailableDELETE→503
Cleanup flow (sync):
- Stat file →
size_before - Truncate or Remove
AppendRuntimeLogCleanupAudit(...)- Return
200+ audit id + sizes
Checklist Phase 2:
go test ./internal/runtimelogs/... -count=1- path traversal + symlink tests (
safe_test.go)
Phase 3 — HTTP handlers
| # | Действие | Файлы |
|---|---|---|
| 3.1 | Регистрация маршрутов | internal/httpapi/routes.go или routes_runtime_logs.go |
| 3.2 | Handlers | internal/httpapi/handlers_runtime_logs.go |
| 3.3 | actorPrefix(a) как в maintenance |
reuse from routes_maintenance.go |
| 3.4 | Handler tests | internal/httpapi/handlers_runtime_logs_test.go |
Роли: list/tail/audit — viewer+; cleanup — operator+.
Checklist Phase 3:
go test ./internal/httpapi/... -run RuntimeLogs(Windows: без-race, CGO disabled)scripts/lint-go.ps1exit 0- lint-httpapi gates (ERR-01, ARCH-01) — проверено grep
Phase 4 — Deploy (compose)
| # | Действие | Файлы |
|---|---|---|
| 4.1 | Bind mount runtime-logs → evobgp-all | deploy/compose/stack.microvps-full.yaml, docker-compose.microvps-full.yaml |
| 4.2 | Env EVOBGP_RUNTIME_LOGS_DIR=/opt/evobgp/runtime-logs |
compose env |
| 4.3 | EVOBGP_SERVICE=evobgp-all (если ещё не задан) |
compose |
| 4.4 | Комментарий в quickstart / manual | docs/quickstart.md или docs/manual.md |
Пример mount:
volumes:
- ${EVOBGP_RUNTIME_LOGS_HOST_DIR:-./runtime-logs}:/opt/evobgp/runtime-logs:rw
environment:
EVOBGP_RUNTIME_LOGS_DIR: /opt/evobgp/runtime-logs
Checklist Phase 4:
- dev:
./runtime-logsрядом с compose (EVOBGP_RUNTIME_LOGS_HOST_DIRdefault) - prod:
/opt/evobgp/runtime-logsна хосте (черезEVOBGP_RUNTIME_LOGS_HOST_DIRв.env) stack.microvps-full.yaml+docker-compose.microvps-full.yaml— mount + env наevobgp-all.env.stack.microvps-full.example,docs/quickstart.md,docs/manual.md
Phase 5 — Web UI: Tenant settings module
Цель: отдельный модуль tenant-настроек; /settings остаётся frontend-only.
| # | Действие | Файлы |
|---|---|---|
| 5.1 | Новый route | web/src/routes/tenant-settings/+page.svelte |
| 5.2 | Компонент-обёртка с Tabs | web/src/lib/components/tenant-settings/TenantSettingsPage.svelte |
| 5.3 | Перенос логики из Operations | refactor OperationsSystemSettingsTab → TenantRevisionSettingsCard.svelte |
| 5.4 | Перенос BIRD | refactor BirdSettingsForm → TenantBirdSettingsCard.svelte |
| 5.5 | Custom KV card | TenantAdditionalSettingsCard.svelte |
| 5.6 | Nav: добавить пункт (main или bottom) | web/src/lib/ui/app/layout/nav.ts |
| 5.7 | Убрать tab system из Operations |
web/src/routes/operations/+page.svelte |
| 5.8 | Network: заменить форму на Card-summary + link | web/src/routes/network/+page.svelte |
| 5.9 | Обновить ссылки в docs strings / empty states | grep tab=system, BirdSettingsForm |
Структура tenant module (предложение для creative CP-1):
/tenant-settings
├─ BIRD (bird_*)
├─ Ревизии (revision_retention_minutes)
└─ Дополнительно (custom KV, operator)
Checklist Phase 5:
npm run check && npm run lint/settingsбез tenant-форм/tenant-settingsс Tabs BIRD / Ревизии / Дополнительно- nav «Параметры»; Operations без tab system; Network summary + link
Phase 6 — Web UI: Runtime logs
| # | Действие | Файлы |
|---|---|---|
| 6.1 | API client | web/src/lib/runtime-logs/runtime-logs-api.ts |
| 6.2 | Tab в Monitoring | web/src/lib/components/monitoring/RuntimeLogsTab.svelte |
| 6.3 | Подключить tab | web/src/routes/monitoring/+page.svelte |
| 6.4 | Таблица файлов (size, mtime) | AppDataTable |
| 6.5 | Preview dialog | ScrollPreBlock + tail API |
| 6.6 | Cleanup | ConfirmDialog + DELETE sync |
| 6.7 | Sub-tab или section: Cleanup audit | таблица GET /v1/runtime-logs/cleanup-audit |
| 6.8 | 503 empty state | «Доступно только на evobgp-all с volume» |
Checklist Phase 6:
npm run check && npm run lint
Phase 7 — Integration, docs, QA
| # | Действие |
|---|---|
| 7.1 | docs/api.md — новые endpoints |
| 7.2 | docs/manual.md — tenant-settings + runtime logs |
| 7.3 | go test ./... -race -count=1 |
| 7.4 | E2E manual: list → tail → truncate → audit row |
Dependency Graph
graph TD
P0[Phase 0 Creative] --> P1[Phase 1 OpenAPI+store]
P1 --> P2[Phase 2 FS layer]
P2 --> P3[Phase 3 HTTP]
P3 --> P4[Phase 4 Deploy]
P0 --> P5[Phase 5 Tenant UI]
P3 --> P6[Phase 6 Runtime logs UI]
P4 --> P6
P5 --> P7[Phase 7 QA]
P6 --> P7
Параллелизация: Phase 5 (tenant UI) можно начинать после Phase 0, не дожидаясь runtime logs backend.
Risks & Mitigations
| Risk | Impact | Mitigation |
|---|---|---|
| Path traversal | Critical | basename only, allowlist, filepath.Clean + root check |
| Sync cleanup блокирует HTTP worker | Medium | лимит размера файла для DELETE; timeout context; документировать |
| evobgp-api без volume | Low | 503 + UI empty state |
| Дублирование settings forms | Medium | Phase 5 удаляет старые вхождения |
| reference compose (не all) | Low | FS API disabled; документировать |
Creative Phases Required
- CP-1 uiux —
creative-tenant-settings-ui.md✅ Tabs/tenant-settings, nav «Параметры» - CP-2 uiux —
creative-runtime-logs-ui.md✅ Monitoring tabruntime-logs+ sub-tabs files/audit - CP-3 algorithm —
creative-runtime-logs-cleanup.md✅ truncate default, max 512MiB, tail 200/2000 lines, 256KiB - CP-4 architecture —
creative-runtime-logs-path-safety.md✅ regex + EvalSymlinks + root prefix check
Acceptance Criteria
/settings— только frontend (токен, тема)/tenant-settings— все tenant KV (BIRD + revision + custom)- Operations без tab
system; Network без полной BIRD-формы (summary + link) - Runtime logs: list, tail, sync cleanup на evobgp-all
- Audit cleanup в БД + просмотр в UI
EVOBGP_RUNTIME_LOGS_DIR, volume в compose- redocly lint, go test -race, web check+lint
Status Checklist
- VAN
- PLAN
- CREATIVE (4 docs)
- BUILD Phase 1 (OpenAPI + migration + store)
- BUILD Phase 2 (FS layer + config)
- BUILD Phase 3 HTTP handlers
- BUILD Phase 4 Deploy (compose)
- BUILD Phase 5 Tenant settings UI
- BUILD Phase 6–7
- REFLECT
- ARCHIVE
Key Files (reference)
Settings today:
web/src/routes/settings/+page.svelte— keep frontend-onlyweb/src/lib/components/operations/OperationsSystemSettingsTab.svelte— migrate outweb/src/lib/components/network/BirdSettingsForm.svelte— migrate outinternal/httpapi/routes_crud.go— settings handlers (unchanged contract)
Runtime logs today:
deploy/compose/stack.microvps-full.yaml—stack-runtime-logs,./runtime-logs
Patterns:
internal/httpapi/routes_maintenance.go— audit list, actor_prefixmigrations/postgres/000025_*— config audit table shape