бла бла бла

This commit is contained in:
2026-10-28 01:03:18 +01:00
parent 334abce357
commit 99185fa392
24 changed files with 1681 additions and 981 deletions
+1
View File
@@ -18,6 +18,7 @@ repositories {
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
testImplementation 'org.springframework.boot:spring-boot-starter-webflux-test'
@@ -1,9 +1,7 @@
package com.htopweb.system;
import com.htopweb.system.linux.LinuxDetailsResponse;
import com.htopweb.system.linux.LinuxDetailsService;
import com.htopweb.system.linux.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -15,12 +13,25 @@ public class SystemMetricsController {
private final SystemMetricsService _systemMetricsService;
private final LinuxDetailsService _linuxDetailsService;
private final CpuDetailsService _cpuDetailsService;
private final LinuxMemoryService _linuxMemoryService;
private final LinuxDiskService _linuxDiskService;
private final LinuxNetworkService _linuxNetworkService;
public SystemMetricsController(
SystemMetricsService systemMetricsService,
LinuxDetailsService linuxDetailsService
LinuxDetailsService linuxDetailsService,
CpuDetailsService cpuDetailsService,
LinuxMemoryService linuxMemoryService, LinuxDiskService linuxDiskService, LinuxNetworkService linuxNetworkService
) {
_systemMetricsService = systemMetricsService;
_linuxDetailsService = linuxDetailsService;
_cpuDetailsService = cpuDetailsService;
_linuxMemoryService = linuxMemoryService;
_linuxDiskService = linuxDiskService;
_linuxNetworkService = linuxNetworkService;
}
@GetMapping("/metrics")
@@ -32,4 +43,24 @@ public class SystemMetricsController {
public LinuxDetailsResponse getLinuxDetails() {
return _linuxDetailsService.getDetails();
}
@GetMapping("/cpu")
public CpuDetailsResponse getCpuDetails() {
return _cpuDetailsService.getDetails();
}
@GetMapping("/linux/memory")
public LinuxMemoryResponse getLinuxMemory() {
return _linuxMemoryService.getDetails();
}
@GetMapping("/linux/disks")
public java.util.List<LinuxDiskResponse> getLinuxDisks() {
return _linuxDiskService.getDisks();
}
@GetMapping("/linux/network")
public java.util.List<LinuxNetworkResponse> getLinuxNetwork() {
return _linuxNetworkService.getInterfaces();
}
}
@@ -0,0 +1,14 @@
package com.htopweb.system.linux;
import java.util.List;
public record CpuDetailsResponse(
double totalUsagePercent,
int logicalProcessors,
List<CpuCoreResponse> cores
) {
public record CpuCoreResponse(
int core,
double usagePercent
) {}
}
@@ -0,0 +1,68 @@
package com.htopweb.system.linux;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class CpuDetailsService {
private final CentralProcessor _processor;
private long[][] _previousCoreTicks;
private long[] _previousSystemTicks;
public CpuDetailsService() {
SystemInfo systemInfo = new SystemInfo();
_processor = systemInfo.getHardware().getProcessor();
_previousCoreTicks = _processor.getProcessorCpuLoadTicks();
_previousSystemTicks = _processor.getSystemCpuLoadTicks();
}
public synchronized CpuDetailsResponse getDetails() {
long[][] currentCoreTicks = _processor.getProcessorCpuLoadTicks();
long[] currentSystemTicks = _processor.getSystemCpuLoadTicks();
double[] coreLoads = _processor.getProcessorCpuLoadBetweenTicks(
_previousCoreTicks,
currentCoreTicks
);
double systemLoad = _processor.getSystemCpuLoadBetweenTicks(
_previousSystemTicks,
currentSystemTicks
);
_previousCoreTicks = currentCoreTicks;
_previousSystemTicks = currentSystemTicks;
List<CpuDetailsResponse.CpuCoreResponse> cores =
new ArrayList<>(coreLoads.length);
for (int i = 0; i < coreLoads.length; i++) {
cores.add(new CpuDetailsResponse.CpuCoreResponse(
i,
toPercent(coreLoads[i] * 100.0)
));
}
return new CpuDetailsResponse(
toPercent(systemLoad * 100.0),
_processor.getLogicalProcessorCount(),
List.copyOf(cores)
);
}
private double toPercent(double value) {
if (!Double.isFinite(value)) {
return 0.0;
}
return Math.round(
Math.max(0.0, Math.min(100.0, value)) * 10.0
) / 10.0;
}
}
@@ -0,0 +1,11 @@
package com.htopweb.system.linux;
public record LinuxDiskResponse(
String name,
String mountPoint,
String fileSystem,
long totalBytes,
long usableBytes,
long usedBytes,
double usagePercent
) {}
@@ -0,0 +1,54 @@
package com.htopweb.system.linux;
import oshi.SystemInfo;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import org.springframework.stereotype.Service;
import java.util.Comparator;
import java.util.List;
@Service
public class LinuxDiskService {
private final OperatingSystem _operatingSystem;
public LinuxDiskService() {
SystemInfo systemInfo = new SystemInfo();
_operatingSystem = systemInfo.getOperatingSystem();
}
public List<LinuxDiskResponse> getDisks() {
return _operatingSystem.getFileSystem()
.getFileStores()
.stream()
.filter(store -> store.getMount().startsWith("/"))
.filter(store -> store.getTotalSpace() > 0)
.map(this::toResponse)
.sorted(Comparator.comparing(LinuxDiskResponse::mountPoint))
.toList();
}
private LinuxDiskResponse toResponse(OSFileStore store) {
long total = Math.max(0L, store.getTotalSpace());
long usable = Math.max(
0L,
Math.min(total, store.getUsableSpace())
);
long used = Math.max(0L, total - usable);
double usage = total > 0
? Math.round((double) used / total * 1000.0) / 10.0
: 0.0;
return new LinuxDiskResponse(
store.getName(),
store.getMount(),
store.getType(),
total,
usable,
used,
usage
);
}
}
@@ -0,0 +1,12 @@
package com.htopweb.system.linux;
public record LinuxMemoryResponse(
long totalRamBytes,
long usedRamBytes,
long availableRamBytes,
double ramUsagePercent,
long totalSwapBytes,
long usedSwapBytes,
long freeSwapBytes,
double swapUsagePercent
) {}
@@ -0,0 +1,53 @@
package com.htopweb.system.linux;
import oshi.SystemInfo;
import oshi.hardware.GlobalMemory;
import oshi.hardware.VirtualMemory;
import org.springframework.stereotype.Service;
@Service
public class LinuxMemoryService {
private final GlobalMemory _memory;
private final VirtualMemory _virtualMemory;
public LinuxMemoryService() {
SystemInfo systemInfo = new SystemInfo();
_memory = systemInfo.getHardware().getMemory();
_virtualMemory = _memory.getVirtualMemory();
}
public LinuxMemoryResponse getDetails() {
long totalRam = Math.max(0L, _memory.getTotal());
long availableRam = Math.max(0L, Math.min(totalRam, _memory.getAvailable()));
long usedRam = Math.max(0L, totalRam - availableRam);
long totalSwap = Math.max(0L, _virtualMemory.getSwapTotal());
long usedSwap = Math.max(
0L,
Math.min(totalSwap, _virtualMemory.getSwapUsed())
);
long freeSwap = Math.max(0L, totalSwap - usedSwap);
return new LinuxMemoryResponse(
totalRam,
usedRam,
availableRam,
percentage(usedRam, totalRam),
totalSwap,
usedSwap,
freeSwap,
percentage(usedSwap, totalSwap)
);
}
private double percentage(long used, long total) {
if (total <= 0) {
return 0.0;
}
return Math.round((double) used / total * 1000.0) / 10.0;
}
}
@@ -0,0 +1,22 @@
package com.htopweb.system.linux;
import java.util.List;
public record LinuxNetworkResponse(
String name,
String displayName,
String macAddress,
List<String> ipv4Addresses,
List<String> ipv6Addresses,
long bytesReceived,
long bytesSent,
long packetsReceived,
long packetsSent,
long inboundErrors,
long outboundErrors,
double receiveBytesPerSecond,
double sendBytesPerSecond,
double receiveMbps,
double sendMbps
) {}
@@ -0,0 +1,93 @@
package com.htopweb.system.linux;
import oshi.SystemInfo;
import oshi.hardware.NetworkIF;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@Service
public class LinuxNetworkService {
private final SystemInfo _systemInfo;
private final ConcurrentMap<String, NetworkSnapshot> _previousSnapshots =
new ConcurrentHashMap<>();
public LinuxNetworkService() {
_systemInfo = new SystemInfo();
}
public List<LinuxNetworkResponse> getInterfaces() {
return _systemInfo.getHardware()
.getNetworkIFs()
.stream()
.map(this::toResponse)
.toList();
}
private LinuxNetworkResponse toResponse(NetworkIF networkIF) {
networkIF.updateAttributes();
String name = networkIF.getName();
long received = Math.max(0L, networkIF.getBytesRecv());
long sent = Math.max(0L, networkIF.getBytesSent());
long now = System.nanoTime();
NetworkSnapshot current = new NetworkSnapshot(received, sent, now);
NetworkSnapshot previous = _previousSnapshots.put(name, current);
double receiveBytesPerSecond = 0.0;
double sendBytesPerSecond = 0.0;
if (previous != null && now > previous.timestampNanos()) {
double elapsedSeconds =
(now - previous.timestampNanos()) / 1_000_000_000.0;
if (received >= previous.bytesReceived()) {
receiveBytesPerSecond =
(received - previous.bytesReceived()) / elapsedSeconds;
}
if (sent >= previous.bytesSent()) {
sendBytesPerSecond =
(sent - previous.bytesSent()) / elapsedSeconds;
}
}
double receiveMbps = receiveBytesPerSecond * 8.0 / 1_000_000.0;
double sendMbps = sendBytesPerSecond * 8.0 / 1_000_000.0;
return new LinuxNetworkResponse(
name,
networkIF.getDisplayName(),
networkIF.getMacaddr(),
Arrays.asList(networkIF.getIPv4addr()),
Arrays.asList(networkIF.getIPv6addr()),
received,
sent,
Math.max(0L, networkIF.getPacketsRecv()),
Math.max(0L, networkIF.getPacketsSent()),
Math.max(0L, networkIF.getInErrors()),
Math.max(0L, networkIF.getOutErrors()),
roundOne(receiveBytesPerSecond),
roundOne(sendBytesPerSecond),
roundOne(receiveMbps),
roundOne(sendMbps)
);
}
private double roundOne(double value) {
return Math.round(value * 10.0) / 10.0;
}
private record NetworkSnapshot(
long bytesReceived,
long bytesSent,
long timestampNanos
) {}
}
+1 -1
View File
@@ -9,5 +9,5 @@
<link rel="stylesheet" href="styles-5INURTSO.css"></head>
<body>
<app-root></app-root>
<script src="main-7OF6PXJ5.js" type="module"></script></body>
<script src="main-Y67327X6.js" type="module"></script></body>
</html>