Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 63316301fb | |||
| 3d375f4792 | |||
| 5a33c1c534 | |||
| 65c3ae2a40 |
@@ -244,6 +244,14 @@ public class MonitoringController : Controller
|
|||||||
return BadRequest(new { error = "Invalid Payload", details = errors });
|
return BadRequest(new { error = "Invalid Payload", details = errors });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prüfen, ob der Server existiert
|
||||||
|
var serverExists = await _context.Servers.AnyAsync(s => s.Id == dto.Server_id);
|
||||||
|
if (!serverExists)
|
||||||
|
{
|
||||||
|
_logger.LogError($"Server with ID {dto.Server_id} does not exist.");
|
||||||
|
return BadRequest(new { error = "Server not found", details = $"Server with ID {dto.Server_id} does not exist. Please register the server first." });
|
||||||
|
}
|
||||||
|
|
||||||
List<Container> newContainers =
|
List<Container> newContainers =
|
||||||
JsonSerializer.Deserialize<List<Container>>(dto.Containers.GetRawText())
|
JsonSerializer.Deserialize<List<Container>>(dto.Containers.GetRawText())
|
||||||
?? new List<Container>();
|
?? new List<Container>();
|
||||||
@@ -370,53 +378,62 @@ public class MonitoringController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("cpu-usage")]
|
[HttpGet("cpu-usage")]
|
||||||
public async Task<IActionResult> GetCpuUsageData(int serverId)
|
public async Task<IActionResult> GetCpuUsageData(int serverId, int hours = 1)
|
||||||
{
|
{
|
||||||
var oneDayAgo = DateTime.UtcNow.AddDays(-1);
|
var startTime = DateTime.UtcNow.AddHours(-hours);
|
||||||
var data = await _context.Metrics
|
var metrics = await _context.Metrics
|
||||||
.Where(m => m.Timestamp >= oneDayAgo && m.ServerId == serverId)
|
.Where(m => m.Timestamp >= startTime && m.ServerId == serverId)
|
||||||
.OrderBy(m => m.Timestamp)
|
.OrderBy(m => m.Timestamp)
|
||||||
.Select(m => new
|
|
||||||
{
|
|
||||||
label = m.Timestamp.ToUniversalTime().ToString("o"),
|
|
||||||
data = m.CPU_Load
|
|
||||||
})
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
// Timestamp-Format basierend auf Zeitbereich anpassen
|
||||||
|
string format = hours > 1 ? "dd.MM HH:mm" : "HH:mm";
|
||||||
|
var data = metrics.Select(m => new
|
||||||
|
{
|
||||||
|
label = m.Timestamp.ToLocalTime().ToString(format),
|
||||||
|
data = m.CPU_Load
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("ram-usage")]
|
[HttpGet("ram-usage")]
|
||||||
public async Task<IActionResult> GetRamUsageData(int serverId)
|
public async Task<IActionResult> GetRamUsageData(int serverId, int hours = 1)
|
||||||
{
|
{
|
||||||
var oneDayAgo = DateTime.UtcNow.AddDays(-1);
|
var startTime = DateTime.UtcNow.AddHours(-hours);
|
||||||
var data = await _context.Metrics
|
var metrics = await _context.Metrics
|
||||||
.Where(m => m.Timestamp >= oneDayAgo && m.ServerId == serverId)
|
.Where(m => m.Timestamp >= startTime && m.ServerId == serverId)
|
||||||
.OrderBy(m => m.Timestamp)
|
.OrderBy(m => m.Timestamp)
|
||||||
.Select(m => new
|
|
||||||
{
|
|
||||||
label = m.Timestamp.ToUniversalTime().ToString("o"),
|
|
||||||
data = m.RAM_Load
|
|
||||||
})
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
// Timestamp-Format basierend auf Zeitbereich anpassen
|
||||||
|
string format = hours > 1 ? "dd.MM HH:mm" : "HH:mm";
|
||||||
|
var data = metrics.Select(m => new
|
||||||
|
{
|
||||||
|
label = m.Timestamp.ToLocalTime().ToString(format),
|
||||||
|
data = m.RAM_Load
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("gpu-usage")]
|
[HttpGet("gpu-usage")]
|
||||||
public async Task<IActionResult> GetGpuUsageData(int serverId)
|
public async Task<IActionResult> GetGpuUsageData(int serverId, int hours = 1)
|
||||||
{
|
{
|
||||||
var oneDayAgo = DateTime.UtcNow.AddDays(-1);
|
var startTime = DateTime.UtcNow.AddHours(-hours);
|
||||||
var data = await _context.Metrics
|
var metrics = await _context.Metrics
|
||||||
.Where(m => m.Timestamp >= oneDayAgo && m.ServerId == serverId)
|
.Where(m => m.Timestamp >= startTime && m.ServerId == serverId)
|
||||||
.OrderBy(m => m.Timestamp)
|
.OrderBy(m => m.Timestamp)
|
||||||
.Select(m => new
|
|
||||||
{
|
|
||||||
label = m.Timestamp.ToUniversalTime().ToString("o"),
|
|
||||||
data = m.GPU_Load
|
|
||||||
})
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
// Timestamp-Format basierend auf Zeitbereich anpassen
|
||||||
|
string format = hours > 1 ? "dd.MM HH:mm" : "HH:mm";
|
||||||
|
var data = metrics.Select(m => new
|
||||||
|
{
|
||||||
|
label = m.Timestamp.ToLocalTime().ToString(format),
|
||||||
|
data = m.GPU_Load
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h6 class="mb-0"><i class="bi bi-graph-up me-1"></i>Metriken</h6>
|
||||||
|
<div class="btn-group btn-group-sm" role="group">
|
||||||
|
<button type="button" class="btn btn-outline-primary active" data-range="1">1 Stunde</button>
|
||||||
|
<button type="button" class="btn btn-outline-primary" data-range="24">24 Stunden</button>
|
||||||
|
<button type="button" class="btn btn-outline-primary" data-range="48">48 Stunden</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<h6><i class="bi bi-graph-up me-1"></i>CPU Last</h6>
|
<h6><i class="bi bi-graph-up me-1"></i>CPU Last</h6>
|
||||||
<div class="graphcontainer p-4 text-center text-muted">
|
<div class="graphcontainer p-4 text-center text-muted">
|
||||||
@@ -94,10 +105,13 @@
|
|||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'CPU Last (%)',
|
label: 'CPU Last (%)',
|
||||||
data: [],
|
data: [],
|
||||||
backgroundColor: 'rgba(255, 99, 132, 0.2)',
|
borderColor: 'rgba(54, 162, 235, 1)',
|
||||||
|
backgroundColor: 'rgba(54, 162, 235, 0.1)',
|
||||||
|
borderWidth: 2,
|
||||||
fill: true,
|
fill: true,
|
||||||
tension: 0.3,
|
tension: 0.4,
|
||||||
pointRadius: 3
|
pointRadius: 0,
|
||||||
|
pointHoverRadius: 4
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
@@ -110,14 +124,29 @@
|
|||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: 'Auslastung in %'
|
text: 'Auslastung in %'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(255, 255, 255, 0.1)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
x: {
|
x: {
|
||||||
title: {
|
title: {
|
||||||
display: false,
|
display: false,
|
||||||
text: 'Zeit'
|
text: 'Zeit'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(255, 255, 255, 0.1)'
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
maxTicksLimit: 12,
|
||||||
|
autoSkip: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -129,10 +158,13 @@
|
|||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'RAM Last (%)',
|
label: 'RAM Last (%)',
|
||||||
data: [],
|
data: [],
|
||||||
backgroundColor: 'rgba(255, 99, 132, 0.2)',
|
borderColor: 'rgba(75, 192, 192, 1)',
|
||||||
|
backgroundColor: 'rgba(75, 192, 192, 0.1)',
|
||||||
|
borderWidth: 2,
|
||||||
fill: true,
|
fill: true,
|
||||||
tension: 0.3,
|
tension: 0.4,
|
||||||
pointRadius: 3
|
pointRadius: 0,
|
||||||
|
pointHoverRadius: 4
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
@@ -145,14 +177,29 @@
|
|||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: 'Auslastung in %'
|
text: 'Auslastung in %'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(255, 255, 255, 0.1)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
x: {
|
x: {
|
||||||
title: {
|
title: {
|
||||||
display: false,
|
display: false,
|
||||||
text: 'Zeit'
|
text: 'Zeit'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(255, 255, 255, 0.1)'
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
maxTicksLimit: 12,
|
||||||
|
autoSkip: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -164,10 +211,13 @@
|
|||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'GPU Last (%)',
|
label: 'GPU Last (%)',
|
||||||
data: [],
|
data: [],
|
||||||
backgroundColor: 'rgba(255, 99, 132, 0.2)',
|
borderColor: 'rgba(153, 102, 255, 1)',
|
||||||
|
backgroundColor: 'rgba(153, 102, 255, 0.1)',
|
||||||
|
borderWidth: 2,
|
||||||
fill: true,
|
fill: true,
|
||||||
tension: 0.3,
|
tension: 0.4,
|
||||||
pointRadius: 3
|
pointRadius: 0,
|
||||||
|
pointHoverRadius: 4
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
@@ -180,21 +230,38 @@
|
|||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: 'Auslastung in %'
|
text: 'Auslastung in %'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(255, 255, 255, 0.1)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
x: {
|
x: {
|
||||||
title: {
|
title: {
|
||||||
display: false,
|
display: false,
|
||||||
text: 'Zeit'
|
text: 'Zeit'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(255, 255, 255, 0.1)'
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
maxTicksLimit: 12,
|
||||||
|
autoSkip: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let currentHours = 1; // Standard: 1 Stunde
|
||||||
|
|
||||||
async function loadCpuData() {
|
async function loadCpuData() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/monitoring/cpu-usage?serverId=@Model.Id');
|
const response = await fetch(`/monitoring/cpu-usage?serverId=@Model.Id&hours=${currentHours}`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP-Fehler: ${response.status}`);
|
throw new Error(`HTTP-Fehler: ${response.status}`);
|
||||||
}
|
}
|
||||||
@@ -217,7 +284,7 @@
|
|||||||
|
|
||||||
async function loadRamData() {
|
async function loadRamData() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/monitoring/ram-usage?serverId=@Model.Id');
|
const response = await fetch(`/monitoring/ram-usage?serverId=@Model.Id&hours=${currentHours}`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP-Fehler: ${response.status}`);
|
throw new Error(`HTTP-Fehler: ${response.status}`);
|
||||||
}
|
}
|
||||||
@@ -240,7 +307,7 @@
|
|||||||
|
|
||||||
async function loadGpuData() {
|
async function loadGpuData() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/monitoring/gpu-usage?serverId=@Model.Id');
|
const response = await fetch(`/monitoring/gpu-usage?serverId=@Model.Id&hours=${currentHours}`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP-Fehler: ${response.status}`);
|
throw new Error(`HTTP-Fehler: ${response.status}`);
|
||||||
}
|
}
|
||||||
@@ -261,6 +328,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Button-Handler für Zeitbereich-Wechsel
|
||||||
|
document.querySelectorAll('[data-range]').forEach(button => {
|
||||||
|
button.addEventListener('click', function() {
|
||||||
|
// Alle Buttons deaktivieren
|
||||||
|
document.querySelectorAll('[data-range]').forEach(btn => {
|
||||||
|
btn.classList.remove('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Aktuellen Button aktivieren
|
||||||
|
this.classList.add('active');
|
||||||
|
|
||||||
|
// Zeitbereich aktualisieren
|
||||||
|
currentHours = parseInt(this.getAttribute('data-range'));
|
||||||
|
|
||||||
|
// Daten neu laden
|
||||||
|
loadCpuData();
|
||||||
|
loadRamData();
|
||||||
|
loadGpuData();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Initiales Laden
|
// Initiales Laden
|
||||||
loadCpuData();
|
loadCpuData();
|
||||||
loadRamData();
|
loadRamData();
|
||||||
|
|||||||
Reference in New Issue
Block a user