KI shit haha
This commit is contained in:
8
Watcher/Services/IUpdateCheckStore.cs
Normal file
8
Watcher/Services/IUpdateCheckStore.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Watcher.Services;
|
||||
|
||||
public interface IUpdateCheckStore
|
||||
{
|
||||
bool IsUpdateAvailable { get; set; }
|
||||
string? LatestVersion { get; set; }
|
||||
DateTime LastChecked { get; set; }
|
||||
}
|
||||
6
Watcher/Services/IVersionService.cs
Normal file
6
Watcher/Services/IVersionService.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Watcher.Services;
|
||||
|
||||
public interface IVersionService
|
||||
{
|
||||
string GetVersion();
|
||||
}
|
||||
127
Watcher/Services/MetricCleanupService.cs
Normal file
127
Watcher/Services/MetricCleanupService.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
159
Watcher/Services/UpdateCheckService.cs
Normal file
159
Watcher/Services/UpdateCheckService.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Watcher.Services;
|
||||
|
||||
public class UpdateCheckService : BackgroundService
|
||||
{
|
||||
private readonly ILogger<UpdateCheckService> _logger;
|
||||
private readonly IUpdateCheckStore _updateCheckStore;
|
||||
private readonly IVersionService _versionService;
|
||||
private readonly string _repositoryUrl;
|
||||
private readonly int _checkIntervalHours;
|
||||
private readonly bool _enabled;
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public UpdateCheckService(
|
||||
ILogger<UpdateCheckService> logger,
|
||||
IUpdateCheckStore updateCheckStore,
|
||||
IVersionService versionService,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
_logger = logger;
|
||||
_updateCheckStore = updateCheckStore;
|
||||
_versionService = versionService;
|
||||
_httpClient = new HttpClient();
|
||||
|
||||
// Konfiguration aus Environment Variablen laden
|
||||
_repositoryUrl = configuration["UpdateCheck:RepositoryUrl"]
|
||||
?? Environment.GetEnvironmentVariable("UPDATE_CHECK_REPOSITORY_URL")
|
||||
?? "https://git.triggermeelmo.com/api/v1/repos/Watcher/watcher/releases/latest";
|
||||
|
||||
_checkIntervalHours = int.TryParse(
|
||||
configuration["UpdateCheck:CheckIntervalHours"]
|
||||
?? Environment.GetEnvironmentVariable("UPDATE_CHECK_INTERVAL_HOURS"),
|
||||
out var hours) ? hours : 24; // Default: 24 Stunden
|
||||
|
||||
_enabled = bool.TryParse(
|
||||
configuration["UpdateCheck:Enabled"]
|
||||
?? Environment.GetEnvironmentVariable("UPDATE_CHECK_ENABLED"),
|
||||
out var enabled) ? enabled : true; // Default: aktiviert
|
||||
|
||||
_logger.LogInformation(
|
||||
"UpdateCheckService konfiguriert: Enabled={Enabled}, Repository={Repo}, IntervalHours={Hours}",
|
||||
_enabled, _repositoryUrl, _checkIntervalHours);
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
if (!_enabled)
|
||||
{
|
||||
_logger.LogInformation("UpdateCheckService ist deaktiviert.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Warte 2 Minuten nach Start, bevor der erste Check läuft
|
||||
await Task.Delay(TimeSpan.FromMinutes(2), stoppingToken);
|
||||
|
||||
var timer = new PeriodicTimer(TimeSpan.FromHours(_checkIntervalHours));
|
||||
|
||||
while (await timer.WaitForNextTickAsync(stoppingToken))
|
||||
{
|
||||
try
|
||||
{
|
||||
await CheckForUpdatesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Fehler beim Update-Check.");
|
||||
}
|
||||
|
||||
await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CheckForUpdatesAsync()
|
||||
{
|
||||
var currentVersion = _versionService.GetVersion();
|
||||
|
||||
_logger.LogInformation("Starte Update-Check. Aktuelle Version: {Version}", currentVersion);
|
||||
|
||||
// Bei "development" oder "latest" immer als aktuell markieren
|
||||
if (currentVersion == "development" || currentVersion == "latest")
|
||||
{
|
||||
_updateCheckStore.IsUpdateAvailable = false;
|
||||
_updateCheckStore.LatestVersion = currentVersion;
|
||||
_updateCheckStore.LastChecked = DateTime.UtcNow;
|
||||
_logger.LogInformation("Development/Latest Build - keine Update-Prüfung nötig.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Gitea API abfragen
|
||||
var response = await _httpClient.GetAsync(_repositoryUrl);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
_logger.LogWarning("Gitea API Fehler: {StatusCode}", response.StatusCode);
|
||||
return;
|
||||
}
|
||||
|
||||
var jsonContent = await response.Content.ReadAsStringAsync();
|
||||
var releaseInfo = JsonSerializer.Deserialize<GiteaReleaseResponse>(jsonContent);
|
||||
|
||||
if (releaseInfo?.TagName == null)
|
||||
{
|
||||
_logger.LogWarning("Keine Release-Information gefunden.");
|
||||
return;
|
||||
}
|
||||
|
||||
var latestVersion = releaseInfo.TagName;
|
||||
_updateCheckStore.LatestVersion = latestVersion;
|
||||
_updateCheckStore.LastChecked = DateTime.UtcNow;
|
||||
|
||||
// Versionsvergleich
|
||||
var isNewer = CompareVersions(latestVersion, currentVersion);
|
||||
_updateCheckStore.IsUpdateAvailable = isNewer;
|
||||
|
||||
if (isNewer)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"Neue Version verfügbar: {Latest} (aktuell: {Current})",
|
||||
latestVersion, currentVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"System ist auf dem neuesten Stand: {Version}",
|
||||
currentVersion);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Fehler beim Abrufen der Release-Informationen von Gitea.");
|
||||
}
|
||||
}
|
||||
|
||||
private bool CompareVersions(string latestVersion, string currentVersion)
|
||||
{
|
||||
// Entferne "v" Prefix falls vorhanden
|
||||
latestVersion = latestVersion.TrimStart('v');
|
||||
currentVersion = currentVersion.TrimStart('v');
|
||||
|
||||
// Versuche semantic versioning zu parsen
|
||||
if (Version.TryParse(latestVersion, out var latest) &&
|
||||
Version.TryParse(currentVersion, out var current))
|
||||
{
|
||||
return latest > current;
|
||||
}
|
||||
|
||||
// Fallback: String-Vergleich
|
||||
return string.Compare(latestVersion, currentVersion, StringComparison.Ordinal) > 0;
|
||||
}
|
||||
|
||||
// DTO für Gitea API Response
|
||||
private class GiteaReleaseResponse
|
||||
{
|
||||
public string? TagName { get; set; }
|
||||
}
|
||||
}
|
||||
8
Watcher/Services/UpdateCheckStore.cs
Normal file
8
Watcher/Services/UpdateCheckStore.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Watcher.Services;
|
||||
|
||||
public class UpdateCheckStore : IUpdateCheckStore
|
||||
{
|
||||
public bool IsUpdateAvailable { get; set; } = false;
|
||||
public string? LatestVersion { get; set; } = null;
|
||||
public DateTime LastChecked { get; set; } = DateTime.MinValue;
|
||||
}
|
||||
19
Watcher/Services/VersionService.cs
Normal file
19
Watcher/Services/VersionService.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace Watcher.Services;
|
||||
|
||||
public class VersionService : IVersionService
|
||||
{
|
||||
private readonly string _version;
|
||||
|
||||
public VersionService(IConfiguration configuration)
|
||||
{
|
||||
// Priorität: Environment Variable > Configuration > Default
|
||||
_version = Environment.GetEnvironmentVariable("WATCHER_VERSION")
|
||||
?? configuration["Application:Version"]
|
||||
?? "development";
|
||||
}
|
||||
|
||||
public string GetVersion()
|
||||
{
|
||||
return _version;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user