feat(audit): 审计日志保留期清理(后端自动清理 + 审计页配置) (#83)

审计日志新增可配置保留期:AuditLogRepository.DeleteBefore + AuditService 保留期监控(每 6h 读取 audit_retention_days,0/缺省=永久保留);审计页新增管理员保留天数配置控件。后端 go test、前端 tsc+vite 通过。
This commit is contained in:
Wu Qing
2026-05-27 08:37:34 +08:00
committed by GitHub
parent a0d1e66199
commit f807ce10e6
7 changed files with 209 additions and 1 deletions
+54
View File
@@ -10,6 +10,7 @@ import (
"fmt"
"log"
"net/http"
"strconv"
"strings"
"sync"
"time"
@@ -51,6 +52,59 @@ func NewAuditService(repo repository.AuditLogRepository) *AuditService {
}
}
// PurgeOlderThan 删除早于 days 天前的审计日志,返回删除条数。days<=0 时不清理。
func (s *AuditService) PurgeOlderThan(ctx context.Context, days int) (int64, error) {
if days <= 0 {
return 0, nil
}
cutoff := time.Now().UTC().AddDate(0, 0, -days)
return s.repo.DeleteBefore(ctx, cutoff)
}
// StartRetentionMonitor 启动后台审计保留期清理:按 interval 周期读取
// audit_retention_days 设置,>0 时删除超期审计日志。缺省/0 表示永久保留
// (向后兼容,默认不删任何历史)。ctx 取消后退出。
func (s *AuditService) StartRetentionMonitor(ctx context.Context, configs repository.SystemConfigRepository, interval time.Duration) {
if s == nil || configs == nil {
return
}
if interval <= 0 {
interval = 6 * time.Hour
}
go func() {
ticker := time.NewTicker(interval)
defer ticker.Stop()
s.runRetentionOnce(ctx, configs) // 启动后立即跑一次
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
s.runRetentionOnce(ctx, configs)
}
}
}()
}
func (s *AuditService) runRetentionOnce(ctx context.Context, configs repository.SystemConfigRepository) {
cfg, err := configs.GetByKey(ctx, SettingKeyAuditRetentionDays)
if err != nil || cfg == nil {
return
}
days, err := strconv.Atoi(strings.TrimSpace(cfg.Value))
if err != nil || days <= 0 {
return
}
deleted, err := s.PurgeOlderThan(ctx, days)
if err != nil {
log.Printf("[audit] retention purge failed: %v", err)
return
}
if deleted > 0 {
log.Printf("[audit] retention purge: deleted %d logs older than %d days", deleted, days)
}
}
// SetWebhook 动态配置审计事件转发 URL 与签名密钥。
// - url 为空字符串时禁用转发
// - secret 非空时对 payload 计算 HMAC-SHA256,作为 X-BackupX-Signature header