Files
EvoBGP/internal/repository/postgres_runtime_logs.go
T
DenozordecandCursor 3f0dd6c234 docs(runtime-logs): implement runtime log management features
Добавлены новые возможности для работы с файловыми логами Docker-сервисов:
- Эндпоинты для получения списка логов и хвоста лог-файла.
- Очистка лог-файлов с возможностью выбора режима (truncate или delete) и запись в аудит очистки.
- Обновлена документация и конфигурация для поддержки новых функций.

Co-authored-by: Cursor <[email protected]>
2026-06-12 19:04:53 +07:00

88 lines
2.4 KiB
Go

package repository
import (
"context"
"encoding/json"
"strconv"
"strings"
"github.com/google/uuid"
"evobgp/internal/store"
)
// AppendRuntimeLogCleanupAudit records a runtime log cleanup operation.
func (p *Postgres) AppendRuntimeLogCleanupAudit(tenantID, actor, filename, action string, sizeBefore int64, sizeAfter *int64, detail map[string]any) (string, error) {
if strings.TrimSpace(tenantID) == "" || !store.ValidRuntimeLogCleanupAction(action) || strings.TrimSpace(filename) == "" {
return "", store.ErrInvalidInput
}
ctx := context.Background()
id := uuid.NewString()
var detailJSON []byte
if detail != nil {
detailJSON, _ = json.Marshal(detail)
}
var sizeAfterVal any
if sizeAfter != nil {
sizeAfterVal = *sizeAfter
}
_, err := p.pool.Exec(ctx, `
INSERT INTO runtime_log_cleanup_audit
(id, tenant_id, actor_prefix, filename, action, size_before, size_after, detail_json, created_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, now())`,
id, tenantID, strings.TrimSpace(actor), strings.TrimSpace(filename), action,
sizeBefore, sizeAfterVal, nullJSONBytes(detailJSON))
if err != nil {
return "", err
}
return id, nil
}
// ListRuntimeLogCleanupAudit returns paginated cleanup audit rows for a tenant.
func (p *Postgres) ListRuntimeLogCleanupAudit(tenantID, cursor string, limit int) ([]*store.RuntimeLogCleanupAudit, string, bool, error) {
if limit <= 0 {
limit = 50
}
off := 0
if cursor != "" {
if n, err := strconv.Atoi(cursor); err == nil && n >= 0 {
off = n
}
}
ctx := context.Background()
rows, err := p.pool.Query(ctx, `
SELECT id, tenant_id, actor_prefix, filename, action, size_before, size_after, detail_json, created_at
FROM runtime_log_cleanup_audit
WHERE tenant_id = $1
ORDER BY created_at DESC, id DESC
LIMIT $2 OFFSET $3`, tenantID, limit+1, off)
if err != nil {
return nil, "", false, err
}
defer rows.Close()
var out []*store.RuntimeLogCleanupAudit
for rows.Next() {
var r store.RuntimeLogCleanupAudit
var detailRaw []byte
var sizeAfter *int64
if err := rows.Scan(&r.ID, &r.TenantID, &r.ActorPrefix, &r.Filename, &r.Action,
&r.SizeBefore, &sizeAfter, &detailRaw, &r.CreatedAt); err != nil {
continue
}
r.SizeAfter = sizeAfter
if len(detailRaw) > 0 {
_ = json.Unmarshal(detailRaw, &r.Detail)
}
out = append(out, &r)
}
more := len(out) > limit
if more {
out = out[:limit]
}
next := ""
if more {
next = strconv.Itoa(off + limit)
}
return out, next, more, rows.Err()
}