From 5dc221199ea4f13739207b5cb213837703470864 Mon Sep 17 00:00:00 2001
From: gaoxq <376340421@qq.com>
Date: Sat, 10 Jan 2026 23:38:38 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=9F=A5=E7=9C=8B=E9=A1=B5?=
=?UTF-8?q?=E9=9D=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
common/pom.xml | 16 +-
.../jeesite/modules/app/Job/biz/hostJob.java | 64 +++---
.../java/com/jeesite/modules/app/Test.java | 10 +-
.../jeesite/modules/app/utils/AesUtil.java | 109 +++++++++++
.../modules/app/utils/MyFileUtils.java | 2 +
.../jeesite/modules/app/utils/MyUtils.java | 4 +
.../jeesite/modules/app/utils/SystemUtil.java | 184 ++++++++++--------
.../jeesite/modules/app/utils/sftpUtils.java | 81 ++++++++
.../com/jeesite/modules/app/utils/vo.java | 41 ----
.../biz/web/BizMonitorAccountController.java | 7 +-
10 files changed, 363 insertions(+), 155 deletions(-)
create mode 100644 web-api/src/main/java/com/jeesite/modules/app/utils/AesUtil.java
create mode 100644 web-api/src/main/java/com/jeesite/modules/app/utils/sftpUtils.java
delete mode 100644 web-api/src/main/java/com/jeesite/modules/app/utils/vo.java
diff --git a/common/pom.xml b/common/pom.xml
index 29df84a2..b95774d4 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -29,7 +29,7 @@
cn.hutool
hutool-all
- 5.8.16
+ 5.8.42
@@ -41,7 +41,19 @@
commons-net
commons-net
- 3.11.0
+ 3.11.0
+
+
+
+ org.apache.poi
+ poi
+ 5.4.1
+
+
+
+ org.apache.poi
+ poi-ooxml
+ 5.4.1
diff --git a/web-api/src/main/java/com/jeesite/modules/app/Job/biz/hostJob.java b/web-api/src/main/java/com/jeesite/modules/app/Job/biz/hostJob.java
index 35932d77..5532125a 100644
--- a/web-api/src/main/java/com/jeesite/modules/app/Job/biz/hostJob.java
+++ b/web-api/src/main/java/com/jeesite/modules/app/Job/biz/hostJob.java
@@ -1,5 +1,6 @@
package com.jeesite.modules.app.Job.biz;
+import com.jcraft.jsch.Session;
import com.jeesite.common.config.Global;
import com.jeesite.modules.app.dao.info.CpuInfo;
import com.jeesite.modules.app.dao.info.DiskInfo;
@@ -81,41 +82,46 @@ public class hostJob {
public void syncServerInfo(BizMonitorHost host) {
BizMonitorAccount monitorAccount = new BizMonitorAccount();
monitorAccount.setHostId(host.getHostId());
+ monitorAccount.setUstatus("1");
monitorAccount.setSshUsername("ogsapp");
List accountList = accountService.findList(monitorAccount);
if (accountList.size() > 0) {
try {
BizMonitorAccount account = accountList.get(0);
- CpuInfo cpuInfo = SystemUtil.getCpuMemUsage(host.getIpAddress(), account.getSshPort(), account.getSshUsername(), vo.getDecode(account.getSshPassword()));
- ServerInfo info = SystemUtil.getServerBasicInfo(host.getIpAddress(), account.getSshPort(), account.getSshUsername(), vo.getDecode(account.getSshPassword()), host.getIpAddress());
- List diskInfos = SystemUtil.getDiskInfos(host.getIpAddress(), account.getSshPort(), account.getSshUsername(), vo.getDecode(account.getSshPassword()));
- syncDeviceInfo(host, diskInfos);
- BizServerInfo bizServerInfo = new BizServerInfo();
- bizServerInfo.setHostId(host.getHostId());
- List serverInfoList = serverInfoService.findList(bizServerInfo);
- BizServerInfo serverInfo = serverInfoList.isEmpty() ? new BizServerInfo() : serverInfoList.get(0);
- serverInfo.setUptime(info.getUptime());
- serverInfo.setOs(info.getOs());
- serverInfo.setKernelVersion(info.getKernelVersion());
- serverInfo.setHostname(info.getHostname());
- serverInfo.setIpAddress(info.getIpAddress());
- serverInfo.setCpuModel(info.getCpuModel());
- serverInfo.setMemoryTotal(info.getMemoryTotal());
- serverInfo.setCpuUsage(cpuInfo.getCpuUsage());
- serverInfo.setMemoryUsage(cpuInfo.getMemoryUsage());
- serverInfo.setLastOnlineTime(new Date());
- serverInfo.setHostId(host.getHostId());
- serverInfoService.save(serverInfo);
- if (serverInfo.getCpuUsage() >= CPU_RATE) {
- BizWarningAlert warningAlert = new BizWarningAlert("ZJ_" + KeyUtil.ObjKey(12, 2), "CPU预警", 2, serverInfo.getHostname() + "CPU预警", "当前主机CPU已超过" + CPU_RATE + "%,请及时处理,主机IP:" + serverInfo.getIpAddress(), "业务系统", "0");
- bizWarningAlertService.save(warningAlert);
- }
- if (serverInfo.getMemoryUsage() >= MEM_RATE) {
- BizWarningAlert warningAlert = new BizWarningAlert("ZJ_" + KeyUtil.ObjKey(12, 2), "内存预警", 2, serverInfo.getHostname() + "内存预警", "当前主机内存已超过" + MEM_RATE + "%,请及时处理,主机IP:" + serverInfo.getIpAddress(), "业务系统", "0");
- bizWarningAlertService.save(warningAlert);
+ Session session = SystemUtil.getSshSession(account);
+ if (session.isConnected()) {
+ CpuInfo cpuInfo = SystemUtil.getCpuMemUsage(session);
+ ServerInfo info = SystemUtil.getServerBasicInfo(session);
+ List diskInfos = SystemUtil.getDiskInfos(session);
+ syncDeviceInfo(host, diskInfos);
+ BizServerInfo bizServerInfo = new BizServerInfo();
+ bizServerInfo.setHostId(host.getHostId());
+ List serverInfoList = serverInfoService.findList(bizServerInfo);
+ BizServerInfo serverInfo = serverInfoList.isEmpty() ? new BizServerInfo() : serverInfoList.get(0);
+ serverInfo.setUptime(info.getUptime());
+ serverInfo.setOs(info.getOs());
+ serverInfo.setKernelVersion(info.getKernelVersion());
+ serverInfo.setHostname(info.getHostname());
+ serverInfo.setIpAddress(info.getIpAddress());
+ serverInfo.setCpuModel(info.getCpuModel());
+ serverInfo.setMemoryTotal(info.getMemoryTotal());
+ serverInfo.setCpuUsage(cpuInfo.getCpuUsage());
+ serverInfo.setMemoryUsage(cpuInfo.getMemoryUsage());
+ serverInfo.setLastOnlineTime(new Date());
+ serverInfo.setHostId(host.getHostId());
+ serverInfoService.save(serverInfo);
+ if (serverInfo.getCpuUsage() >= CPU_RATE) {
+ BizWarningAlert warningAlert = new BizWarningAlert("ZJ_" + KeyUtil.ObjKey(12, 2), "CPU预警", 2, serverInfo.getHostname() + "CPU预警", "当前主机CPU已超过" + CPU_RATE + "%,请及时处理,主机IP:" + serverInfo.getIpAddress(), "业务系统", "0");
+ bizWarningAlertService.save(warningAlert);
+ }
+ if (serverInfo.getMemoryUsage() >= MEM_RATE) {
+ BizWarningAlert warningAlert = new BizWarningAlert("ZJ_" + KeyUtil.ObjKey(12, 2), "内存预警", 2, serverInfo.getHostname() + "内存预警", "当前主机内存已超过" + MEM_RATE + "%,请及时处理,主机IP:" + serverInfo.getIpAddress(), "业务系统", "0");
+ bizWarningAlertService.save(warningAlert);
+ }
+ SystemUtil.closeSession(session);
}
} catch (Exception e) {
- logger.error(e.getMessage());
+ logger.error(e.getMessage(), host);
}
}
}
@@ -145,7 +151,7 @@ public class hostJob {
bizWarningAlertService.save(warningAlert);
}
} catch (Exception e) {
- logger.error(e.getMessage());
+ logger.error(e.getMessage(), host);
}
}
}
diff --git a/web-api/src/main/java/com/jeesite/modules/app/Test.java b/web-api/src/main/java/com/jeesite/modules/app/Test.java
index ba1d3141..b69d92d9 100644
--- a/web-api/src/main/java/com/jeesite/modules/app/Test.java
+++ b/web-api/src/main/java/com/jeesite/modules/app/Test.java
@@ -1,8 +1,16 @@
package com.jeesite.modules.app;
+import com.jeesite.modules.app.utils.SystemUtil;
+
+import com.jcraft.jsch.Session;
+
public class Test {
- public static void main(String[] args) {
+ public static void main(String[] args) throws Exception {
+
+// Session session = SystemUtil.getSshSession("192.168.31.182", 22, "ogsapp", "WIjYVp3bSNaJ7gK9n9jk7Q==");
+//
+// System.out.println(SystemUtil.getServerBasicInfo(session));
}
}
diff --git a/web-api/src/main/java/com/jeesite/modules/app/utils/AesUtil.java b/web-api/src/main/java/com/jeesite/modules/app/utils/AesUtil.java
new file mode 100644
index 00000000..789dadda
--- /dev/null
+++ b/web-api/src/main/java/com/jeesite/modules/app/utils/AesUtil.java
@@ -0,0 +1,109 @@
+package com.jeesite.modules.app.utils;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.Arrays;
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * AES加密解密工具类(CBC/PKCS5Padding)
+ * 优化说明:修复密钥BUG+解决换行问题+性能优化+安全加固+零依赖
+ */
+public class AesUtil {
+
+
+ private static final LoggerUtils logger = LoggerUtils.getInstance();
+ private static final String AES_KEY_HEX = "AD42F6697B035B7580E4FEF93BE20BAD"; // 你的32位16进制密钥
+ private static final String CHARSET = StandardCharsets.UTF_8.name();
+ private static final int IV_LENGTH = 16; // AES CBC IV固定16字节
+ private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
+ private static final String ALGORITHM = "AES";
+
+ private static final ThreadLocal ENCRYPT_CIPHER = ThreadLocal.withInitial(() -> {
+ try {
+ return Cipher.getInstance(TRANSFORMATION);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ private static final ThreadLocal DECRYPT_CIPHER = ThreadLocal.withInitial(() -> {
+ try {
+ return Cipher.getInstance(TRANSFORMATION);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ /**
+ * 加密
+ */
+ public static String encrypt(String content) {
+ return encrypt(content, hex2Bytes(AES_KEY_HEX));
+ }
+
+ /**
+ * 解密
+ */
+ public static String decrypt(String content) {
+ return decrypt(content, hex2Bytes(AES_KEY_HEX));
+ }
+
+ public static String encrypt(String content, byte[] key) {
+ if (content == null || content.isEmpty()) {
+ return "";
+ }
+ try {
+ SecretKeySpec secretKey = new SecretKeySpec(key, ALGORITHM);
+ IvParameterSpec iv = new IvParameterSpec(Arrays.copyOf(key, IV_LENGTH));
+ Cipher cipher = ENCRYPT_CIPHER.get();
+ cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
+ byte[] encryptBytes = cipher.doFinal(content.getBytes(CHARSET));
+ return Base64.getEncoder().encodeToString(encryptBytes);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String decrypt(String content, byte[] key) {
+ if (content == null || content.isEmpty()) {
+ return "";
+ }
+ try {
+ SecretKeySpec secretKey = new SecretKeySpec(key, ALGORITHM);
+ IvParameterSpec iv = new IvParameterSpec(Arrays.copyOf(key, IV_LENGTH));
+ Cipher cipher = DECRYPT_CIPHER.get();
+ cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
+ byte[] decryptBytes = cipher.doFinal(Base64.getDecoder().decode(content));
+ String result = new String(decryptBytes, CHARSET);
+ return result.trim();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 32位16进制字符串转16字节数组(解决你的密钥长度BUG的核心方法)
+ */
+ private static byte[] hex2Bytes(String hexStr) {
+ if (hexStr == null || hexStr.length() % 2 != 0) {
+ throw new IllegalArgumentException("密钥必须是偶数长度的16进制字符串");
+ }
+ byte[] bytes = new byte[hexStr.length() / 2];
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = (byte) Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2), 16);
+ }
+ return bytes;
+ }
+
+ /**
+ * 生成随机16字节IV向量(方案2:安全随机IV,新业务推荐使用)
+ */
+ private static byte[] generateRandomIV() {
+ byte[] iv = new byte[IV_LENGTH];
+ ThreadLocalRandom.current().nextBytes(iv);
+ return iv;
+ }
+}
\ No newline at end of file
diff --git a/web-api/src/main/java/com/jeesite/modules/app/utils/MyFileUtils.java b/web-api/src/main/java/com/jeesite/modules/app/utils/MyFileUtils.java
index be593e6f..d85887ac 100644
--- a/web-api/src/main/java/com/jeesite/modules/app/utils/MyFileUtils.java
+++ b/web-api/src/main/java/com/jeesite/modules/app/utils/MyFileUtils.java
@@ -1,5 +1,7 @@
package com.jeesite.modules.app.utils;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
diff --git a/web-api/src/main/java/com/jeesite/modules/app/utils/MyUtils.java b/web-api/src/main/java/com/jeesite/modules/app/utils/MyUtils.java
index 76c23679..fcca792e 100644
--- a/web-api/src/main/java/com/jeesite/modules/app/utils/MyUtils.java
+++ b/web-api/src/main/java/com/jeesite/modules/app/utils/MyUtils.java
@@ -19,6 +19,10 @@ public class MyUtils {
return sb.toString();
}
+ public static String getPath(String... paths) {
+ return String.join("/", paths);
+ }
+
public static Map convertToTreeNode(BizFolders folder, String parentName) {
Map node = new HashMap<>();
diff --git a/web-api/src/main/java/com/jeesite/modules/app/utils/SystemUtil.java b/web-api/src/main/java/com/jeesite/modules/app/utils/SystemUtil.java
index 42173705..c97d799a 100644
--- a/web-api/src/main/java/com/jeesite/modules/app/utils/SystemUtil.java
+++ b/web-api/src/main/java/com/jeesite/modules/app/utils/SystemUtil.java
@@ -1,12 +1,12 @@
package com.jeesite.modules.app.utils;
-
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jeesite.modules.app.dao.info.CpuInfo;
import com.jeesite.modules.app.dao.info.DiskInfo;
import com.jeesite.modules.app.dao.info.ServerInfo;
+import com.jeesite.modules.biz.entity.BizMonitorAccount;
import org.springframework.util.StringUtils;
import java.io.BufferedReader;
@@ -15,167 +15,195 @@ import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;
-
+/**
+ * 服务器系统信息采集工具类(SSH方式)
+ * 最终优化版:解决Session复用问题,调用方统一管理会话生命周期,杜绝重复关闭
+ */
public class SystemUtil {
-
- // SSH 连接超时时间(毫秒)
- private static final int SSH_TIMEOUT = 5000;
-
+ // CPU使用率默认值
+ private static final double DEFAULT_USAGE = 0.0;
+ private static final List FILTER_FILE_SYSTEM = Arrays.asList("dev");
/**
* 建立SSH连接
*/
- private static Session getSshSession(String host, int port, String username, String password) throws Exception {
- JSch jsch = new JSch();
- Session session = jsch.getSession(username, host, port);
- session.setPassword(password);
-
- Properties config = new Properties();
- config.put("StrictHostKeyChecking", "no");
- session.setConfig(config);
-
- session.setTimeout(SSH_TIMEOUT);
- session.connect();
+ public static Session getSshSession(BizMonitorAccount account) {
+ Session session = null;
+ try {
+ String passwd = AesUtil.decrypt(account.getSshPassword());
+ JSch jsch = new JSch();
+ session = jsch.getSession(account.getSshUsername(), account.getIpAddress(), account.getSshPort());
+ session.setPassword(passwd);
+ Properties config = new Properties();
+ config.put("StrictHostKeyChecking", "no");
+ session.setConfig(config);
+ session.setTimeout(account.getTimeoutSeconds());
+ session.connect();
+ } catch (Exception e) {
+ System.out.println(e);
+ }
return session;
}
+ // ======================== 统一的资源关闭工具方法 ========================
+
/**
- * 执行SSH命令并返回结果
+ * 安全关闭SSH通道,空指针安全+异常捕获
*/
- private static String executeCommand(Session session, String command) throws Exception {
- ChannelExec channel = (ChannelExec) session.openChannel("exec");
- channel.setCommand(command);
-
- InputStream in = channel.getInputStream();
- channel.connect();
-
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(in, StandardCharsets.UTF_8)
- );
- StringBuilder result = new StringBuilder();
- String line;
- while ((line = reader.readLine()) != null) {
- result.append(line).append("\n");
+ private static void closeChannel(ChannelExec channel) {
+ if (channel != null && channel.isConnected()) {
+ try {
+ channel.disconnect();
+ } catch (Exception e) {
+ System.out.println(e);
+ }
}
-
- reader.close();
- channel.disconnect();
- return result.toString().trim();
}
+ /**
+ * 安全关闭SSH会话,空指针安全+异常捕获
+ * 【核心】仅提供给调用方,在所有业务查询完成后统一调用!
+ */
+ public static void closeSession(Session session) {
+ if (session != null && session.isConnected()) {
+ try {
+ session.disconnect();
+ } catch (Exception e) {
+ System.out.println(e);
+ }
+ }
+ }
+
+ /**
+ * 执行SSH命令并返回结果(核心优化,资源闭环+异常安全)
+ */
+ private static String executeCommand(Session session, String command) throws Exception {
+ if (session == null || !session.isConnected() || !StringUtils.hasText(command)) {
+ return "";
+ }
+ ChannelExec channel = null;
+ try {
+ channel = (ChannelExec) session.openChannel("exec");
+ channel.setCommand(command);
+ try (InputStream in = channel.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
+ channel.connect();
+ StringBuilder result = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ result.append(line).append("\n");
+ }
+ return result.toString().trim();
+ }
+ } finally {
+ // 只关闭通道,不关闭会话
+ closeChannel(channel);
+ }
+ }
/**
* 获取服务器基础信息
+ * ✅ 关键修改:移除finally中的closeSession(session),不再关闭会话
*/
- public static ServerInfo getServerBasicInfo(String host, int port, String username, String password, String ipAddress) throws Exception {
+ public static ServerInfo getServerBasicInfo(Session session) {
ServerInfo info = new ServerInfo();
- Session session = null;
try {
- session = getSshSession(host, port, username, password);
-
// 主机运行时间
String uptimeResult = executeCommand(session, "uptime");
if (StringUtils.hasText(uptimeResult)) {
String[] parts = uptimeResult.split("up ");
if (parts.length > 1) {
- info.setUptime(parts[1].split(", ")[0]);
+ String uptime = parts[1].split(",")[0];
+ info.setUptime(uptime);
}
}
-
// 操作系统
String osResult = executeCommand(session, "cat /etc/os-release | grep PRETTY_NAME | cut -d'=' -f2 | tr -d '\"'");
- info.setOs(osResult.isEmpty() ? "Unknown" : osResult);
-
+ info.setOs(StringUtils.hasText(osResult) ? osResult : "Unknown");
// 内核版本
info.setKernelVersion(executeCommand(session, "uname -r"));
-
// 主机名
info.setHostname(executeCommand(session, "hostname"));
-
// IP地址(传入参数)
- info.setIpAddress(ipAddress);
-
+ info.setIpAddress(session.getHost());
// CPU型号
String cpuResult = executeCommand(session, "cat /proc/cpuinfo | grep 'model name' | head -n 1 | cut -d: -f2 | sed -e 's/^ *//'");
- info.setCpuModel(cpuResult.isEmpty() ? "Unknown" : cpuResult);
-
+ info.setCpuModel(StringUtils.hasText(cpuResult) ? cpuResult : "Unknown");
// 内存总量
String memResult = executeCommand(session, "free -h | grep Mem | awk '{print $2}'");
- info.setMemoryTotal(memResult.isEmpty() ? "Unknown" : memResult);
-
- } finally {
- if (session != null && session.isConnected()) {
- session.disconnect();
- }
+ info.setMemoryTotal(StringUtils.hasText(memResult) ? memResult : "Unknown");
+ } catch (Exception e) {
+ System.out.println(e);
}
return info;
}
/**
* 获取CPU和内存使用率
+ * ✅ 关键修改:移除finally中的closeSession(session),不再关闭会话
*/
- public static CpuInfo getCpuMemUsage(String host, int port, String username, String password) throws Exception {
+ public static CpuInfo getCpuMemUsage(Session session) {
CpuInfo usage = new CpuInfo();
- Session session = null;
try {
- session = getSshSession(host, port, username, password);
-
// CPU使用率
String cpuCommand = "top -bn2 | grep '%Cpu' | tail -n1 | awk '{print 100 - $8}'";
String cpuResult = executeCommand(session, cpuCommand);
if (StringUtils.hasText(cpuResult)) {
usage.setCpuUsage(Double.parseDouble(cpuResult));
+ } else {
+ usage.setCpuUsage(DEFAULT_USAGE);
}
// 内存使用率
String memCommand = "free | grep Mem | awk '{print $3/$2 * 100}'";
String memResult = executeCommand(session, memCommand);
if (StringUtils.hasText(memResult)) {
usage.setMemoryUsage(Double.parseDouble(memResult));
+ } else {
+ usage.setMemoryUsage(DEFAULT_USAGE);
}
-
- } finally {
- if (session != null && session.isConnected()) {
- session.disconnect();
- }
+ } catch (Exception e) {
+ System.out.println(e);
}
return usage;
}
/**
* 获取所有磁盘信息
+ * ✅ 关键修改:移除finally中的closeSession(session),不再关闭会话
*/
- public static List getDiskInfos(String host, int port, String username, String password) throws Exception {
+ public static List getDiskInfos(Session session) {
List diskInfos = new ArrayList<>();
- Session session = null;
try {
- session = getSshSession(host, port, username, password);
- // 关键修改:强制英文输出 + 调整字段索引
String diskCommand = "LANG=en_US.UTF-8 df -h | awk '{print $1, $6, $2, $3, $5}'";
String diskResult = executeCommand(session, diskCommand);
-
if (StringUtils.hasText(diskResult)) {
String[] lines = diskResult.split("\n");
for (String line : lines) {
- // 过滤空行和标题行
if (line.trim().isEmpty() || line.contains("Filesystem")) {
continue;
}
- // 按任意空格分割(兼容多个空格)
String[] parts = line.trim().split("\\s+");
if (parts.length >= 5) {
+ String fileSystem = parts[0];
+ boolean isFilter = FILTER_FILE_SYSTEM.stream().anyMatch(fileSystem::contains);
+ if (isFilter) {
+ continue;
+ }
+ double usage = DEFAULT_USAGE;
String usageStr = parts[4].replace("%", "").trim();
- DiskInfo diskInfo = new DiskInfo(parts[0], parts[1], parts[2], parts[3], Double.parseDouble(usageStr));
+ if (StringUtils.hasText(usageStr)) {
+ usage = Double.parseDouble(usageStr);
+ }
+ DiskInfo diskInfo = new DiskInfo(parts[0], parts[1], parts[2], parts[3], usage);
diskInfos.add(diskInfo);
}
}
}
- } finally {
- if (session != null && session.isConnected()) {
- session.disconnect();
- }
+ } catch (Exception e) {
+ System.out.println(e);
}
return diskInfos;
}
-}
+}
\ No newline at end of file
diff --git a/web-api/src/main/java/com/jeesite/modules/app/utils/sftpUtils.java b/web-api/src/main/java/com/jeesite/modules/app/utils/sftpUtils.java
new file mode 100644
index 00000000..208ba224
--- /dev/null
+++ b/web-api/src/main/java/com/jeesite/modules/app/utils/sftpUtils.java
@@ -0,0 +1,81 @@
+package com.jeesite.modules.app.utils;
+
+
+import com.jcraft.jsch.ChannelSftp;
+import cn.hutool.core.lang.Filter;
+import cn.hutool.extra.ssh.JschUtil;
+import cn.hutool.extra.ssh.Sftp;
+import com.jeesite.modules.biz.entity.BizMonitorAccount;
+
+import java.io.File;
+import java.util.List;
+import java.util.regex.Pattern;
+
+public class sftpUtils {
+
+ private static final LoggerUtils logger = LoggerUtils.getInstance();
+
+
+ public static Filter ruleFilter(String pattern) {
+ if (pattern == null || pattern.isBlank()) {
+ return entry -> false;
+ }
+ String matchPattern = pattern.trim().toLowerCase();
+ String[] ruleArr = matchPattern.split(",");
+ StringBuilder regexBuilder = new StringBuilder();
+ for (int i = 0; i < ruleArr.length; i++) {
+ String rule = ruleArr[i].trim();
+ if (rule.isBlank()) continue;
+ // 通配符转正则
+ String singleRegex = rule.replace(".", "\\.").replace("*", ".*");
+ regexBuilder.append("^").append(singleRegex).append("$");
+ if (i < ruleArr.length - 1) {
+ regexBuilder.append("|"); // 多规则用或连接
+ }
+ }
+ Pattern compilePattern = Pattern.compile(regexBuilder.toString());
+ return entry -> {
+ if (entry == null || entry.getAttrs().isDir()) {
+ return false;
+ }
+ String fileName = entry.getFilename();
+ if (fileName == null || fileName.isBlank()) {
+ return false;
+ }
+ return compilePattern.matcher(fileName.toLowerCase()).matches();
+ };
+ }
+
+ /**
+ * 上传文件
+ */
+ public static void fileUpload(BizMonitorAccount account, String getRemotePath, String localFile) {
+ try {
+ File file = new File(localFile);
+ if (file.exists()) {
+ Sftp sftp = JschUtil.createSftp(account.getIpAddress(), account.getSshPort(), account.getSshUsername(), AesUtil.decrypt(account.getSshPassword()));
+ sftp.put(localFile, getRemotePath);
+ sftp.close();
+ }
+ } catch (Exception e) {
+ logger.error(e.getMessage());
+ }
+ }
+
+
+ /**
+ * 下载文件
+ */
+ public static void fileDownload(BizMonitorAccount account, String getRemotePath, String filter, String localPath) {
+ try {
+ Sftp sftp = JschUtil.createSftp(account.getIpAddress(), account.getSshPort(), account.getSshUsername(), AesUtil.decrypt(account.getSshPassword()));
+ List files = sftp.ls(getRemotePath, ruleFilter(filter));
+ for (String fileName : files) {
+ sftp.get(MyUtils.getPath(getRemotePath, fileName), localPath);
+ }
+ sftp.close();
+ } catch (Exception e) {
+ logger.error(e.getMessage());
+ }
+ }
+}
diff --git a/web-api/src/main/java/com/jeesite/modules/app/utils/vo.java b/web-api/src/main/java/com/jeesite/modules/app/utils/vo.java
deleted file mode 100644
index 69e99bdb..00000000
--- a/web-api/src/main/java/com/jeesite/modules/app/utils/vo.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.jeesite.modules.app.utils;
-
-import com.jeesite.common.codec.AesUtils;
-
-
-public class vo {
-
- private static final String AES_KEY = "010e06108bb801e85f8738e01c396dd2";
-
- /**
- * 获取加密Key
- */
- public static String getKey() {
- return AesUtils.genKeyString();
- }
-
-
- /**
- * 加密
- */
- public static String getEncode(String s) {
- try {
- return AesUtils.encode(s, AES_KEY);
- } catch (Exception e) {
- System.out.println(e.getMessage());
- return s;
- }
- }
-
- /**
- * 解密
- */
- public static String getDecode(String s) {
- try {
- return AesUtils.decode(s, AES_KEY);
- } catch (Exception e) {
- System.out.println(e.getMessage());
- return s;
- }
- }
-}
diff --git a/web-api/src/main/java/com/jeesite/modules/biz/web/BizMonitorAccountController.java b/web-api/src/main/java/com/jeesite/modules/biz/web/BizMonitorAccountController.java
index efc5eed4..ae7d0d7a 100644
--- a/web-api/src/main/java/com/jeesite/modules/biz/web/BizMonitorAccountController.java
+++ b/web-api/src/main/java/com/jeesite/modules/biz/web/BizMonitorAccountController.java
@@ -1,9 +1,8 @@
package com.jeesite.modules.biz.web;
-import java.util.Date;
import java.util.List;
-import com.jeesite.modules.app.utils.vo;
+import com.jeesite.modules.app.utils.AesUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@@ -91,11 +90,11 @@ public class BizMonitorAccountController extends BaseController {
@ResponseBody
public String save(@Validated BizMonitorAccount bizMonitorAccount) {
if (bizMonitorAccount.getIsNewRecord()) {
- bizMonitorAccount.setSshPassword(vo.getEncode(bizMonitorAccount.getSshPassword()));
+ bizMonitorAccount.setSshPassword(AesUtil.encrypt(bizMonitorAccount.getSshPassword()));
} else {
BizMonitorAccount account = bizMonitorAccountService.get(bizMonitorAccount.getAccountId());
if (!account.getSshPassword().equals(bizMonitorAccount.getSshPassword())) {
- bizMonitorAccount.setSshPassword(vo.getEncode(bizMonitorAccount.getSshPassword()));
+ bizMonitorAccount.setSshPassword(AesUtil.encrypt(bizMonitorAccount.getSshPassword()));
}
}
bizMonitorAccountService.save(bizMonitorAccount);