feat: 新增终端顶部实时服务器监控面板

This commit is contained in:
liumangmang
2026-03-30 16:54:56 +08:00
parent ba1acdc2dd
commit 832d55c722
3 changed files with 370 additions and 57 deletions

View File

@@ -0,0 +1,139 @@
package com.sshmanager.controller;
import com.sshmanager.entity.Connection;
import com.sshmanager.entity.User;
import com.sshmanager.repository.UserRepository;
import com.sshmanager.service.ConnectionService;
import com.sshmanager.service.SshService;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/monitor")
public class MonitorController {
private final ConnectionService connectionService;
private final SshService sshService;
private final UserRepository userRepository;
public MonitorController(ConnectionService connectionService, SshService sshService, UserRepository userRepository) {
this.connectionService = connectionService;
this.sshService = sshService;
this.userRepository = userRepository;
}
private Long getCurrentUserId(Authentication auth) {
User user = userRepository.findByUsername(auth.getName()).orElseThrow(() -> new IllegalStateException("User not found"));
return user.getId();
}
@GetMapping("/{connectionId}")
public ResponseEntity<Map<String, Object>> getServerMetrics(@PathVariable Long connectionId, Authentication authentication) {
try {
Long userId = getCurrentUserId(authentication);
Connection conn = connectionService.getConnectionForSsh(connectionId, userId);
if (conn == null) {
return ResponseEntity.notFound().build();
}
String password = connectionService.getDecryptedPassword(conn);
String privateKey = connectionService.getDecryptedPrivateKey(conn);
String passphrase = connectionService.getDecryptedPassphrase(conn);
Map<String, Object> metrics = new HashMap<>();
// 获取CPU使用率
try {
String cpuOutput = sshService.executeCommand(conn, password, privateKey, passphrase,
"top -bn1 | grep 'Cpu(s)' | sed 's/.*, *\\([0-9.]*\\)%* id.*/\\1/' | awk '{print 100 - $1}'");
double cpuUsage = Double.parseDouble(cpuOutput.trim());
metrics.put("cpuUsage", Math.round(cpuUsage * 10.0) / 10.0);
} catch (Exception e) {
metrics.put("cpuUsage", null);
}
// 获取内存信息
try {
String memOutput = sshService.executeCommand(conn, password, privateKey, passphrase,
"free -b | grep Mem");
String[] memParts = memOutput.trim().split("\\s+");
long totalMem = Long.parseLong(memParts[1]);
long usedMem = Long.parseLong(memParts[2]);
double memUsage = (double) usedMem / totalMem * 100;
metrics.put("memTotal", totalMem);
metrics.put("memUsed", usedMem);
metrics.put("memUsage", Math.round(memUsage * 10.0) / 10.0);
} catch (Exception e) {
metrics.put("memTotal", null);
metrics.put("memUsed", null);
metrics.put("memUsage", null);
}
// 获取磁盘使用率
try {
String diskOutput = sshService.executeCommand(conn, password, privateKey, passphrase,
"df -P / | tail -1");
String[] diskParts = diskOutput.trim().split("\\s+");
int diskUsage = Integer.parseInt(diskParts[4].replace("%", ""));
metrics.put("diskUsage", diskUsage);
} catch (Exception e) {
metrics.put("diskUsage", null);
}
// 获取系统负载
try {
String loadOutput = sshService.executeCommand(conn, password, privateKey, passphrase,
"cat /proc/loadavg");
String[] loadParts = loadOutput.trim().split("\\s+");
double load1 = Double.parseDouble(loadParts[0]);
metrics.put("load1", load1);
} catch (Exception e) {
metrics.put("load1", null);
}
// 获取CPU核数
try {
String cpuCountOutput = sshService.executeCommand(conn, password, privateKey, passphrase,
"grep -c ^processor /proc/cpuinfo");
int cpuCores = Integer.parseInt(cpuCountOutput.trim());
metrics.put("cpuCores", cpuCores);
} catch (Exception e) {
metrics.put("cpuCores", null);
}
// 获取系统运行时间
try {
String uptimeOutput = sshService.executeCommand(conn, password, privateKey, passphrase,
"uptime -p");
metrics.put("uptime", uptimeOutput.trim().replace("up ", ""));
} catch (Exception e) {
// 尝试另一种uptime格式
try {
String uptimeOutput = sshService.executeCommand(conn, password, privateKey, passphrase,
"cat /proc/uptime | awk '{print $1}'");
double uptimeSeconds = Double.parseDouble(uptimeOutput.trim());
long days = (long) (uptimeSeconds / 86400);
long hours = (long) ((uptimeSeconds % 86400) / 3600);
long minutes = (long) ((uptimeSeconds % 3600) / 60);
StringBuilder uptimeStr = new StringBuilder();
if (days > 0) uptimeStr.append(days).append("d ");
if (hours > 0) uptimeStr.append(hours).append("h ");
uptimeStr.append(minutes).append("m");
metrics.put("uptime", uptimeStr.toString().trim());
} catch (Exception e2) {
metrics.put("uptime", null);
}
}
return ResponseEntity.ok(metrics);
} catch (Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("error", e.getMessage());
return ResponseEntity.badRequest().body(error);
}
}
}