Files
EvoBGP/memory-bank/creative/creative-runtime-logs-cleanup.md
T
DenozordecandCursor 493575aca4 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]>
2026-06-12 18:58:06 +07:00

4.4 KiB
Raw Blame History

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.goTailFile(path, opts) ([]byte, truncated bool, err)
  • internal/runtimelogs/cleanup.goCleanup(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