Refresh Rate anpassbar, Containerübersicht wird nicht mehr überschrieben
This commit is contained in:
@@ -21,12 +21,16 @@ namespace Watcher.Controllers
|
|||||||
// Daten der Backgroundchecks abrufen
|
// Daten der Backgroundchecks abrufen
|
||||||
private IDashboardStore _DashboardStore;
|
private IDashboardStore _DashboardStore;
|
||||||
|
|
||||||
|
// System Store für Konfigurationen
|
||||||
|
private ISystemStore _SystemStore;
|
||||||
|
|
||||||
// HomeController Constructor
|
// HomeController Constructor
|
||||||
public HomeController(AppDbContext context, ILogger<HomeController> logger, IDashboardStore dashboardStore)
|
public HomeController(AppDbContext context, ILogger<HomeController> logger, IDashboardStore dashboardStore, ISystemStore systemStore)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_DashboardStore = dashboardStore;
|
_DashboardStore = dashboardStore;
|
||||||
|
_SystemStore = systemStore;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +63,8 @@ namespace Watcher.Controllers
|
|||||||
.OrderBy(s => s.Name)
|
.OrderBy(s => s.Name)
|
||||||
.ToListAsync(),
|
.ToListAsync(),
|
||||||
NetworkStatus = _DashboardStore.NetworkStatus,
|
NetworkStatus = _DashboardStore.NetworkStatus,
|
||||||
DatabaseStatus = _DashboardStore.DatabaseStatus
|
DatabaseStatus = _DashboardStore.DatabaseStatus,
|
||||||
|
RefreshIntervalMilliseconds = _SystemStore.FrontendRefreshIntervalMilliseconds
|
||||||
};
|
};
|
||||||
//ViewBag.NetworkConnection = _NetworkCheckStore.NetworkStatus;
|
//ViewBag.NetworkConnection = _NetworkCheckStore.NetworkStatus;
|
||||||
return View(viewModel);
|
return View(viewModel);
|
||||||
|
|||||||
@@ -280,9 +280,18 @@ public class MonitoringController : Controller
|
|||||||
foreach (Container c in newContainers)
|
foreach (Container c in newContainers)
|
||||||
{
|
{
|
||||||
// Überprüfen, ob ein übergebener Container bereits für den Host registriert ist
|
// Überprüfen, ob ein übergebener Container bereits für den Host registriert ist
|
||||||
if (existingContainers.Contains(c))
|
// Wichtig: Vergleich über ContainerId, nicht über Objektreferenz!
|
||||||
|
var existingContainer = existingContainers
|
||||||
|
.FirstOrDefault(ec => ec.ContainerId == c.ContainerId);
|
||||||
|
|
||||||
|
if (existingContainer != null)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Container with id " + c.ContainerId + " already exists.");
|
// Container existiert bereits, nur Daten aktualisieren falls sich etwas geändert hat
|
||||||
|
existingContainer.Name = c.Name;
|
||||||
|
existingContainer.Image = c.Image;
|
||||||
|
existingContainer.IsRunning = true;
|
||||||
|
|
||||||
|
_logger.LogInformation("Container '{containerName}' (ID: {containerId}) already exists for Server {serverId}, updated.", c.Name, c.ContainerId, dto.Server_id);
|
||||||
}
|
}
|
||||||
// Container auf einen Host/Server registrieren
|
// Container auf einen Host/Server registrieren
|
||||||
else
|
else
|
||||||
@@ -292,11 +301,11 @@ public class MonitoringController : Controller
|
|||||||
{
|
{
|
||||||
_context.Containers.Add(c);
|
_context.Containers.Add(c);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
_logger.LogInformation(c.Name + " added for Host " + c.ServerId);
|
_logger.LogInformation("Container '{containerName}' (ID: {containerId}) added for Server {serverId}", c.Name, c.ContainerId, c.ServerId);
|
||||||
}
|
}
|
||||||
catch (SqliteException e)
|
catch (SqliteException e)
|
||||||
{
|
{
|
||||||
_logger.LogError("Error writing new Containers to Database: " + e.Message);
|
_logger.LogError("Error writing new Container '{containerName}' to Database: {error}", c.Name, e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,7 +314,11 @@ public class MonitoringController : Controller
|
|||||||
foreach (Container c in existingContainers)
|
foreach (Container c in existingContainers)
|
||||||
{
|
{
|
||||||
// Abfrage, ob bereits vorhandener Container im Payload vorhanden war
|
// Abfrage, ob bereits vorhandener Container im Payload vorhanden war
|
||||||
if (!newContainers.Contains(c))
|
// Wichtig: Vergleich über ContainerId, nicht über Objektreferenz!
|
||||||
|
var stillRunning = newContainers
|
||||||
|
.Any(nc => nc.ContainerId == c.ContainerId);
|
||||||
|
|
||||||
|
if (!stillRunning)
|
||||||
{
|
{
|
||||||
// Container entfernen
|
// Container entfernen
|
||||||
_context.Containers.Remove(c);
|
_context.Containers.Remove(c);
|
||||||
@@ -314,10 +327,13 @@ public class MonitoringController : Controller
|
|||||||
// Metrics für den Container entfernen
|
// Metrics für den Container entfernen
|
||||||
//Todo
|
//Todo
|
||||||
|
|
||||||
_logger.LogInformation("Container " + c.Name + " (" + c.Id + ") on Host-Id " + c.ServerId + " was successfully removed from the database.");
|
_logger.LogInformation("Container '{containerName}' (DB-ID: {id}, ContainerID: {containerId}) on Server {serverId} was removed from the database.", c.Name, c.Id, c.ContainerId, c.ServerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Alle Änderungen in einem Batch speichern
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Watcher.Data;
|
using Watcher.Data;
|
||||||
using Watcher.Models;
|
using Watcher.Models;
|
||||||
using Watcher.ViewModels;
|
using Watcher.ViewModels;
|
||||||
|
using Watcher.Services;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
@@ -13,11 +14,14 @@ public class ServerController : Controller
|
|||||||
|
|
||||||
private readonly ILogger<ServerController> _logger;
|
private readonly ILogger<ServerController> _logger;
|
||||||
|
|
||||||
|
private readonly ISystemStore _systemStore;
|
||||||
|
|
||||||
public ServerController(AppDbContext context, ILogger<ServerController> logger)
|
|
||||||
|
public ServerController(AppDbContext context, ILogger<ServerController> logger, ISystemStore systemStore)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_systemStore = systemStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -26,7 +30,8 @@ public class ServerController : Controller
|
|||||||
{
|
{
|
||||||
var vm = new ServerOverviewViewModel
|
var vm = new ServerOverviewViewModel
|
||||||
{
|
{
|
||||||
Servers = await _context.Servers.OrderBy(s => s.Id).ToListAsync()
|
Servers = await _context.Servers.OrderBy(s => s.Id).ToListAsync(),
|
||||||
|
RefreshIntervalMilliseconds = _systemStore.FrontendRefreshIntervalMilliseconds
|
||||||
};
|
};
|
||||||
|
|
||||||
return View(vm);
|
return View(vm);
|
||||||
@@ -159,7 +164,8 @@ public class ServerController : Controller
|
|||||||
CreatedAt = s.CreatedAt,
|
CreatedAt = s.CreatedAt,
|
||||||
IsOnline = s.IsOnline,
|
IsOnline = s.IsOnline,
|
||||||
LastSeen = s.LastSeen,
|
LastSeen = s.LastSeen,
|
||||||
IsVerified = s.IsVerified
|
IsVerified = s.IsVerified,
|
||||||
|
RefreshIntervalMilliseconds = _systemStore.FrontendRefreshIntervalMilliseconds
|
||||||
};
|
};
|
||||||
|
|
||||||
return View(vm);
|
return View(vm);
|
||||||
@@ -177,6 +183,7 @@ public class ServerController : Controller
|
|||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ViewBag.RefreshIntervalMilliseconds = _systemStore.FrontendRefreshIntervalMilliseconds;
|
||||||
return PartialView("_ServerCard", servers);
|
return PartialView("_ServerCard", servers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,10 +34,24 @@ builder.Services.AddHttpContextAccessor();
|
|||||||
|
|
||||||
// Storage Singleton
|
// Storage Singleton
|
||||||
builder.Services.AddSingleton<IDashboardStore, DashboardStore>();
|
builder.Services.AddSingleton<IDashboardStore, DashboardStore>();
|
||||||
builder.Services.AddSingleton<ISystemStore, SystemStore>();
|
|
||||||
builder.Services.AddSingleton<IVersionService, VersionService>();
|
builder.Services.AddSingleton<IVersionService, VersionService>();
|
||||||
builder.Services.AddSingleton<IUpdateCheckStore, UpdateCheckStore>();
|
builder.Services.AddSingleton<IUpdateCheckStore, UpdateCheckStore>();
|
||||||
|
|
||||||
|
// SystemStore mit Konfiguration initialisieren
|
||||||
|
builder.Services.AddSingleton<ISystemStore>(sp =>
|
||||||
|
{
|
||||||
|
var configuration = sp.GetRequiredService<IConfiguration>();
|
||||||
|
var refreshIntervalSeconds = int.TryParse(
|
||||||
|
configuration["Frontend:RefreshIntervalSeconds"]
|
||||||
|
?? Environment.GetEnvironmentVariable("FRONTEND_REFRESH_INTERVAL_SECONDS"),
|
||||||
|
out var seconds) ? seconds : 30;
|
||||||
|
|
||||||
|
return new SystemStore
|
||||||
|
{
|
||||||
|
FrontendRefreshIntervalMilliseconds = refreshIntervalSeconds * 1000
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
// Background Services
|
// Background Services
|
||||||
builder.Services.AddHostedService<NetworkCheck>();
|
builder.Services.AddHostedService<NetworkCheck>();
|
||||||
builder.Services.AddHostedService<DatabaseCheck>();
|
builder.Services.AddHostedService<DatabaseCheck>();
|
||||||
|
|||||||
@@ -6,4 +6,6 @@ public interface ISystemStore
|
|||||||
|
|
||||||
Double DatabaseSize { get; set; }
|
Double DatabaseSize { get; set; }
|
||||||
|
|
||||||
|
int FrontendRefreshIntervalMilliseconds { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,4 +6,6 @@ public class SystemStore: ISystemStore
|
|||||||
|
|
||||||
public Double DatabaseSize { get; set; }
|
public Double DatabaseSize { get; set; }
|
||||||
|
|
||||||
|
public int FrontendRefreshIntervalMilliseconds { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -17,5 +17,7 @@ namespace Watcher.ViewModels
|
|||||||
public String? NetworkStatus { get; set; } = "?";
|
public String? NetworkStatus { get; set; } = "?";
|
||||||
public String? DatabaseStatus { get; set; } = "?";
|
public String? DatabaseStatus { get; set; } = "?";
|
||||||
|
|
||||||
|
public int RefreshIntervalMilliseconds { get; set; } = 30000;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,4 +36,6 @@ public class ServerDetailsViewModel
|
|||||||
public DateTime LastSeen { get; set; }
|
public DateTime LastSeen { get; set; }
|
||||||
|
|
||||||
public Boolean IsVerified { get; set; } = false;
|
public Boolean IsVerified { get; set; } = false;
|
||||||
|
|
||||||
|
public int RefreshIntervalMilliseconds { get; set; } = 30000;
|
||||||
}
|
}
|
||||||
@@ -6,5 +6,6 @@ namespace Watcher.ViewModels
|
|||||||
public class ServerOverviewViewModel
|
public class ServerOverviewViewModel
|
||||||
{
|
{
|
||||||
public List<Server> Servers { get; set; } = new();
|
public List<Server> Servers { get; set; } = new();
|
||||||
|
public int RefreshIntervalMilliseconds { get; set; } = 30000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial laden und dann alle 30 Sekunden
|
// Initial laden und dann mit konfiguriertem Intervall
|
||||||
loadDashboardStats();
|
loadDashboardStats();
|
||||||
setInterval(loadDashboardStats, 30000);
|
setInterval(loadDashboardStats, @Model.RefreshIntervalMilliseconds);
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -480,10 +480,10 @@
|
|||||||
loadRamData();
|
loadRamData();
|
||||||
loadGpuData();
|
loadGpuData();
|
||||||
|
|
||||||
// Alle 30 Sekunden aktualisieren
|
// Mit konfiguriertem Intervall aktualisieren
|
||||||
setInterval(loadCpuData, 30000);
|
setInterval(loadCpuData, @Model.RefreshIntervalMilliseconds);
|
||||||
setInterval(loadRamData, 30000);
|
setInterval(loadRamData, @Model.RefreshIntervalMilliseconds);
|
||||||
setInterval(loadGpuData, 30000);
|
setInterval(loadGpuData, @Model.RefreshIntervalMilliseconds);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial laden und alle 30 Sekunden aktualisieren
|
// Initial laden und mit konfiguriertem Intervall aktualisieren
|
||||||
loadCurrentMetrics();
|
loadCurrentMetrics();
|
||||||
setInterval(loadCurrentMetrics, 30000);
|
const refreshInterval = @(ViewBag.RefreshIntervalMilliseconds ?? 30000);
|
||||||
|
setInterval(loadCurrentMetrics, refreshInterval);
|
||||||
</script>
|
</script>
|
||||||
@@ -44,8 +44,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial laden und dann alle 30 Sekunden
|
// Initial laden und dann mit konfiguriertem Intervall
|
||||||
loadServerCards();
|
loadServerCards();
|
||||||
setInterval(loadServerCards, 30000);
|
setInterval(loadServerCards, @Model.RefreshIntervalMilliseconds);
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
@@ -12,5 +12,9 @@
|
|||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"Sqlite": "Data Source=./persistence/watcher.db"
|
"Sqlite": "Data Source=./persistence/watcher.db"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"Frontend": {
|
||||||
|
"RefreshIntervalSeconds": 30
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,11 @@ services:
|
|||||||
- METRIC_RETENTION_DAYS=30
|
- METRIC_RETENTION_DAYS=30
|
||||||
- METRIC_CLEANUP_INTERVAL_HOURS=24
|
- METRIC_CLEANUP_INTERVAL_HOURS=24
|
||||||
- METRIC_CLEANUP_ENABLED=true
|
- METRIC_CLEANUP_ENABLED=true
|
||||||
|
# Aktualisierungsrate Frontend
|
||||||
|
- FRONTEND_REFRESH_INTERVAL_SECONDS=30
|
||||||
ports:
|
ports:
|
||||||
- "5000:5000"
|
- "5000:5000"
|
||||||
volumes:
|
volumes:
|
||||||
- ./watcher-volumes/data:/app/persistence
|
- ./data/db:/app/persistence
|
||||||
- ./watcher-volumes/dumps:/app/wwwroot/downloads/sqlite
|
- ./data/dumps:/app/wwwroot/downloads/sqlite
|
||||||
- ./watcher-volumes/logs:/app/logs
|
- ./data/logs:/app/logs
|
||||||
|
|||||||
Reference in New Issue
Block a user