128 lines
4.4 KiB
C#
128 lines
4.4 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Watcher.Data;
|
|
|
|
namespace Watcher.Services;
|
|
|
|
public class MetricCleanupService : BackgroundService
|
|
{
|
|
private readonly ILogger<MetricCleanupService> _logger;
|
|
private readonly IServiceProvider _serviceProvider;
|
|
private readonly int _retentionDays;
|
|
private readonly int _checkIntervalHours;
|
|
private readonly bool _enabled;
|
|
|
|
public MetricCleanupService(
|
|
ILogger<MetricCleanupService> logger,
|
|
IServiceProvider serviceProvider,
|
|
IConfiguration configuration)
|
|
{
|
|
_logger = logger;
|
|
_serviceProvider = serviceProvider;
|
|
|
|
// Konfiguration aus Environment Variablen laden
|
|
_retentionDays = int.TryParse(
|
|
configuration["DataRetention:MetricRetentionDays"] ??
|
|
Environment.GetEnvironmentVariable("METRIC_RETENTION_DAYS"),
|
|
out var days) ? days : 30; // Default: 30 Tage
|
|
|
|
_checkIntervalHours = int.TryParse(
|
|
configuration["DataRetention:CleanupIntervalHours"] ??
|
|
Environment.GetEnvironmentVariable("METRIC_CLEANUP_INTERVAL_HOURS"),
|
|
out var hours) ? hours : 24; // Default: 24 Stunden
|
|
|
|
_enabled = bool.TryParse(
|
|
configuration["DataRetention:Enabled"] ??
|
|
Environment.GetEnvironmentVariable("METRIC_CLEANUP_ENABLED"),
|
|
out var enabled) ? enabled : true; // Default: aktiviert
|
|
|
|
_logger.LogInformation(
|
|
"MetricCleanupService konfiguriert: Enabled={Enabled}, RetentionDays={Days}, IntervalHours={Hours}",
|
|
_enabled, _retentionDays, _checkIntervalHours);
|
|
}
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
if (!_enabled)
|
|
{
|
|
_logger.LogInformation("MetricCleanupService ist deaktiviert.");
|
|
return;
|
|
}
|
|
|
|
// Warte 1 Minute nach Start, bevor der erste Cleanup läuft
|
|
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
|
|
|
|
var timer = new PeriodicTimer(TimeSpan.FromHours(_checkIntervalHours));
|
|
|
|
while (await timer.WaitForNextTickAsync(stoppingToken))
|
|
{
|
|
try
|
|
{
|
|
await CleanupOldMetricsAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Fehler beim Cleanup alter Metriken.");
|
|
}
|
|
|
|
// Offset nach Cleanup
|
|
await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
|
|
}
|
|
}
|
|
|
|
private async Task CleanupOldMetricsAsync()
|
|
{
|
|
_logger.LogInformation("Starte Metric Cleanup für Daten älter als {Days} Tage...", _retentionDays);
|
|
|
|
using var scope = _serviceProvider.CreateScope();
|
|
var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
|
|
|
var cutoffDate = DateTime.UtcNow.AddDays(-_retentionDays);
|
|
|
|
try
|
|
{
|
|
// Anzahl der zu löschenden Einträge ermitteln
|
|
var countToDelete = await context.Metrics
|
|
.Where(m => m.Timestamp < cutoffDate)
|
|
.CountAsync();
|
|
|
|
if (countToDelete == 0)
|
|
{
|
|
_logger.LogInformation("Keine alten Metriken zum Löschen gefunden.");
|
|
return;
|
|
}
|
|
|
|
_logger.LogInformation("Lösche {Count} Metriken vor {Date}...", countToDelete, cutoffDate);
|
|
|
|
// Metriken löschen
|
|
var deletedCount = await context.Metrics
|
|
.Where(m => m.Timestamp < cutoffDate)
|
|
.ExecuteDeleteAsync();
|
|
|
|
_logger.LogInformation(
|
|
"Metric Cleanup abgeschlossen: {DeletedCount} Einträge gelöscht.",
|
|
deletedCount);
|
|
|
|
// Optional: ContainerMetrics auch bereinigen
|
|
var containerMetricsCount = await context.ContainerMetrics
|
|
.Where(cm => cm.Timestamp < cutoffDate)
|
|
.CountAsync();
|
|
|
|
if (containerMetricsCount > 0)
|
|
{
|
|
var deletedContainerMetrics = await context.ContainerMetrics
|
|
.Where(cm => cm.Timestamp < cutoffDate)
|
|
.ExecuteDeleteAsync();
|
|
|
|
_logger.LogInformation(
|
|
"ContainerMetrics Cleanup: {DeletedCount} Einträge gelöscht.",
|
|
deletedContainerMetrics);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Fehler beim Löschen alter Metriken aus der Datenbank.");
|
|
throw;
|
|
}
|
|
}
|
|
}
|