Добавлены новые возможности для работы с файловыми логами Docker-сервисов: - Эндпоинты для получения списка логов и хвоста лог-файла. - Очистка лог-файлов с возможностью выбора режима (truncate или delete) и запись в аудит очистки. - Обновлена документация и конфигурация для поддержки новых функций. Co-authored-by: Cursor <[email protected]>
88 lines
2.4 KiB
Go
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()
|
|
}
|