mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 14:06:36 +08:00
157 lines
5.0 KiB
Go
157 lines
5.0 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package tasks
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/Rain-kl/Wavelet/internal/model"
|
|
"github.com/Rain-kl/Wavelet/internal/repository"
|
|
)
|
|
|
|
const (
|
|
// DatabaseCleanupTargetAccessLogs is the API cleanup target for access logs.
|
|
DatabaseCleanupTargetAccessLogs = "node_access_logs"
|
|
// DatabaseCleanupTargetMetricSnapshots is the API cleanup target for metric snapshots.
|
|
DatabaseCleanupTargetMetricSnapshots = "node_metric_snapshots"
|
|
// DatabaseCleanupTargetRequestReports is the API cleanup target for request reports.
|
|
DatabaseCleanupTargetRequestReports = "node_request_reports"
|
|
)
|
|
|
|
var databaseCleanupTargets = map[string]string{
|
|
DatabaseCleanupTargetAccessLogs: "访问日志",
|
|
DatabaseCleanupTargetMetricSnapshots: "性能快照",
|
|
DatabaseCleanupTargetRequestReports: "请求聚合",
|
|
}
|
|
|
|
// DatabaseCleanupInput describes a manual observability cleanup request.
|
|
type DatabaseCleanupInput struct {
|
|
Target string `json:"target"`
|
|
RetentionDays *int `json:"retention_days"`
|
|
}
|
|
|
|
// DatabaseCleanupResult summarizes a manual observability cleanup run.
|
|
type DatabaseCleanupResult struct {
|
|
Target string `json:"target"`
|
|
TargetLabel string `json:"target_label"`
|
|
DeletedCount int64 `json:"deleted_count"`
|
|
DeleteAll bool `json:"delete_all"`
|
|
RetentionDays *int `json:"retention_days,omitempty"`
|
|
Cutoff *time.Time `json:"cutoff,omitempty"`
|
|
}
|
|
|
|
// DatabaseAutoCleanupSummary summarizes a scheduled auto-cleanup run.
|
|
type DatabaseAutoCleanupSummary struct {
|
|
RetentionDays int `json:"retention_days"`
|
|
ExecutedAt time.Time `json:"executed_at"`
|
|
Results []DatabaseCleanupResult `json:"results"`
|
|
}
|
|
|
|
// CleanupDatabaseObservability deletes observability rows for the given target.
|
|
func CleanupDatabaseObservability(ctx context.Context, input DatabaseCleanupInput) (*DatabaseCleanupResult, error) {
|
|
target := strings.TrimSpace(input.Target)
|
|
targetLabel, ok := databaseCleanupTargets[target]
|
|
if !ok {
|
|
return nil, errors.New("unsupported cleanup target")
|
|
}
|
|
if input.RetentionDays != nil && *input.RetentionDays <= 0 {
|
|
return nil, errors.New("retention_days 必须为大于 0 的整数")
|
|
}
|
|
|
|
result := &DatabaseCleanupResult{
|
|
Target: target,
|
|
TargetLabel: targetLabel,
|
|
DeleteAll: input.RetentionDays == nil,
|
|
}
|
|
|
|
if input.RetentionDays == nil {
|
|
deleted, err := deleteAllObservabilityRows(ctx, target)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result.DeletedCount = deleted
|
|
return result, nil
|
|
}
|
|
|
|
retentionDays := *input.RetentionDays
|
|
cutoff := time.Now().UTC().Add(-time.Duration(retentionDays) * 24 * time.Hour)
|
|
deleted, err := deleteObservabilityRowsBefore(ctx, target, cutoff)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result.DeletedCount = deleted
|
|
result.RetentionDays = &retentionDays
|
|
result.Cutoff = &cutoff
|
|
return result, nil
|
|
}
|
|
|
|
// RunDatabaseAutoCleanupOnce runs retention-based cleanup for all observability targets.
|
|
func RunDatabaseAutoCleanupOnce(ctx context.Context, now time.Time) (*DatabaseAutoCleanupSummary, error) {
|
|
enabled, err := repository.GetBoolByKey(ctx, model.ConfigKeyDatabaseAutoCleanupEnabled)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read database_auto_cleanup_enabled: %w", err)
|
|
}
|
|
if !enabled {
|
|
return nil, nil
|
|
}
|
|
|
|
retentionDays, err := repository.GetIntByKey(ctx, model.ConfigKeyDatabaseAutoCleanupRetentionDays)
|
|
if err != nil || retentionDays <= 0 {
|
|
// Use default value 30 if config read fails or value is invalid
|
|
retentionDays = 30
|
|
}
|
|
|
|
results := make([]DatabaseCleanupResult, 0, len(databaseCleanupTargets))
|
|
for _, target := range []string{
|
|
DatabaseCleanupTargetAccessLogs,
|
|
DatabaseCleanupTargetMetricSnapshots,
|
|
DatabaseCleanupTargetRequestReports,
|
|
} {
|
|
result, err := CleanupDatabaseObservability(ctx, DatabaseCleanupInput{
|
|
Target: target,
|
|
RetentionDays: &retentionDays,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
results = append(results, *result)
|
|
}
|
|
|
|
return &DatabaseAutoCleanupSummary{
|
|
RetentionDays: retentionDays,
|
|
ExecutedAt: now.UTC(),
|
|
Results: results,
|
|
}, nil
|
|
}
|
|
|
|
func deleteAllObservabilityRows(ctx context.Context, target string) (int64, error) {
|
|
switch target {
|
|
case DatabaseCleanupTargetAccessLogs:
|
|
return model.DeleteAllOpenFlareAccessLogs(ctx)
|
|
case DatabaseCleanupTargetMetricSnapshots:
|
|
return model.DeleteAllOpenFlareMetricSnapshots(ctx)
|
|
case DatabaseCleanupTargetRequestReports:
|
|
return model.DeleteAllOpenFlareRequestReports(ctx)
|
|
default:
|
|
return 0, errors.New("unsupported cleanup target")
|
|
}
|
|
}
|
|
|
|
func deleteObservabilityRowsBefore(ctx context.Context, target string, cutoff time.Time) (int64, error) {
|
|
switch target {
|
|
case DatabaseCleanupTargetAccessLogs:
|
|
return model.DeleteOpenFlareAccessLogsBefore(ctx, cutoff)
|
|
case DatabaseCleanupTargetMetricSnapshots:
|
|
return model.DeleteOpenFlareMetricSnapshotsBefore(ctx, cutoff)
|
|
case DatabaseCleanupTargetRequestReports:
|
|
return model.DeleteOpenFlareRequestReportsBefore(ctx, cutoff)
|
|
default:
|
|
return 0, errors.New("unsupported cleanup target")
|
|
}
|
|
}
|