docs(memory-bank): add creative phase CP-3 runtime logs cleanup
Решение: truncate по умолчанию, delete опционально, лимиты tail и max 512 MiB на sync cleanup. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# Creative: Runtime Logs Cleanup & Tail (CP-3)
|
||||
|
||||
📌 **CREATIVE PHASE START: Cleanup Semantics & Tail Limits**
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
## 1️⃣ PROBLEM
|
||||
|
||||
**Description:** Sync cleanup больших `.log` файлов на HTTP worker; tail/preview без OOM. Нужны чёткие лимиты и режимы очистки, совместимые с sidecar `docker logs -f >> file` (файл пересоздаётся при рестарте sidecar).
|
||||
|
||||
**Requirements:**
|
||||
- Cleanup — **синхронный** HTTP (решение заказчика)
|
||||
- Audit: `size_before`, `size_after`, `action`
|
||||
- Sidecar продолжает писать в тот же путь после truncate
|
||||
- Защита от чтения гигабайтных файлов в tail
|
||||
|
||||
**Constraints:**
|
||||
- Без `jobs.Registry` для cleanup
|
||||
- Request timeout: разумный предел на handler (context с deadline 60s для cleanup)
|
||||
- Файлы: только allowlisted basenames (CP-4)
|
||||
|
||||
## 2️⃣ OPTIONS — Cleanup mode
|
||||
|
||||
| Option | Описание |
|
||||
|--------|----------|
|
||||
| **A** | **Truncate** по умолчанию (`os.Truncate(0)` или `O_TRUNC`) — файл остаётся, inode может сохраниться |
|
||||
| **B** | **Delete** по умолчанию — `os.Remove`, sidecar создаст при следующей записи |
|
||||
| **C** | Rotate: rename to `.old` + create new |
|
||||
| **D** | Truncate только < N MB, иначе reject |
|
||||
|
||||
## 3️⃣ ANALYSIS — Cleanup
|
||||
|
||||
| Criterion | A Truncate | B Delete | C Rotate | D Size gate |
|
||||
|-----------|------------|----------|----------|-------------|
|
||||
| Sidecar совместимость | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ |
|
||||
| Predictable filename | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
|
||||
| Sync latency | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
|
||||
| Audit clarity | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
|
||||
|
||||
**Key insight:** sidecar открывает файл через shell redirect `>>`; **truncate** обнуляет содержимое без смены имени в list — оператор видит тот же `evobgp-all.log`. Delete допустим как явная опция (файл исчезнет из list до следующей строки sidecar).
|
||||
|
||||
## 4️⃣ DECISION — Cleanup
|
||||
|
||||
**Default:** `mode=truncate` (query param, default when omitted).
|
||||
|
||||
**Optional:** `mode=delete` — только operator, UI second action «Удалить файл полностью».
|
||||
|
||||
**Max file size for cleanup:** **512 MiB** — выше reject `413` / problem `file_too_large` (защита sync worker). Документировать в OpenAPI.
|
||||
|
||||
**Handler timeout:** `60s` context на cleanup; для типичных log < 512 MiB truncate/delete — миллисекунды.
|
||||
|
||||
**Audit:** всегда запись после успешной операции; при ошибке — no audit, `500`.
|
||||
|
||||
## 2️⃣ OPTIONS — Tail / preview
|
||||
|
||||
| Option | Lines default | Bytes cap |
|
||||
|--------|---------------|-----------|
|
||||
| **T1** | 200 lines | 256 KiB |
|
||||
| **T2** | 500 lines | 1 MiB |
|
||||
| **T3** | 1000 lines | 512 KiB |
|
||||
|
||||
## 4️⃣ DECISION — Tail
|
||||
|
||||
**Query params** `GET /v1/runtime-logs/files/{filename}`:
|
||||
|
||||
| Param | Default | Max | Note |
|
||||
|-------|---------|-----|------|
|
||||
| `lines` | 200 | 2000 | Читать с конца файла |
|
||||
| `bytes` | — | 262144 (256 KiB) | Альтернатива lines; если оба — **min** лимит |
|
||||
| `grep` | — | max 128 chars | Опционально; фильтр после чтения tail chunk |
|
||||
|
||||
**Implementation:** read last N bytes (cap 256 KiB), split lines, take last `lines` (cap 2000). Не mmap всего файла.
|
||||
|
||||
**grep:** простой `strings.Contains` post-filter (не regex) — снижает ReDoS risk.
|
||||
|
||||
## 5️⃣ IMPLEMENTATION NOTES
|
||||
|
||||
- `internal/runtimelogs/tail.go` — `TailFile(path, opts) ([]byte, truncated bool, err)`
|
||||
- `internal/runtimelogs/cleanup.go` — `Cleanup(path, mode) (sizeBefore, sizeAfter int64, err)`
|
||||
- OpenAPI enum `RuntimeLogCleanupMode: truncate | delete`
|
||||
- Response cleanup: `{ "audit_id", "filename", "action", "size_before", "size_after" }`
|
||||
- UI: primary button «Очистить (обнулить)»; secondary «Удалить файл»
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
📌 **CREATIVE PHASE END: Cleanup & Tail**
|
||||
@@ -319,7 +319,7 @@ graph TD
|
||||
|
||||
- [x] **CP-1 uiux** — `creative-tenant-settings-ui.md` ✅ Tabs `/tenant-settings`, nav «Параметры»
|
||||
- [x] **CP-2 uiux** — `creative-runtime-logs-ui.md` ✅ Monitoring tab `runtime-logs` + sub-tabs files/audit
|
||||
- [ ] **CP-3 algorithm** — `creative-runtime-logs-cleanup.md` (truncate default vs delete)
|
||||
- [x] **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`
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user