Compare commits

..

2 Commits

Author SHA1 Message Date
b9514ba98e Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/main/java/dev/dinauer/monitoring/TopNodesService.java
#	src/main/java/dev/dinauer/monitoring/nodes/NodeMetrics.java
#	src/main/java/dev/dinauer/monitoring/nodes/client/NodeDiskService.java
2025-11-16 15:20:33 +01:00
adbba593e5 New Metrics 2025-11-16 15:19:54 +01:00
7 changed files with 85 additions and 7 deletions

View File

@ -23,7 +23,7 @@ public class MonitoringService
{
case LABEL ->
{
return podService.findByLabels(targetConfig.getNamespace(), targetConfig.getLabels()).stream().filter(pod -> pod.getStatus().getPhase().equals("Running")).toList();
return podService.findByNamespaceAndLabels(targetConfig.getNamespace(), targetConfig.getLabels()).stream().filter(pod -> pod.getStatus().getPhase().equals("Running")).toList();
}
case DEPLOYMENT, STATEFUL_SET ->
{

View File

@ -3,6 +3,8 @@ package dev.dinauer.monitoring;
import dev.dinauer.ProcessRunner;
import dev.dinauer.monitoring.nodes.MonitoredNode;
import dev.dinauer.monitoring.nodes.NodeMetrics;
import dev.dinauer.monitoring.nodes.client.NodeDiskMetrics;
import dev.dinauer.monitoring.nodes.client.NodeDiskService;
import dev.dinauer.service.PodService;
import dev.dinauer.utils.ClientProvider;
import io.fabric8.kubernetes.api.model.Node;
@ -24,12 +26,16 @@ public class TopNodesService
@Inject
PodService podService;
@Inject
NodeDiskService nodeDiskService;
public List<MonitoredNode> findAll()
{
List<MonitoredNode> result = new ArrayList<>();
List<String> stats = runTopNodesCommand();
Map<String, Integer> podsOnNodes = countPods();
Map<String, NodeDiskMetrics> nodeDiskMetrics = nodeDiskService.getDiskMetrics();
for(String nodeName : stats)
{
String[] parts = nodeName.split("\\s+");
@ -44,8 +50,17 @@ public class TopNodesService
Integer totalCpu = Integer.parseInt(node.getStatus().getAllocatable().get("cpu").getAmount()) * 1000;
Integer totalMemory = extractMemory(node.getStatus().getAllocatable().get("memory").getAmount());
Integer totalPods = podsOnNodes.get(node.getMetadata().getName());
NodeMetrics metrics = new NodeMetrics(absoluteCpu, relativeCpu, totalCpu, absoluteMemory, relativeMemory, totalMemory, totalPods, null, null);
result.add(new MonitoredNode(node, metrics));
NodeDiskMetrics diskMetrics = nodeDiskMetrics.get(node.getMetadata().getName());
if (diskMetrics != null)
{
NodeMetrics metrics = new NodeMetrics(absoluteCpu, relativeCpu, totalCpu, absoluteMemory, relativeMemory, totalMemory, totalPods, diskMetrics.relativeDiskUsage(), diskMetrics.totalDiskSpace());
result.add(new MonitoredNode(node, metrics));
}
else
{
NodeMetrics metrics = new NodeMetrics(absoluteCpu, relativeCpu, totalCpu, absoluteMemory, relativeMemory, totalMemory, totalPods, null, null);
result.add(new MonitoredNode(node, metrics));
}
}
}
return result;

View File

@ -1,5 +1,5 @@
package dev.dinauer.monitoring.nodes;
public record NodeMetrics(Integer absoluteCpuUsage, Integer relativeCpuUsage, Integer totalCpu, Integer absoluteMemory, Integer relativeMemory, Integer totalMemory, Integer runningPods, Integer relativeDiskUsage, Integer totalDiskSpace)
public record NodeMetrics(Integer absoluteCpuUsage, Integer relativeCpuUsage, Integer totalCpu, Integer absoluteMemory, Integer relativeMemory, Integer totalMemory, Integer runningPods, Integer relativeDiskUsage, Long totalDiskSpace)
{
}

View File

@ -0,0 +1,5 @@
package dev.dinauer.monitoring.nodes.client;
public record NodeDiskMetrics(Integer relativeDiskUsage, Long totalDiskSpace)
{
}

View File

@ -4,15 +4,69 @@ import dev.dinauer.service.PodService;
import io.fabric8.kubernetes.api.model.Pod;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.jboss.logging.Logger;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ApplicationScoped
public class NodeDiskService
{
private static final Map<String, String> label = Map.ofEntries(Map.entry("dev.dinauer.kubooboo/component", "node-monitor"));
private static final Integer PORT = 8080;
@Inject
Logger LOG;
@Inject
PodService podService;
public Map<String, NodeDiskMetrics> getDiskMetrics()
{
Map<String, NodeDiskMetrics> result = new HashMap<>();
List<Pod> pods = podService.findByLabels(label);
for (Pod pod : pods)
{
String nodeName = pod.getSpec().getNodeName();
String ip = pod.getStatus().getPodIP();
LOG.infof("Collect disk monitoring for node %s", nodeName);
try (HttpClient client = HttpClient.newBuilder().build())
{
HttpRequest request = HttpRequest.newBuilder().uri(new URI(String.format("http://%s:%s", ip, PORT))).GET().build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
NodeDiskMetrics metrics = parse(response.body());
result.put(nodeName, metrics);
}
catch (URISyntaxException | IOException | InterruptedException e)
{
LOG.errorf("Failed to collect disk monitoring for node %s", nodeName);
}
}
return result;
}
private NodeDiskMetrics parse(String input)
{
Map<String, String> result = new HashMap<>();
for (String line : input.split("\\s+"))
{
String[] sections = line.split(":");
if (sections.length == 2)
{
result.put(sections[0], sections[1]);
}
else
{
LOG.errorf("Cannot parse metrics line '%s'", line);
}
}
return new NodeDiskMetrics(Integer.parseInt(result.get("percentage_used")), Long.parseLong(result.get("total-space")));
}
}

View File

@ -2,7 +2,6 @@ package dev.dinauer.service;
import dev.dinauer.monitoring.TopNodesService;
import dev.dinauer.monitoring.nodes.MonitoredNode;
import io.fabric8.kubernetes.api.model.Node;
import io.fabric8.kubernetes.client.Watch;
import io.fabric8.kubernetes.client.Watcher;
import jakarta.enterprise.context.ApplicationScoped;

View File

@ -57,17 +57,22 @@ public class PodService implements ResourceService<Pod>
StatefulSet set = apps.statefulSets().inNamespace(namespace).withName(name).get();
if (set != null)
{
return findByLabels(namespace, set.getSpec().getSelector().getMatchLabels());
return findByNamespaceAndLabels(namespace, set.getSpec().getSelector().getMatchLabels());
}
return null;
}
}
public List<Pod> findByLabels(String namespace, Map<String, String> labels)
public List<Pod> findByNamespaceAndLabels(String namespace, Map<String, String> labels)
{
return clientProvider.getClient().pods().inNamespace(namespace).withLabels(labels).list().getItems();
}
public List<Pod> findByLabels(Map<String, String> labels)
{
return clientProvider.getClient().pods().inAnyNamespace().withLabels(labels).list().getItems();
}
public List<Pod> findAll()
{
return clientProvider.getClient().pods().inAnyNamespace().list().getItems();