backend/src/main/java/dev/dinauer/monitoring/TopNodesService.java

110 lines
3.8 KiB
Java

package dev.dinauer.monitoring;
import java.util.*;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import io.fabric8.kubernetes.api.model.Node;
import io.fabric8.kubernetes.api.model.Pod;
import dev.dinauer.utils.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;
@ApplicationScoped
public class TopNodesService
{
@Inject
ClientProvider clientProvider;
@Inject
ProcessRunner processRunner;
@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+");
if (parts.length == 5)
{
String name = parts[0];
Node node = clientProvider.getClient().nodes().withName(name).get();
Integer absoluteCpu = extractInteger(parts[1]);
Integer relativeCpu = extractInteger(parts[2]);
Integer absoluteMemory = extractMemory(parts[3]);
Integer relativeMemory = extractInteger(parts[4]);
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());
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;
}
private Map<String, Integer> countPods()
{
List<Pod> pods = podService.findAll();
Map<String, Integer> result = new HashMap<>();
for (Pod pod : pods)
{
String nodeName = pod.getSpec().getNodeName();
result.put(nodeName, Optional.ofNullable(result.get(nodeName)).orElse(0) + 1);
}
return result;
}
private List<String> runTopNodesCommand()
{
return processRunner.runToLines("kubectl top nodes --no-headers");
}
private Integer extractInteger(String input)
{
return Integer.valueOf(input.replace("m", "").replace("%", ""));
}
private Integer extractMemory(String input)
{
if (input.contains("Ki"))
{
return Integer.parseInt(input.replace("Ki", ""));
}
if (input.contains("Mi"))
{
return Integer.parseInt(input.replace("Mi", "")) * 1024;
}
if (input.contains("Gi"))
{
return Integer.parseInt(input.replace("Gi", "")) * 1024 * 1024;
}
return Integer.parseInt(input);
}
}