bla bla bla
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
package com.htopweb;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import oshi.util.GlobalConfig;
|
||||
|
||||
@SpringBootApplication
|
||||
public class BackendApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
|
||||
if (System.getProperty("os.name").toLowerCase().contains("win")) {
|
||||
GlobalConfig.set(
|
||||
GlobalConfig.OSHI_OS_WINDOWS_CPU_UTILITY,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
SpringApplication.run(BackendApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.htopweb.system;
|
||||
|
||||
public record ProcessInfoResponse(
|
||||
int pid,
|
||||
String name,
|
||||
String state,
|
||||
double cpuUsagePercent,
|
||||
long residentMemoryBytes,
|
||||
long virtualMemoryBytes,
|
||||
long uptimeSeconds,
|
||||
int threadCount
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
package com.htopweb.system;
|
||||
|
||||
import com.htopweb.system.linux.LinuxDetailsResponse;
|
||||
import com.htopweb.system.linux.LinuxDetailsService;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/system")
|
||||
public class SystemMetricsController {
|
||||
|
||||
private final SystemMetricsService _systemMetricsService;
|
||||
private final LinuxDetailsService _linuxDetailsService;
|
||||
|
||||
public SystemMetricsController(
|
||||
SystemMetricsService systemMetricsService,
|
||||
LinuxDetailsService linuxDetailsService
|
||||
) {
|
||||
_systemMetricsService = systemMetricsService;
|
||||
_linuxDetailsService = linuxDetailsService;
|
||||
}
|
||||
|
||||
@GetMapping("/metrics")
|
||||
public SystemMetricsResponse getMetrics() {
|
||||
return _systemMetricsService.getMetrics();
|
||||
}
|
||||
|
||||
@GetMapping("/linux")
|
||||
public LinuxDetailsResponse getLinuxDetails() {
|
||||
return _linuxDetailsService.getDetails();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.htopweb.system;
|
||||
|
||||
public record SystemMetricsResponse(
|
||||
String operatingSystem,
|
||||
String osVersion,
|
||||
String hostname,
|
||||
String processor,
|
||||
int logicalProcessors,
|
||||
double cpuUsagePercent,
|
||||
long totalMemoryBytes,
|
||||
long availableMemoryBytes,
|
||||
long usedMemoryBytes,
|
||||
double memoryUsagePercent
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
|
||||
package com.htopweb.system;
|
||||
|
||||
import oshi.SystemInfo;
|
||||
import oshi.hardware.CentralProcessor;
|
||||
import oshi.hardware.GlobalMemory;
|
||||
import oshi.hardware.HardwareAbstractionLayer;
|
||||
import oshi.software.os.OperatingSystem;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SystemMetricsService {
|
||||
|
||||
private final SystemInfo _systemInfo;
|
||||
private final HardwareAbstractionLayer _hardware;
|
||||
private final OperatingSystem _operatingSystem;
|
||||
private final CentralProcessor _processor;
|
||||
private final GlobalMemory _memory;
|
||||
|
||||
private long[] _previousCpuTicks;
|
||||
|
||||
public SystemMetricsService() {
|
||||
_systemInfo = new SystemInfo();
|
||||
_hardware = _systemInfo.getHardware();
|
||||
_operatingSystem = _systemInfo.getOperatingSystem();
|
||||
_processor = _hardware.getProcessor();
|
||||
_memory = _hardware.getMemory();
|
||||
|
||||
_previousCpuTicks = _processor.getSystemCpuLoadTicks();
|
||||
}
|
||||
|
||||
public synchronized SystemMetricsResponse getMetrics() {
|
||||
long[] currentCpuTicks = _processor.getSystemCpuLoadTicks();
|
||||
|
||||
double cpuUsage = _processor.getSystemCpuLoadBetweenTicks(
|
||||
_previousCpuTicks,
|
||||
currentCpuTicks
|
||||
);
|
||||
|
||||
_previousCpuTicks = currentCpuTicks;
|
||||
|
||||
if (Double.isNaN(cpuUsage) || Double.isInfinite(cpuUsage)) {
|
||||
cpuUsage = 0.0;
|
||||
}
|
||||
|
||||
// Task Manager displays system CPU usage in the 0–100% range.
|
||||
cpuUsage = Math.max(0.0, Math.min(1.0, cpuUsage));
|
||||
|
||||
long totalMemory = _memory.getTotal();
|
||||
long availableMemory = _memory.getAvailable();
|
||||
long usedMemory = Math.max(0L, totalMemory - availableMemory);
|
||||
|
||||
double memoryUsage = totalMemory > 0
|
||||
? (double) usedMemory / totalMemory * 100.0
|
||||
: 0.0;
|
||||
|
||||
return new SystemMetricsResponse(
|
||||
_operatingSystem.getFamily(),
|
||||
_operatingSystem.getVersionInfo().getVersion(),
|
||||
_operatingSystem.getNetworkParams().getHostName(),
|
||||
_processor.getProcessorIdentifier().getName(),
|
||||
_processor.getLogicalProcessorCount(),
|
||||
round(cpuUsage * 100.0),
|
||||
totalMemory,
|
||||
availableMemory,
|
||||
usedMemory,
|
||||
round(memoryUsage)
|
||||
);
|
||||
}
|
||||
|
||||
private double round(double value) {
|
||||
return Math.round(value * 10.0) / 10.0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.htopweb.system;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/system")
|
||||
public class SystemProcessesController {
|
||||
|
||||
private final SystemProcessesService _systemProcessesService;
|
||||
|
||||
public SystemProcessesController(
|
||||
SystemProcessesService systemProcessesService
|
||||
) {
|
||||
_systemProcessesService = systemProcessesService;
|
||||
}
|
||||
|
||||
@GetMapping("/processes")
|
||||
public List<ProcessInfoResponse> getProcesses() {
|
||||
return _systemProcessesService.getProcesses();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
|
||||
package com.htopweb.system;
|
||||
|
||||
import oshi.SystemInfo;
|
||||
import oshi.software.os.OSProcess;
|
||||
import oshi.software.os.OperatingSystem;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class SystemProcessesService {
|
||||
|
||||
private final OperatingSystem _operatingSystem;
|
||||
private final int _logicalProcessorCount;
|
||||
|
||||
private final Map<Integer, OSProcess> _previousProcesses =
|
||||
new HashMap<>();
|
||||
|
||||
public SystemProcessesService() {
|
||||
SystemInfo systemInfo = new SystemInfo();
|
||||
|
||||
_operatingSystem = systemInfo.getOperatingSystem();
|
||||
_logicalProcessorCount = Math.max(
|
||||
1,
|
||||
systemInfo.getHardware()
|
||||
.getProcessor()
|
||||
.getLogicalProcessorCount()
|
||||
);
|
||||
}
|
||||
|
||||
public synchronized List<ProcessInfoResponse> getProcesses() {
|
||||
List<OSProcess> processes = _operatingSystem.getProcesses();
|
||||
Map<Integer, OSProcess> currentProcesses = new HashMap<>();
|
||||
|
||||
List<ProcessInfoResponse> result = processes.stream()
|
||||
.map(process -> {
|
||||
int pid = process.getProcessID();
|
||||
currentProcesses.put(pid, process);
|
||||
|
||||
OSProcess previous = _previousProcesses.get(pid);
|
||||
double cpuUsage = 0.0;
|
||||
|
||||
if (pid != 0
|
||||
&& previous != null
|
||||
&& previous.getStartTime() == process.getStartTime()) {
|
||||
|
||||
cpuUsage = process.getProcessCpuLoadBetweenTicks(previous)
|
||||
* 100.0 / _logicalProcessorCount;
|
||||
|
||||
cpuUsage = Math.max(0.0, Math.min(100.0, cpuUsage));
|
||||
}
|
||||
|
||||
return new ProcessInfoResponse(
|
||||
pid,
|
||||
process.getName(),
|
||||
process.getState().name(),
|
||||
Math.round(cpuUsage * 10.0) / 10.0,
|
||||
process.getResidentMemory(),
|
||||
process.getVirtualSize(),
|
||||
Math.max(
|
||||
0L,
|
||||
(System.currentTimeMillis()
|
||||
- process.getStartTime()) / 1000
|
||||
),
|
||||
process.getThreadCount()
|
||||
);
|
||||
})
|
||||
.sorted(
|
||||
Comparator.comparingDouble(
|
||||
ProcessInfoResponse::cpuUsagePercent
|
||||
).reversed()
|
||||
)
|
||||
.toList();
|
||||
|
||||
_previousProcesses.clear();
|
||||
_previousProcesses.putAll(currentProcesses);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
package com.htopweb.system.linux;
|
||||
|
||||
public record LinuxDetailsResponse(
|
||||
boolean linux,
|
||||
String hostname,
|
||||
String distribution,
|
||||
String kernelVersion,
|
||||
long uptimeSeconds,
|
||||
double loadAverage1Min,
|
||||
double loadAverage5Min,
|
||||
double loadAverage15Min,
|
||||
int logicalProcessors
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
package com.htopweb.system.linux;
|
||||
|
||||
import oshi.SystemInfo;
|
||||
import oshi.software.os.OperatingSystem;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@Service
|
||||
public class LinuxDetailsService {
|
||||
|
||||
private final OperatingSystem _operatingSystem;
|
||||
private final int _logicalProcessors;
|
||||
|
||||
private final oshi.hardware.CentralProcessor _processor;
|
||||
|
||||
public LinuxDetailsService() {
|
||||
SystemInfo systemInfo = new SystemInfo();
|
||||
|
||||
_operatingSystem = systemInfo.getOperatingSystem();
|
||||
_logicalProcessors = systemInfo.getHardware()
|
||||
.getProcessor()
|
||||
.getLogicalProcessorCount();
|
||||
_processor = systemInfo.getHardware().getProcessor();
|
||||
}
|
||||
|
||||
public LinuxDetailsResponse getDetails() {
|
||||
boolean linux = System.getProperty("os.name", "")
|
||||
.toLowerCase(Locale.ROOT)
|
||||
.contains("linux");
|
||||
|
||||
String hostname = _operatingSystem.getNetworkParams().getHostName();
|
||||
String distribution = _operatingSystem.getFamily();
|
||||
String kernelVersion = _operatingSystem.getVersionInfo().getVersion();
|
||||
|
||||
long uptimeSeconds = _operatingSystem.getSystemUptime();
|
||||
|
||||
double[] loadAverages = _processor.getSystemLoadAverage(3);
|
||||
|
||||
return new LinuxDetailsResponse(
|
||||
linux,
|
||||
hostname,
|
||||
distribution,
|
||||
kernelVersion,
|
||||
uptimeSeconds,
|
||||
safeLoad(loadAverages, 0),
|
||||
safeLoad(loadAverages, 1),
|
||||
safeLoad(loadAverages, 2),
|
||||
_logicalProcessors
|
||||
);
|
||||
}
|
||||
|
||||
private double safeLoad(double[] values, int index) {
|
||||
if (values == null || values.length <= index
|
||||
|| !Double.isFinite(values[index])
|
||||
|| values[index] < 0) {
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
return Math.round(values[index] * 100.0) / 100.0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user