🚀 feat(agent): 监控机器网络流程支持配置排除网卡或者仅统计对应的网卡

This commit is contained in:
小吾立 2024-04-24 17:51:55 +08:00
parent 4a3217d575
commit 298cef01cc
6 changed files with 89 additions and 12 deletions

View File

@ -6,6 +6,7 @@
1. 【server】修复 资产管理 SSH 配置禁用命令无法回显(感谢@zhangw
2. 【server】修复 资产管理 SSH 未配置授权目录时 NPE (感谢[@Anley](https://gitee.com/MrAnley) [Gitee issues I9J17G](https://gitee.com/dromara/Jpom/issues/I9J17G)
3. 【agent】优化 监控机器网络流程支持配置排除网卡或者仅统计对应的网卡
------

View File

@ -37,7 +37,7 @@ import java.util.Optional;
@Configuration
@ConfigurationProperties("jpom")
@Data
@EnableConfigurationProperties({ProjectConfig.class, ProjectLogConfig.class, SystemConfig.class, AgentAuthorize.class})
@EnableConfigurationProperties({ProjectConfig.class, ProjectLogConfig.class, SystemConfig.class, AgentAuthorize.class, MonitorConfig.class, MonitorConfig.NetworkConfig.class})
public class AgentConfig implements ILoadEvent, InitializingBean {
private final JpomApplication jpomApplication;
@ -59,6 +59,11 @@ public class AgentConfig implements ILoadEvent, InitializingBean {
* 系统配置参数
*/
private SystemConfig system;
/**
* 监控配置
*/
private MonitorConfig monitor;
/**
* 数据目录
*/

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2019 Of Him Code Technology Studio
* Jpom is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.jpom.configuration;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author bwcx_jzy
* @since 2024/4/24
*/
@Data
@ConfigurationProperties("jpom.monitor")
public class MonitorConfig {
private NetworkConfig network;
@Data
@ConfigurationProperties("jpom.monitor.network")
public static class NetworkConfig {
/**
* 忽略的网卡,多个使用逗号分隔
*/
private String statExcludeNames;
/**
* 仅统计的网卡
* ,多个使用逗号分隔
*/
private String statContainsOnlyNames;
}
}

View File

@ -23,6 +23,8 @@ import org.dromara.jpom.common.RemoteVersion;
import org.dromara.jpom.common.commander.ProjectCommander;
import org.dromara.jpom.common.commander.SystemCommander;
import org.dromara.jpom.common.interceptor.NotAuthorize;
import org.dromara.jpom.configuration.AgentConfig;
import org.dromara.jpom.configuration.MonitorConfig;
import org.dromara.jpom.model.data.NodeProjectInfoModel;
import org.dromara.jpom.model.data.NodeScriptModel;
import org.dromara.jpom.plugin.PluginFactory;
@ -39,6 +41,7 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
@ -55,15 +58,18 @@ public class IndexController extends BaseAgentController {
private final NodeScriptServer nodeScriptServer;
private final SystemCommander systemCommander;
private final ProjectCommander projectCommander;
private final AgentConfig agentConfig;
public IndexController(ProjectInfoService projectInfoService,
NodeScriptServer nodeScriptServer,
SystemCommander systemCommander,
ProjectCommander projectCommander) {
ProjectCommander projectCommander,
AgentConfig agentConfig) {
this.projectInfoService = projectInfoService;
this.nodeScriptServer = nodeScriptServer;
this.systemCommander = systemCommander;
this.projectCommander = projectCommander;
this.agentConfig = agentConfig;
}
@RequestMapping(value = {"index", "", "index.html", "/"}, produces = MediaType.TEXT_PLAIN_VALUE)
@ -95,7 +101,9 @@ public class IndexController extends BaseAgentController {
public IJsonMessage<JSONObject> getDirectTop() {
JSONObject jsonObject = new JSONObject();
try {
JSONObject topInfo = org.dromara.jpom.util.OshiUtils.getSimpleInfo();
Optional<MonitorConfig> monitorConfig = Optional.ofNullable(agentConfig).map(AgentConfig::getMonitor);
JSONObject topInfo = org.dromara.jpom.util.OshiUtils.getSimpleInfo(monitorConfig.orElse(null));
jsonObject.put("simpleStatus", topInfo);
// 系统固定休眠时间
jsonObject.put("systemSleep", org.dromara.jpom.util.OshiUtils.NET_STAT_SLEEP + org.dromara.jpom.util.OshiUtils.CPU_STAT_SLEEP);

View File

@ -9,6 +9,7 @@
*/
package org.dromara.jpom.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.SystemClock;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
@ -16,6 +17,7 @@ import cn.hutool.system.oshi.CpuInfo;
import cn.hutool.system.oshi.OshiUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
import org.dromara.jpom.configuration.MonitorConfig;
import oshi.hardware.*;
import oshi.software.os.FileSystem;
import oshi.software.os.NetworkParams;
@ -97,7 +99,7 @@ public class OshiUtils {
*
* @return json
*/
public static JSONObject getSimpleInfo() {
public static JSONObject getSimpleInfo(MonitorConfig monitorConfig) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("time", SystemClock.now());
CpuInfo cpuInfo = OshiUtil.getCpuInfo(CPU_STAT_SLEEP);
@ -129,27 +131,44 @@ public class OshiUtils {
}
jsonObject.put("disk", NumberUtil.div(used, total, 2) * 100);
//
NetIoInfo startNetInfo = getNetInfo();
MonitorConfig.NetworkConfig networkConfig1 = Optional.ofNullable(monitorConfig)
.map(MonitorConfig::getNetwork).orElse(null);
NetIoInfo startNetInfo = getNetInfo(networkConfig1);
//暂停1秒
Util.sleep(NET_STAT_SLEEP);
NetIoInfo endNetInfo = getNetInfo();
NetIoInfo endNetInfo = getNetInfo(networkConfig1);
jsonObject.put("netTxBytes", endNetInfo.getTxbyt() - startNetInfo.getTxbyt());
jsonObject.put("netRxBytes", endNetInfo.getRxbyt() - startNetInfo.getRxbyt());
return jsonObject;
}
private static NetIoInfo getNetInfo() {
private static NetIoInfo getNetInfo(MonitorConfig.NetworkConfig networkConfig) {
//
List<String> statExcludeNames = Optional.ofNullable(networkConfig)
.map(MonitorConfig.NetworkConfig::getStatExcludeNames)
.map(s -> StrUtil.splitTrim(s, StrUtil.COMMA))
.orElse(CollUtil.newArrayList());
List<String> statContainsOnlyNames = Optional.ofNullable(networkConfig)
.map(MonitorConfig.NetworkConfig::getStatContainsOnlyNames)
.map(s -> StrUtil.splitTrim(s, StrUtil.COMMA))
.orElse(CollUtil.newArrayList());
long rxBytesBegin = 0;
long txBytesBegin = 0;
long rxPacketsBegin = 0;
long txPacketsBegin = 0;
List<NetworkIF> listBegin = OshiUtil.getNetworkIFs();
for (NetworkIF net : listBegin) {
rxBytesBegin += net.getBytesRecv();
txBytesBegin += net.getBytesSent();
rxPacketsBegin += net.getPacketsRecv();
txPacketsBegin += net.getPacketsSent();
if (listBegin != null) {
listBegin = listBegin.stream()
.filter(networkIF -> CollUtil.isEmpty(statExcludeNames) || !CollUtil.contains(statExcludeNames, networkIF.getName()))
.filter(networkIF -> CollUtil.isEmpty(statContainsOnlyNames) || CollUtil.contains(statContainsOnlyNames, networkIF.getName()))
.collect(Collectors.toList());
for (NetworkIF net : listBegin) {
rxBytesBegin += net.getBytesRecv();
txBytesBegin += net.getBytesSent();
rxPacketsBegin += net.getPacketsRecv();
txPacketsBegin += net.getPacketsSent();
}
}
NetIoInfo netIoInfo = new NetIoInfo();
netIoInfo.setRxbyt(rxBytesBegin);

View File

@ -53,6 +53,12 @@ jpom:
allowed-downgrade: false
# 执行系统主要命名是否填充 sudo(sudo xxx) 使用前提需要配置 sudo 免密
command-use-sudo: false
monitor:
network:
# 监控网络流量只统计对应的网卡
stat-contains-only-names: io
# 监控网络流量排除对应的网卡
stat-exclude-names: io
server:
#运行端口号
port: 2123