作者 钟来

应用程序告警

package com.ruoyi.system.domain.sys;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.PublicSQLConfig;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import com.ruoyi.common.tool.BaseEntity;
/**
* 应用状态监控对象 sys_monitor_application
*
* @author zhonglai
* @date 2025-06-25
*/
@ApiModel("应用状态监控")
public class SysMonitorApplication extends BaseEntity
{
@PublicSQLConfig(isSelect = false)
private static final long serialVersionUID = 1L;
/** $column.columnComment */
private Integer id;
/** 更新时间 */
@ApiModelProperty(value="更新时间")
@Excel(name = "更新时间", width = 30)
private String timestamp;
/** 主机 */
@ApiModelProperty(value="主机")
@Excel(name = "主机")
private String hostname;
/** 名称 */
@ApiModelProperty(value="名称")
@Excel(name = "名称")
private String name;
/** 进程id */
@ApiModelProperty(value="进程id")
@Excel(name = "进程id")
private Integer pid;
/** cpu使用情况 */
@ApiModelProperty(value="cpu使用情况")
@Excel(name = "cpu使用情况")
private String cpu;
/** 内存使用情况 */
@ApiModelProperty(value="内存使用情况")
@Excel(name = "内存使用情况")
private String mem;
/** 执行指令 */
@ApiModelProperty(value="执行指令")
@Excel(name = "执行指令")
private String cmd;
/** 状态 */
@ApiModelProperty(value="状态")
@Excel(name = "状态")
private String status;
@ApiModelProperty(value="远程ip")
@Excel(name = "远程ip")
private String remoteIp;
@ApiModelProperty(value="app描述")
@Excel(name = "app描述")
private String appDescribe;
public String getAppDescribe() {
return appDescribe;
}
public void setAppDescribe(String appDescribe) {
this.appDescribe = appDescribe;
}
public String getRemoteIp() {
return remoteIp;
}
public void setRemoteIp(String remoteIp) {
this.remoteIp = remoteIp;
}
public void setId(Integer id)
{
this.id = id;
}
public Integer getId()
{
return id;
}
public void setTimestamp(String timestamp)
{
this.timestamp = timestamp;
}
public String getTimestamp()
{
return timestamp;
}
public void setHostname(String hostname)
{
this.hostname = hostname;
}
public String getHostname()
{
return hostname;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setPid(Integer pid)
{
this.pid = pid;
}
public Integer getPid()
{
return pid;
}
public void setCpu(String cpu)
{
this.cpu = cpu;
}
public String getCpu()
{
return cpu;
}
public void setMem(String mem)
{
this.mem = mem;
}
public String getMem()
{
return mem;
}
public void setCmd(String cmd)
{
this.cmd = cmd;
}
public String getCmd()
{
return cmd;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("timestamp", getTimestamp())
.append("hostname", getHostname())
.append("name", getName())
.append("pid", getPid())
.append("cpu", getCpu())
.append("mem", getMem())
.append("cmd", getCmd())
.append("status", getStatus())
.toString();
}
}
... ...
package com.ruoyi.system.domain.sys;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.PublicSQLConfig;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import com.ruoyi.common.tool.BaseEntity;
/**
* 应用状态监控记录对象 sys_monitor_application_log
*
* @author zhonglai
* @date 2025-06-25
*/
@ApiModel("应用状态监控记录")
public class SysMonitorApplicationLog extends BaseEntity
{
@PublicSQLConfig(isSelect = false)
private static final long serialVersionUID = 1L;
/** $column.columnComment */
private Integer id;
/** 更新时间 */
@ApiModelProperty(value="更新时间")
@Excel(name = "更新时间", width = 30)
private String timestamp;
/** 进程id */
@ApiModelProperty(value="进程id")
@Excel(name = "进程id")
private Integer pid;
/** cpu使用情况 */
@ApiModelProperty(value="cpu使用情况")
@Excel(name = "cpu使用情况")
private String cpu;
/** 内存使用情况 */
@ApiModelProperty(value="内存使用情况")
@Excel(name = "内存使用情况")
private String mem;
/** 状态 */
@ApiModelProperty(value="状态")
@Excel(name = "状态")
private String status;
@ApiModelProperty(value="应用表id")
@Excel(name = "应用表id")
private Integer monitorApplicationId;
public Integer getMonitorApplicationId() {
return monitorApplicationId;
}
public void setMonitorApplicationId(Integer monitorApplicationId) {
this.monitorApplicationId = monitorApplicationId;
}
public void setId(Integer id)
{
this.id = id;
}
public Integer getId()
{
return id;
}
public void setTimestamp(String timestamp)
{
this.timestamp = timestamp;
}
public String getTimestamp()
{
return timestamp;
}
public void setPid(Integer pid)
{
this.pid = pid;
}
public Integer getPid()
{
return pid;
}
public void setCpu(String cpu)
{
this.cpu = cpu;
}
public String getCpu()
{
return cpu;
}
public void setMem(String mem)
{
this.mem = mem;
}
public String getMem()
{
return mem;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("timestamp", getTimestamp())
.append("monitorApplicationId", getMonitorApplicationId())
.append("pid", getPid())
.append("cpu", getCpu())
.append("mem", getMem())
.append("status", getStatus())
.toString();
}
}
... ...
... ... @@ -5,6 +5,7 @@ import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.sys.SysMonitorApplication;
import com.ruoyi.system.domain.sys.SysMonitorServer;
import com.zhonglai.luhui.dao.service.PublicService;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -42,10 +43,10 @@ public class ServerAlarmTask {
stringBuffer.append("\n");
if(sms.getCpu_usage()>=cpu_usage)
{
stringBuffer.append("<font color=\"warning\">");
// stringBuffer.append("<font color=\"warning\">");
stringBuffer.append(">CPU使用率:");
stringBuffer.append(sms.getCpu_usage()/100+"%");
stringBuffer.append("</font>");
// stringBuffer.append("</font>");
}else{
stringBuffer.append(">CPU使用率:");
stringBuffer.append(sms.getCpu_usage()/100+"%");
... ... @@ -54,10 +55,10 @@ public class ServerAlarmTask {
stringBuffer.append("\n");
if(sms.getMemory_usage()>=memory_usage)
{
stringBuffer.append("<font color=\"warning\">");
// stringBuffer.append("<font color=\"warning\">");
stringBuffer.append(">内存使用率:");
stringBuffer.append(sms.getMemory_usage()/100+"%");
stringBuffer.append("</font>");
// stringBuffer.append("</font>");
}else{
stringBuffer.append(">内存使用率:");
stringBuffer.append(sms.getMemory_usage()/100+"%");
... ... @@ -66,10 +67,10 @@ public class ServerAlarmTask {
stringBuffer.append("\n");
if(sms.getDisk_usage()>=disk_usage)
{
stringBuffer.append("<font color=\"warning\">");
// stringBuffer.append("<font color=\"warning\">");
stringBuffer.append(">磁盘使用率:");
stringBuffer.append(sms.getDisk_usage()/100+"%");
stringBuffer.append("</font>");
// stringBuffer.append("</font>");
}else{
stringBuffer.append(">磁盘使用率:");
stringBuffer.append(sms.getDisk_usage()/100+"%");
... ... @@ -79,10 +80,10 @@ public class ServerAlarmTask {
if (sms.getConnection_count()>=connection_count)
{
stringBuffer.append("<font color=\"warning\">");
// stringBuffer.append("<font color=\"warning\">");
stringBuffer.append(">系统连接数:");
stringBuffer.append(sms.getConnection_count());
stringBuffer.append("</font>");
// stringBuffer.append("</font>");
}else{
stringBuffer.append(">系统连接数:");
stringBuffer.append(sms.getConnection_count());
... ... @@ -96,26 +97,70 @@ public class ServerAlarmTask {
ips.append("'");
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("msgtype","markdown");
jsonObject.put("msgtype","text");
JSONObject text = new JSONObject();
text.put("content",stringBuffer.toString());
text.put("mentioned_mobile_list",new String[]{"@all"});
jsonObject.put("markdown",text);
jsonObject.put("text",text);
HttpUtil.post("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=0c811725-6ee8-4bb5-b7de-378b6fa5b9b0",jsonObject.toJSONString());
publicService.updateBySql("update `sys_monitor_server` set notification_time="+DateUtils.getNowTimeMilly()+" where ip in("+ips+")");
}
}
public void checkServerStatus() {
List<Map<String,Object>> list = publicService.getObjectListBySQL("SELECT * FROM `sys_monitor_application` WHERE `status`='not_running' AND notification_time < "+(DateUtils.getNowTimeMilly()-2*60*60));
if(null != list && list.size()!=0)
{
StringBuffer stringBuffer = new StringBuffer("**应用运维状态:**");
StringBuffer ips = new StringBuffer("0");
for (Map<String,Object> map:list)
{
SysMonitorApplication sms = BeanUtil.mapToBean(map, SysMonitorApplication.class,false,null);
stringBuffer.append("\n");
stringBuffer.append("\n");
stringBuffer.append(">ip:");
stringBuffer.append(sms.getRemoteIp());
stringBuffer.append("\n");
// stringBuffer.append("<font color=\"warning\">");
stringBuffer.append(">"+sms.getAppDescribe()+":");
stringBuffer.append(sms.getName());
// stringBuffer.append("</font>");
stringBuffer.append("\n");
stringBuffer.append(DateUtils.parseDateToStr("yyyy年MM月dd日HH时mm分ss秒",new Date()));
stringBuffer.append("\n");
// stringBuffer.append("<font color=\"warning\">");
stringBuffer.append("程序被运行停止,请联系管理员查看");
// stringBuffer.append("</font>");
stringBuffer.append("\n");
ips.append(",");
ips.append(sms.getId());
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("msgtype","text");
JSONObject text = new JSONObject();
text.put("content",stringBuffer.toString());
text.put("mentioned_mobile_list",new String[]{"@all"});
jsonObject.put("text",text);
HttpUtil.post("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=0c811725-6ee8-4bb5-b7de-378b6fa5b9b0",jsonObject.toJSONString());
publicService.updateBySql("update `sys_monitor_application` set notification_time="+DateUtils.getNowTimeMilly()+" where id in("+ips+")");
}
}
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("颜色测试:");
stringBuffer.append("<font color=\"warning\">警告</font>");
JSONObject jsonObject = new JSONObject();
jsonObject.put("msgtype","markdown");
jsonObject.put("msgtype","text");
JSONObject text = new JSONObject();
text.put("content",stringBuffer.toString());
text.put("mentioned_mobile_list",new String[]{"@all"});
jsonObject.put("markdown",text);
jsonObject.put("text",text);
String str = HttpUtil.post("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=0c811725-6ee8-4bb5-b7de-378b6fa5b9b0",jsonObject.toJSONString());
System.out.println(str);
}
... ...
... ... @@ -11,9 +11,12 @@ import com.ruoyi.common.utils.GsonConstructor;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.framework.web.domain.Server;
import com.ruoyi.system.domain.sys.SysMonitorApplication;
import com.ruoyi.system.domain.sys.SysMonitorApplicationLog;
import com.ruoyi.system.domain.sys.SysMonitorServer;
import com.ruoyi.system.domain.sys.SysMonitorServerLog;
import com.zhonglai.luhui.action.BaseController;
import com.zhonglai.luhui.admin.dto.MonitorServerUploadApplicationDto;
import com.zhonglai.luhui.admin.dto.MonitorServerUploadDto;
import com.zhonglai.luhui.admin.qywx.AesException;
import com.zhonglai.luhui.admin.qywx.QyWxApplication;
... ... @@ -26,6 +29,7 @@ import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.w3c.dom.Document;
... ... @@ -73,6 +77,7 @@ public class ServerController extends BaseController
}
@ApiOperation("上传状态")
@Transactional
@PostMapping("/upload")
public AjaxResult upload(@RequestBody MonitorServerUploadDto monitorServerUploadDto)
{
... ... @@ -84,12 +89,30 @@ public class ServerController extends BaseController
sysMonitorServer.setIp(ip+"("+monitorServerUploadDto.getLocalip()+")");
}
Long st = publicService.getObjectListTotle(sysMonitorServer, null);
sysMonitorServer.setCpu_usage(new Double(monitorServerUploadDto.getCpu_usage()*100).intValue());
sysMonitorServer.setConnection_count(monitorServerUploadDto.getConnection_count());
sysMonitorServer.setMemory_usage(new Double(monitorServerUploadDto.getMemory_usage()*100).intValue());
sysMonitorServer.setDisk_usage(new Double(monitorServerUploadDto.getDisk_usage()*100).intValue());
sysMonitorServer.setCpu_info(tranPsAux(monitorServerUploadDto.getCpu_info()));
sysMonitorServer.setMemory_info(tranPsAux(monitorServerUploadDto.getMemory_info()));
if(null != monitorServerUploadDto.getCpu_usage())
{
sysMonitorServer.setCpu_usage(new Double(monitorServerUploadDto.getCpu_usage()*100).intValue());
}
if(null != monitorServerUploadDto.getConnection_count())
{
sysMonitorServer.setConnection_count(monitorServerUploadDto.getConnection_count());
}
if(null != monitorServerUploadDto.getMemory_usage())
{
sysMonitorServer.setMemory_usage(new Double(monitorServerUploadDto.getMemory_usage()*100).intValue());
}
if(null != monitorServerUploadDto.getDisk_usage())
{
sysMonitorServer.setDisk_usage(new Double(monitorServerUploadDto.getDisk_usage()*100).intValue());
}
if (null != monitorServerUploadDto.getCpu_info())
{
sysMonitorServer.setCpu_info(tranPsAux(monitorServerUploadDto.getCpu_info()));
}
if (null != monitorServerUploadDto.getMemory_info())
{
sysMonitorServer.setMemory_info(tranPsAux(monitorServerUploadDto.getMemory_info()));
}
if(st==0)
{
... ... @@ -110,6 +133,48 @@ public class ServerController extends BaseController
return AjaxResult.success();
}
@ApiOperation("上传应用状态")
@Transactional
@PostMapping("/uploadApplication")
public AjaxResult uploadApplication(@RequestBody MonitorServerUploadApplicationDto monitorServerUploadApplicationDto)
{
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
for(SysMonitorApplication sysMonitorApplication:monitorServerUploadApplicationDto.getData())
{
SysMonitorApplication selectSysMonitorApplication = publicService.getObject(SysMonitorApplication.class,"remoteIp,name", ip+","+sysMonitorApplication.getName());
sysMonitorApplication.setRemoteIp(ip);
if(null == selectSysMonitorApplication)
{
publicService.insert(sysMonitorApplication);
}else {
sysMonitorApplication.setId(selectSysMonitorApplication.getId());
publicService.updateObject(sysMonitorApplication,"id");
}
SysMonitorApplicationLog sysMonitorApplicationLog = JSONObject.parseObject(JSONObject.toJSONString(sysMonitorApplication),SysMonitorApplicationLog.class);
sysMonitorApplicationLog.setId(null);
sysMonitorApplicationLog.setMonitorApplicationId(sysMonitorApplication.getId());
publicService.insert(sysMonitorApplicationLog);
}
return AjaxResult.success();
}
@ApiOperation("获取服务器应用列表")
@GetMapping("/getServiceAoolicationList")
public Map<String,Object> getServiceAoolicationList()
{
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
List<Map<String,Object>> list = publicService.getObjectListBySQL("SELECT GROUP_CONCAT(`name`) processes FROM `sys_monitor_application` WHERE remote_ip='"+ip+"' GROUP BY remote_ip");
Map<String,Object> map = new HashMap<>();
map.put("processes","");
if(null != list && list.size()>0)
{
String pprocesses = list.get(0).get("processes").toString();
map.put("processes",pprocesses.split(","));
}
return map;
}
private String tranPsAux(String princmd)
{
String[] auxs = princmd.split(";");
... ... @@ -211,6 +276,26 @@ public class ServerController extends BaseController
return getDataTable(list);
}
@ApiOperation("获取应用状态列表")
@GetMapping("/getSysMonitorApplicationList")
public TableDataInfo getSysMonitorApplicationList(SysMonitorApplication sysMonitorApplication) throws Exception
{
startPage();
startOrderBy();
List<Map<String,Object>> list = publicService.getObjectList(sysMonitorApplication,"*",null,null,0,0);
return getDataTable(list);
}
@ApiOperation("获取应用状态记录列表")
@GetMapping("/getSysMonitorApplicationLogList")
public TableDataInfo getSysMonitorApplicationLogList(SysMonitorApplicationLog sysMonitorApplicationLog) throws Exception
{
startPage();
startOrderBy();
List<Map<String,Object>> list = publicService.getObjectList(sysMonitorApplicationLog,"*",null,null,0,0);
return getDataTable(list);
}
@ApiOperation("获取服务器状态曲线")
@GetMapping("/getSysMonitorServerLogList")
public TableDataInfo getSysMonitorServerLogList(String ip,Long startTime,Long endTime) throws Exception
... ... @@ -233,4 +318,10 @@ public class ServerController extends BaseController
SysMonitorServerLog sysMonitorServerLog = publicService.getObject(SysMonitorServerLog.class,"id",id+"");
return AjaxResult.success(sysMonitorServerLog);
}
public static void main(String[] args) {
String str = "{\"data\":[ {\"timestamp\":\"2025-06-25 22:07:01\",\"hostname\":\"iZ28dmbj1ksZ\",\"name\":\"lh-admin.jar\",\"pid\":5603,\"cpu\":3.3,\"mem\":8.2,\"cmd\":\"/root/jdk1.8.0_291/bin/java -jar -Xmx1024M -Xms256M /www/wwwroot/lh-admin/lh-admin.jar --server.port\u003d6257 --spring.config.location\u003d/www/wwwroot/lh-admin/application.yml\",\"status\":\"running\"},{\"timestamp\":\"2025-06-25 22:07:01\",\"hostname\":\"iZ28dmbj1ksZ\",\"name\":\"ly-zhongyu-device-service.jar\",\"pid\":16942,\"cpu\":0.0,\"mem\":0.0,\"cmd\":\"curl -X POST -H Content-Type: application/json -d {\"cpu_usage\": \"66.7\", \"memory_usage\": \"70.85\", \"disk_usage\": \"61\", \"connection_count\": \"105\", \"memory_info\": \"USERfg9527PIDfg9527MEMORY(M)fg9527COMMAND;mysqlfg952715047fg95272665.56Mfg9527/www/server/mysql/bin/mysqld --basedir\u003d/www/server/mysql --datadir\u003d/www/server/data --plugin-dir\u003d/www/server/mysql/lib/plugin --user\u003dmysql --log-error\u003diZ28dmbj1ksZ.err --open-files-limit\u003d65535 --pid-file\u003d/www/server/data/iZ28dmbj1ksZ.pid --socket\u003d/tmp/mysql.sock --port\u003d3306 ;rootfg95275603fg9527648.18Mfg9527/root/jdk1.8.0_291/bin/java -jar -Xmx1024M -Xms256M /www/wwwroot/lh-admin/lh-admin.jar --server.port\u003d6257 --spring.config.location\u003d/www/wwwroot/lh-admin/application.yml ;gitfg952716053fg9527379.48Mfg9527sidekiq 4.1.2 gitlab-rails [0 of 25 busy] ;gitfg952731125fg9527317.29Mfg9527unicorn worker[1] -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru ;gitfg952718271fg9527316.69Mfg9527unicorn worker[2] -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru ;gitfg952716299fg9527315.64Mfg9527unicorn worker[0] -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru ;rootfg952731718fg9527302.00Mfg9527/root/jdk1.8.0_291/bin/java -jar -Xmx512M -Xms256M /www/wwwroot/ly-zhongyu-device-service/ly-zhongyu-device-service.jar --server.port\u003d7624 ;gitfg952716109fg9527265.38Mfg9527unicorn master -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru ;gitlab-+fg952716056fg952768.73Mfg9527/opt/gitlab/embedded/bin/postgres -D /var/opt/gitlab/postgresql/data ;rootfg952728865fg952768.66Mfg9527/www/server/panel/pyenv/bin/python3 /www/server/panel/BT-Panel ;\", \"cpu_info\": \"USERfg9527PIDfg9527CPU(%)fg9527COMMAND;rootfg952732008fg95273.40%fg9527/usr/local/aegis/aegis_client/aegis_12_53/AliYunDunMonitor ;rootfg95275603fg95273.30%fg9527/root/jdk1.8.0_291/bin/java -jar -Xmx1024M -Xms256M /www/wwwroot/lh-admin/lh-admin.jar --server.port\u003d6257 --spring.config.location\u003d/www/wwwroot/lh-admin/application.yml ;rootfg952731830fg95271.00%fg9527/usr/local/aegis/aegis_client/aegis_12_53/AliYunDun ;gitfg952716299fg95270.60%fg9527unicorn worker[0] -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru ;gitfg952718271fg95270.60%fg9527unicorn worker[2] -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru ;gitfg952731125fg95270.60%fg9527unicorn worker[1] -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru ;gitfg952716053fg95270.50%fg9527sidekiq 4.1.2 gitlab-rails [0 of 25 busy] ;rootfg952731718fg95270.20%fg9527/root/jdk1.8.0_291/bin/java -jar -Xmx512M -Xms256M /www/wwwroot/ly-zhongyu-device-service/ly-zhongyu-device-service.jar --server.port\u003d7624 ;rootfg95279fg95270.10%fg9527[rcu_sched] ;mysqlfg952715047fg95270.10%fg9527/www/server/mysql/bin/mysqld --basedir\u003d/www/server/mysql --datadir\u003d/www/server/data --plugin-dir\u003d/www/server/mysql/lib/plugin --user\u003dmysql --log-error\u003diZ28dmbj1ksZ.err --open-files-limit\u003d65535 --pid-file\u003d/www/server/data/iZ28dmbj1ksZ.pid --socket\u003d/tmp/mysql.sock --port\u003d3306 ;\"} --insecure https://lh.admin.yu2le.com/api/monitor/server/upload\",\"status\":\"running\"},{\"timestamp\":\"2025-06-25 22:07:01\",\"hostname\":\"iZ28dmbj1ksZ\",\"name\":\"ly-zhongyu-device-service.jar\",\"pid\":31718,\"cpu\":0.2,\"mem\":3.8,\"cmd\":\"/root/jdk1.8.0_291/bin/java -jar -Xmx512M -Xms256M /www/wwwroot/ly-zhongyu-device-service/ly-zhongyu-device-service.jar --server.port\u003d7624\",\"status\":\"running\"} ]}";
System.out.println(JSONObject.parse(str));
}
}
... ...
package com.zhonglai.luhui.admin.dto;
import com.ruoyi.system.domain.sys.SysMonitorApplication;
import io.swagger.annotations.ApiModel;
import java.util.List;
@ApiModel("服务器应用状态监控")
public class MonitorServerUploadApplicationDto {
private List<SysMonitorApplication> data;
public List<SysMonitorApplication> getData() {
return data;
}
public void setData(List<SysMonitorApplication> data) {
this.data = data;
}
}
... ...
#!/bin/bash
# 安装(指定间隔) curl -sSL https://lh.admin.yu2le.com/shell/install_monitor_timer.sh | bash -s -- 1
# 卸载 curl -sSL https://yourserver.com/monitor/install_monitor_timer.sh | bash -s -- --uninstall
# === 配置项 ===
SCRIPT_NAME="multi_process_monitor.sh"
SCRIPT_URL="https://lh.admin.yu2le.com/shell/$SCRIPT_NAME"
SCRIPT_TARGET_PATH="/usr/local/bin/$SCRIPT_NAME"
LOG_FILE="/var/log/multi_process_monitor.log"
# === 处理参数 ===
if [[ "$1" == "--uninstall" ]]; then
echo "🗑️ 开始卸载..."
# 删除 crontab 中的定时任务
crontab -l 2>/dev/null | grep -v "$SCRIPT_TARGET_PATH" | crontab -
# 删除脚本文件
if [ -f "$SCRIPT_TARGET_PATH" ]; then
rm -f "$SCRIPT_TARGET_PATH"
echo "✅ 已删除脚本:$SCRIPT_TARGET_PATH"
fi
echo "✅ 定时任务卸载完成。"
exit 0
fi
# === 安装模式 ===
INTERVAL_MINUTES=$1
# 默认每 5 分钟运行一次
if [[ -z "$INTERVAL_MINUTES" ]]; then
INTERVAL_MINUTES=5
fi
# 参数校验
if ! [[ "$INTERVAL_MINUTES" =~ ^[1-9][0-9]*$ ]]; then
echo "❌ 错误:间隔时间必须是正整数分钟"
exit 1
fi
echo "📥 正在安装 $SCRIPT_NAME,每 $INTERVAL_MINUTES 分钟执行一次"
# 下载脚本
curl -fsSL "$SCRIPT_URL" -o "$SCRIPT_TARGET_PATH"
if [ $? -ne 0 ]; then
echo "❌ 脚本下载失败:$SCRIPT_URL"
exit 1
fi
chmod +x "$SCRIPT_TARGET_PATH"
# 添加 crontab 任务
CRON_JOB="*/$INTERVAL_MINUTES * * * * $SCRIPT_TARGET_PATH >> $LOG_FILE 2>&1"
(crontab -l 2>/dev/null | grep -F "$SCRIPT_TARGET_PATH") >/dev/null
if [ $? -eq 0 ]; then
echo "✅ 定时任务已存在,无需添加"
else
(crontab -l 2>/dev/null; echo "$CRON_JOB") | crontab -
echo "✅ 已添加定时任务"
fi
echo "🟢 安装完成!日志文件:$LOG_FILE"
... ...
#!/bin/bash
PROCESS_API="https://lh.admin.yu2le.com/api/monitor/server/getServiceAoolicationList"
UPLOAD_API="https://lh.admin.yu2le.com/api/monitor/server/uploadApplication"
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
HOSTNAME=$(hostname)
DATA_LIST=()
# ✅ JSON 字符串转义函数
escape_json_string() {
echo "$1" | sed \
-e 's/\\/\\\\/g' \
-e 's/"/\\"/g' \
-e 's/\t/\\t/g' \
-e 's/\r/\\r/g' \
-e 's/\n/\\n/g'
}
# 获取 process 名称列表
PROCESS_NAMES=$(curl -s "$PROCESS_API" | grep -oP '"processes"\s*:\s*\[\K[^\]]*' | tr -d '"' | tr ',' '\n')
for NAME in $PROCESS_NAMES; do
MATCHED=false
for PID in $(pgrep -f "$NAME"); do
MATCHED=true
STATS=$(ps -p $PID -o pid,%cpu,%mem,cmd --no-headers)
CPU=$(echo $STATS | awk '{print $2}')
MEM=$(echo $STATS | awk '{print $3}')
CMD=$(echo $STATS | cut -d ' ' -f4-)
# 转义所有字段
ESC_CMD=$(escape_json_string "$CMD")
ESC_NAME=$(escape_json_string "$NAME")
JSON="{\"timestamp\":\"$TIMESTAMP\",\"hostname\":\"$HOSTNAME\",\"name\":\"$ESC_NAME\",\"pid\":$PID,\"cpu\":$CPU,\"mem\":$MEM,\"cmd\":\"$ESC_CMD\",\"status\":\"running\"}"
DATA_LIST+=("$JSON")
done
if [ "$MATCHED" = false ]; then
ESC_NAME=$(escape_json_string "$NAME")
JSON="{\"timestamp\":\"$TIMESTAMP\",\"hostname\":\"$HOSTNAME\",\"name\":\"$ESC_NAME\",\"status\":\"not_running\"}"
DATA_LIST+=("$JSON")
fi
done
# 构造并上传 JSON
if [ ${#DATA_LIST[@]} -gt 0 ]; then
JOINED_JSON=""
for item in "${DATA_LIST[@]}"; do
if [ -n "$JOINED_JSON" ]; then
JOINED_JSON+=","
fi
JOINED_JSON+="$item"
done
POST_BODY="{\"data\":[ $JOINED_JSON ]}"
curl -s -X POST "$UPLOAD_API" \
-H "Content-Type: application/json" \
-d "$POST_BODY"
fi
... ...