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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
spring:
|
||||
application:
|
||||
name: backend
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en" data-beasties-container>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Frontend</title>
|
||||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link rel="stylesheet" href="styles-5INURTSO.css"></head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
<script src="main-7OF6PXJ5.js" type="module"></script></body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user