mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-02 20:08:40 +08:00
差异发布、节点首页新增其他类型进程监控
This commit is contained in:
parent
492e4c8c0a
commit
b731692fb6
@ -5,6 +5,7 @@
|
||||
### 新增功能
|
||||
|
||||
1. 节点缓存页面新增定时作业列表
|
||||
2. 节点首页新增其他类型进程监控(感谢@大土豆)
|
||||
|
||||
### 解决BUG、优化功能
|
||||
|
||||
|
@ -40,7 +40,7 @@ import cn.hutool.system.SystemUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import io.jpom.common.commander.impl.LinuxProjectCommander;
|
||||
import io.jpom.common.commander.impl.MacOSProjectCommander;
|
||||
import io.jpom.common.commander.impl.MacOsProjectCommander;
|
||||
import io.jpom.common.commander.impl.WindowsProjectCommander;
|
||||
import io.jpom.model.RunMode;
|
||||
import io.jpom.model.data.JdkInfoModel;
|
||||
@ -101,7 +101,7 @@ public abstract class AbstractProjectCommander {
|
||||
// Windows系统
|
||||
abstractProjectCommander = new WindowsProjectCommander();
|
||||
} else if (SystemUtil.getOsInfo().isMac()) {
|
||||
abstractProjectCommander = new MacOSProjectCommander();
|
||||
abstractProjectCommander = new MacOsProjectCommander();
|
||||
} else {
|
||||
throw new JpomRuntimeException("不支持的:" + SystemUtil.getOsInfo().getName());
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ package io.jpom.common.commander;
|
||||
import cn.hutool.system.SystemUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.jpom.common.commander.impl.LinuxSystemCommander;
|
||||
import io.jpom.common.commander.impl.MacOSSystemCommander;
|
||||
import io.jpom.common.commander.impl.MacOsSystemCommander;
|
||||
import io.jpom.common.commander.impl.WindowsSystemCommander;
|
||||
import io.jpom.model.system.ProcessModel;
|
||||
import io.jpom.system.JpomRuntimeException;
|
||||
@ -55,7 +55,7 @@ public abstract class AbstractSystemCommander {
|
||||
// Windows系统
|
||||
abstractSystemCommander = new WindowsSystemCommander();
|
||||
} else if (SystemUtil.getOsInfo().isMac()) {
|
||||
abstractSystemCommander = new MacOSSystemCommander();
|
||||
abstractSystemCommander = new MacOsSystemCommander();
|
||||
} else {
|
||||
throw new JpomRuntimeException("不支持的:" + SystemUtil.getOsInfo().getName());
|
||||
}
|
||||
@ -72,9 +72,10 @@ public abstract class AbstractSystemCommander {
|
||||
/**
|
||||
* 获取当前服务器的所有进程列表
|
||||
*
|
||||
* @param processName 进程名称
|
||||
* @return array
|
||||
*/
|
||||
public abstract List<ProcessModel> getProcessList();
|
||||
public abstract List<ProcessModel> getProcessList(String processName);
|
||||
|
||||
/**
|
||||
* 获取指定进程的 内存信息
|
||||
|
@ -72,8 +72,8 @@ public class LinuxSystemCommander extends AbstractSystemCommander {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProcessModel> getProcessList() {
|
||||
String s = CommandUtil.execSystemCommand("top -b -n 1 | grep java");
|
||||
public List<ProcessModel> getProcessList(String processName) {
|
||||
String s = CommandUtil.execSystemCommand("top -b -n 1 | grep " + processName);
|
||||
return formatLinuxTop(s, false);
|
||||
}
|
||||
|
||||
|
@ -1,119 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Code Technology Studio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.jpom.common.commander.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.text.StrSplitter;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.jpom.common.commander.AbstractProjectCommander;
|
||||
import io.jpom.common.commander.AbstractSystemCommander;
|
||||
import io.jpom.model.data.NodeProjectInfoModel;
|
||||
import io.jpom.model.system.NetstatModel;
|
||||
import io.jpom.util.CommandUtil;
|
||||
import io.jpom.util.JvmUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MacOSProjectCommander
|
||||
*
|
||||
* @author Hotstrip
|
||||
* @Description some commands cannot execute success on Mac OS
|
||||
*/
|
||||
public class MacOSProjectCommander extends AbstractProjectCommander {
|
||||
|
||||
@Override
|
||||
public String buildCommand(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) {
|
||||
String path = NodeProjectInfoModel.getClassPathLib(nodeProjectInfoModel);
|
||||
if (StrUtil.isBlank(path)) {
|
||||
return null;
|
||||
}
|
||||
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();
|
||||
return String.format("nohup %s %s %s" +
|
||||
" %s %s %s >> %s 2>&1 &",
|
||||
getRunJavaPath(nodeProjectInfoModel, false),
|
||||
javaCopyItem == null ? nodeProjectInfoModel.getJvm() : javaCopyItem.getJvm(),
|
||||
JvmUtil.getJpomPidTag(tag, nodeProjectInfoModel.allLib()),
|
||||
path,
|
||||
nodeProjectInfoModel.getMainClass(),
|
||||
javaCopyItem == null ? nodeProjectInfoModel.getArgs() : javaCopyItem.getArgs(),
|
||||
nodeProjectInfoModel.getAbsoluteLog(javaCopyItem));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetstatModel> listNetstat(int pId, boolean listening) {
|
||||
String cmd;
|
||||
if (listening) {
|
||||
cmd = "lsof -n -P -iTCP -sTCP:LISTEN |grep " + pId + " | head -20";
|
||||
} else {
|
||||
cmd = "lsof -n -P -iTCP -sTCP:CLOSE_WAIT |grep " + pId + " | head -20";
|
||||
}
|
||||
String result = CommandUtil.execSystemCommand(cmd);
|
||||
//DefaultSystemLog.getLog().debug("Mac OS lsof data: {}", result);
|
||||
List<String> netList = StrSplitter.splitTrim(result, "\n", true);
|
||||
if (netList == null || netList.size() <= 0) {
|
||||
return null;
|
||||
}
|
||||
List<NetstatModel> array = new ArrayList<>();
|
||||
for (String str : netList) {
|
||||
List<String> list = StrSplitter.splitTrim(str, " ", true);
|
||||
if (list.size() < 5) {
|
||||
continue;
|
||||
}
|
||||
NetstatModel netstatModel = new NetstatModel();
|
||||
netstatModel.setProtocol(list.get(0));
|
||||
netstatModel.setReceive(list.get(1));
|
||||
netstatModel.setSend(list.get(2));
|
||||
netstatModel.setLocal(list.get(3));
|
||||
netstatModel.setForeign(list.get(4));
|
||||
if ("tcp".equalsIgnoreCase(netstatModel.getProtocol())) {
|
||||
netstatModel.setStatus(CollUtil.get(list, 5));
|
||||
netstatModel.setName(CollUtil.get(list, 6));
|
||||
} else {
|
||||
netstatModel.setStatus(StrUtil.DASHED);
|
||||
netstatModel.setName(CollUtil.get(list, 5));
|
||||
}
|
||||
array.add(netstatModel);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stop(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) throws Exception {
|
||||
String result = super.stop(nodeProjectInfoModel, javaCopyItem);
|
||||
int pid = parsePid(result);
|
||||
if (pid > 0) {
|
||||
String kill = AbstractSystemCommander.getInstance().kill(FileUtil.file(nodeProjectInfoModel.allLib()), pid);
|
||||
if (loopCheckRun(nodeProjectInfoModel.getId(), false)) {
|
||||
// 强制杀进程
|
||||
String cmd = String.format("kill -9 %s", pid);
|
||||
CommandUtil.asyncExeLocalCommand(FileUtil.file(nodeProjectInfoModel.allLib()), cmd);
|
||||
}
|
||||
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();
|
||||
result = status(tag) + StrUtil.SPACE + kill;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Code Technology Studio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.jpom.common.commander.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.text.StrSplitter;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.jpom.common.commander.AbstractProjectCommander;
|
||||
import io.jpom.common.commander.AbstractSystemCommander;
|
||||
import io.jpom.model.data.NodeProjectInfoModel;
|
||||
import io.jpom.model.system.NetstatModel;
|
||||
import io.jpom.util.CommandUtil;
|
||||
import io.jpom.util.JvmUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MacOSProjectCommander
|
||||
* <p>
|
||||
* some commands cannot execute success on Mac OS
|
||||
*
|
||||
* @author Hotstrip
|
||||
*/
|
||||
public class MacOsProjectCommander extends AbstractProjectCommander {
|
||||
|
||||
@Override
|
||||
public String buildCommand(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) {
|
||||
String path = NodeProjectInfoModel.getClassPathLib(nodeProjectInfoModel);
|
||||
if (StrUtil.isBlank(path)) {
|
||||
return null;
|
||||
}
|
||||
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();
|
||||
return String.format("nohup %s %s %s" +
|
||||
" %s %s %s >> %s 2>&1 &",
|
||||
getRunJavaPath(nodeProjectInfoModel, false),
|
||||
javaCopyItem == null ? nodeProjectInfoModel.getJvm() : javaCopyItem.getJvm(),
|
||||
JvmUtil.getJpomPidTag(tag, nodeProjectInfoModel.allLib()),
|
||||
path,
|
||||
nodeProjectInfoModel.getMainClass(),
|
||||
javaCopyItem == null ? nodeProjectInfoModel.getArgs() : javaCopyItem.getArgs(),
|
||||
nodeProjectInfoModel.getAbsoluteLog(javaCopyItem));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetstatModel> listNetstat(int pId, boolean listening) {
|
||||
String cmd;
|
||||
if (listening) {
|
||||
cmd = "lsof -n -P -iTCP -sTCP:LISTEN |grep " + pId + " | head -20";
|
||||
} else {
|
||||
cmd = "lsof -n -P -iTCP -sTCP:CLOSE_WAIT |grep " + pId + " | head -20";
|
||||
}
|
||||
String result = CommandUtil.execSystemCommand(cmd);
|
||||
//DefaultSystemLog.getLog().debug("Mac OS lsof data: {}", result);
|
||||
List<String> netList = StrSplitter.splitTrim(result, "\n", true);
|
||||
if (netList == null || netList.size() <= 0) {
|
||||
return null;
|
||||
}
|
||||
List<NetstatModel> array = new ArrayList<>();
|
||||
for (String str : netList) {
|
||||
List<String> list = StrSplitter.splitTrim(str, " ", true);
|
||||
if (list.size() < 5) {
|
||||
continue;
|
||||
}
|
||||
NetstatModel netstatModel = new NetstatModel();
|
||||
netstatModel.setProtocol(list.get(0));
|
||||
netstatModel.setReceive(list.get(1));
|
||||
netstatModel.setSend(list.get(2));
|
||||
netstatModel.setLocal(list.get(3));
|
||||
netstatModel.setForeign(list.get(4));
|
||||
if ("tcp".equalsIgnoreCase(netstatModel.getProtocol())) {
|
||||
netstatModel.setStatus(CollUtil.get(list, 5));
|
||||
netstatModel.setName(CollUtil.get(list, 6));
|
||||
} else {
|
||||
netstatModel.setStatus(StrUtil.DASHED);
|
||||
netstatModel.setName(CollUtil.get(list, 5));
|
||||
}
|
||||
array.add(netstatModel);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stop(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) throws Exception {
|
||||
String result = super.stop(nodeProjectInfoModel, javaCopyItem);
|
||||
int pid = parsePid(result);
|
||||
if (pid > 0) {
|
||||
String kill = AbstractSystemCommander.getInstance().kill(FileUtil.file(nodeProjectInfoModel.allLib()), pid);
|
||||
if (loopCheckRun(nodeProjectInfoModel.getId(), false)) {
|
||||
// 强制杀进程
|
||||
String cmd = String.format("kill -9 %s", pid);
|
||||
CommandUtil.asyncExeLocalCommand(FileUtil.file(nodeProjectInfoModel.allLib()), cmd);
|
||||
}
|
||||
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();
|
||||
result = status(tag) + StrUtil.SPACE + kill;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -41,7 +41,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author User
|
||||
*/
|
||||
public class MacOSSystemCommander extends AbstractSystemCommander {
|
||||
public class MacOsSystemCommander extends AbstractSystemCommander {
|
||||
|
||||
@Override
|
||||
public JSONObject getAllMonitor() {
|
||||
@ -126,8 +126,8 @@ public class MacOSSystemCommander extends AbstractSystemCommander {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProcessModel> getProcessList() {
|
||||
String s = CommandUtil.execSystemCommand("top -l 1 | grep java");
|
||||
public List<ProcessModel> getProcessList(String processName) {
|
||||
String s = CommandUtil.execSystemCommand("top -l 1 | grep " + processName);
|
||||
return formatLinuxTop(s, false);
|
||||
}
|
||||
|
@ -76,13 +76,13 @@ public class WindowsSystemCommander extends AbstractSystemCommander {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProcessModel> getProcessList() {
|
||||
public List<ProcessModel> getProcessList(String processName) {
|
||||
Scheduler scheduler = CronUtil.getScheduler();
|
||||
Task task = scheduler.getTask(ID);
|
||||
if (task == null) {
|
||||
CronUtil.schedule(ID, "0 0/1 * * * ?", () -> {
|
||||
try {
|
||||
lastResult = CommandUtil.execSystemCommand("tasklist /V | findstr java");
|
||||
lastResult = CommandUtil.execSystemCommand("tasklist /V | findstr " + processName);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("执行控制台进程统计错误", e);
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -95,9 +94,9 @@ public class WelcomeController extends AbstractController {
|
||||
|
||||
|
||||
@RequestMapping(value = "processList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public String getProcessList() {
|
||||
List<ProcessModel> array = AbstractSystemCommander.getInstance().getProcessList();
|
||||
public String getProcessList(String processName) {
|
||||
processName = StrUtil.emptyToDefault(processName, "java");
|
||||
List<ProcessModel> array = AbstractSystemCommander.getInstance().getProcessList(processName);
|
||||
if (array != null && !array.isEmpty()) {
|
||||
array.sort(Comparator.comparingInt(ProcessModel::getPid));
|
||||
return JsonMessage.getString(200, "", array);
|
||||
@ -107,7 +106,6 @@ public class WelcomeController extends AbstractController {
|
||||
|
||||
|
||||
@RequestMapping(value = "kill.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public String kill(int pid) {
|
||||
long jpomAgentId = JpomManifest.getInstance().getPid();
|
||||
Assert.state(StrUtil.equals(StrUtil.toString(jpomAgentId), StrUtil.toString(pid)), "不支持在线关闭 Jpom Agent 进程");
|
||||
|
@ -105,7 +105,7 @@ public class AgentWebSocketConsoleHandle extends BaseAgentWebSocketHandle {
|
||||
private NodeProjectInfoModel checkProject(String projectId, String copyId, Session session) throws IOException {
|
||||
NodeProjectInfoModel nodeProjectInfoModel = projectInfoService.getItem(projectId);
|
||||
if (nodeProjectInfoModel == null) {
|
||||
SocketSessionUtil.send(session, "没有对应项目");
|
||||
SocketSessionUtil.send(session, "没有对应项目:" + projectId);
|
||||
session.close();
|
||||
return null;
|
||||
}
|
||||
|
@ -53,7 +53,12 @@ public abstract class BaseAgentWebSocketHandle {
|
||||
protected String getParameters(Session session, String name) {
|
||||
Map<String, List<String>> pathParameters = session.getRequestParameterMap();
|
||||
List<String> strings = pathParameters.get(name);
|
||||
return CollUtil.join(strings, StrUtil.COMMA);
|
||||
String join = CollUtil.join(strings, StrUtil.COMMA);
|
||||
if (StrUtil.isEmpty(join)) {
|
||||
Map<String, String> parameters = session.getPathParameters();
|
||||
return parameters.get(name);
|
||||
}
|
||||
return join;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,12 +41,12 @@ public class FileUtils {
|
||||
|
||||
private static JSONObject fileToJson(File file) {
|
||||
JSONObject jsonObject = new JSONObject(6);
|
||||
long sizeFile = FileUtil.size(file);
|
||||
if (file.isDirectory()) {
|
||||
jsonObject.put("isDirectory", true);
|
||||
long sizeFile = FileUtil.size(file);
|
||||
jsonObject.put("fileSize", FileUtil.readableFileSize(sizeFile));
|
||||
} else {
|
||||
jsonObject.put("fileSize", FileUtil.readableFileSize(file.length()));
|
||||
jsonObject.put("fileSize", FileUtil.readableFileSize(sizeFile));
|
||||
}
|
||||
jsonObject.put("filename", file.getName());
|
||||
long mTime = file.lastModified();
|
||||
|
@ -64,8 +64,8 @@ public class MacOSSystemCommanderTest {
|
||||
|
||||
DefaultSystemLog.getLog().info("-----------------------------");
|
||||
|
||||
MacOSSystemCommander macOSSystemCommander = new MacOSSystemCommander();
|
||||
MacOsSystemCommander macOSSystemCommander = new MacOsSystemCommander();
|
||||
macOSSystemCommander.getAllMonitor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,12 +93,25 @@ public interface BaseEnum {
|
||||
* @return 对应的枚举
|
||||
*/
|
||||
static <T extends BaseEnum> T getEnum(Class<? extends BaseEnum> t, Integer code) {
|
||||
return getEnum(t, code, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据枚举获取枚举对象
|
||||
*
|
||||
* @param t 枚举类型
|
||||
* @param code code
|
||||
* @param def 默认值
|
||||
* @param <T> 泛型
|
||||
* @return 对应的枚举
|
||||
*/
|
||||
static <T extends BaseEnum> T getEnum(Class<? extends BaseEnum> t, Integer code, T def) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
return def;
|
||||
}
|
||||
Map<Integer, BaseEnum> map = getMap(t);
|
||||
if (map == null) {
|
||||
return null;
|
||||
return def;
|
||||
}
|
||||
return (T) map.get(code);
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public abstract class BaseBuild {
|
||||
FileUtil.appendLines(CollectionUtil.toList(title), this.logFile, CharsetUtil.CHARSET_UTF_8);
|
||||
String s = ExceptionUtil.stacktraceToString(throwable);
|
||||
FileUtil.appendLines(CollectionUtil.toList(s), this.logFile, CharsetUtil.CHARSET_UTF_8);
|
||||
updateStatus(status);
|
||||
this.updateStatus(status);
|
||||
}
|
||||
|
||||
protected void log(String info) {
|
||||
|
@ -23,6 +23,8 @@
|
||||
package io.jpom.build;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import io.jpom.model.AfterOpt;
|
||||
import io.jpom.model.BaseModel;
|
||||
import io.jpom.model.data.BuildInfoModel;
|
||||
import io.jpom.model.enums.BuildReleaseMethod;
|
||||
@ -72,11 +74,22 @@ public class BuildExtraModule extends BaseModel {
|
||||
* 发布到ssh中的目录
|
||||
*/
|
||||
private String releasePath;
|
||||
|
||||
/**
|
||||
* 工作空间 ID
|
||||
*/
|
||||
private String workspaceId;
|
||||
/**
|
||||
* 增量同步
|
||||
*/
|
||||
private boolean diffSync;
|
||||
|
||||
public boolean isDiffSync() {
|
||||
return diffSync;
|
||||
}
|
||||
|
||||
public void setDiffSync(boolean diffSync) {
|
||||
this.diffSync = diffSync;
|
||||
}
|
||||
|
||||
public String getReleasePath() {
|
||||
return releasePath;
|
||||
@ -160,16 +173,30 @@ public class BuildExtraModule extends BaseModel {
|
||||
|
||||
public void updateValue(BuildHistoryLog buildHistoryLog) {
|
||||
//
|
||||
this.setAfterOpt(buildHistoryLog.getAfterOpt());
|
||||
this.setAfterOpt(ObjectUtil.defaultIfNull(buildHistoryLog.getAfterOpt(), AfterOpt.No.getCode()));
|
||||
this.setReleaseMethod(buildHistoryLog.getReleaseMethod());
|
||||
this.setReleaseCommand(buildHistoryLog.getReleaseCommand());
|
||||
this.setReleasePath(buildHistoryLog.getReleasePath());
|
||||
this.setReleaseMethodDataId(buildHistoryLog.getReleaseMethodDataId());
|
||||
this.setClearOld(buildHistoryLog.getClearOld());
|
||||
this.setClearOld(ObjectUtil.defaultIfNull(buildHistoryLog.getClearOld(), false));
|
||||
this.setResultDirFile(buildHistoryLog.getResultDirFile());
|
||||
this.setName(buildHistoryLog.getBuildName());
|
||||
//
|
||||
this.setId(buildHistoryLog.getBuildDataId());
|
||||
this.setWorkspaceId(buildHistoryLog.getWorkspaceId());
|
||||
this.setDiffSync(ObjectUtil.defaultIfNull(buildHistoryLog.getDiffSync(), false));
|
||||
}
|
||||
|
||||
public void fillLogValue(BuildHistoryLog buildHistoryLog) {
|
||||
//
|
||||
buildHistoryLog.setAfterOpt(ObjectUtil.defaultIfNull(this.getAfterOpt(), AfterOpt.No.getCode()));
|
||||
buildHistoryLog.setReleaseMethod(this.getReleaseMethod());
|
||||
buildHistoryLog.setReleaseCommand(this.getReleaseCommand());
|
||||
buildHistoryLog.setReleasePath(this.getReleasePath());
|
||||
buildHistoryLog.setReleaseMethodDataId(this.getReleaseMethodDataId());
|
||||
buildHistoryLog.setClearOld(this.isClearOld());
|
||||
buildHistoryLog.setResultDirFile(this.getResultDirFile());
|
||||
buildHistoryLog.setDiffSync(this.isDiffSync());
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -199,17 +199,20 @@ public class BuildInfoManage extends BaseBuild implements Runnable {
|
||||
this.logId = IdUtil.fastSimpleUUID();
|
||||
BuildHistoryLog buildHistoryLog = new BuildHistoryLog();
|
||||
// 更新其他配置字段
|
||||
buildHistoryLog.setResultDirFile(buildExtraModule.getResultDirFile());
|
||||
buildExtraModule.fillLogValue(buildHistoryLog);
|
||||
// buildHistoryLog.setResultDirFile(buildExtraModule.getResultDirFile());
|
||||
// buildHistoryLog.setReleaseMethod(buildExtraModule.getReleaseMethod());
|
||||
// buildHistoryLog.setReleaseMethodDataId(buildExtraModule.getReleaseMethodDataId());
|
||||
// buildHistoryLog.setAfterOpt(buildExtraModule.getAfterOpt());
|
||||
// buildHistoryLog.setReleasePath(buildExtraModule.getReleasePath());
|
||||
// buildHistoryLog.setReleaseCommand(buildExtraModule.getReleaseCommand());
|
||||
// buildHistoryLog.setClearOld(buildExtraModule.isClearOld());
|
||||
|
||||
buildHistoryLog.setTriggerBuildType(triggerBuildType);
|
||||
buildHistoryLog.setReleaseMethod(buildExtraModule.getReleaseMethod());
|
||||
buildHistoryLog.setReleaseMethodDataId(buildExtraModule.getReleaseMethodDataId());
|
||||
buildHistoryLog.setAfterOpt(buildExtraModule.getAfterOpt());
|
||||
buildHistoryLog.setBuildDataId(buildInfoModel.getId());
|
||||
buildHistoryLog.setReleasePath(buildExtraModule.getReleasePath());
|
||||
buildHistoryLog.setReleaseCommand(buildExtraModule.getReleaseCommand());
|
||||
buildHistoryLog.setBuildNumberId(buildInfoModel.getBuildId());
|
||||
buildHistoryLog.setBuildName(buildInfoModel.getName());
|
||||
buildHistoryLog.setClearOld(buildExtraModule.isClearOld());
|
||||
buildHistoryLog.setBuildDataId(buildInfoModel.getId());
|
||||
|
||||
//
|
||||
buildHistoryLog.setWorkspaceId(this.buildInfoModel.getWorkspaceId());
|
||||
buildHistoryLog.setId(this.logId);
|
||||
|
@ -137,11 +137,8 @@ public class ReleaseManage extends BaseBuild {
|
||||
//
|
||||
this.doOutGiving();
|
||||
} else if (releaseMethod == BuildReleaseMethod.Project.getCode()) {
|
||||
AfterOpt afterOpt = BaseEnum.getEnum(AfterOpt.class, this.buildExtraModule.getAfterOpt());
|
||||
if (afterOpt == null) {
|
||||
afterOpt = AfterOpt.No;
|
||||
}
|
||||
this.doProject(afterOpt, this.buildExtraModule.isClearOld());
|
||||
AfterOpt afterOpt = BaseEnum.getEnum(AfterOpt.class, this.buildExtraModule.getAfterOpt(), AfterOpt.No);
|
||||
this.doProject(afterOpt, this.buildExtraModule.isClearOld(), this.buildExtraModule.isDiffSync());
|
||||
} else if (releaseMethod == BuildReleaseMethod.Ssh.getCode()) {
|
||||
this.doSsh();
|
||||
} else if (releaseMethod == BuildReleaseMethod.LocalCommand.getCode()) {
|
||||
@ -294,21 +291,30 @@ public class ReleaseManage extends BaseBuild {
|
||||
}
|
||||
}
|
||||
|
||||
private void diffSyncProject() {
|
||||
File resultFile = this.resultFile;
|
||||
List<File> files = FileUtil.loopFiles(resultFile);
|
||||
this.log("还没有实现");
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布项目
|
||||
*
|
||||
* @param afterOpt 后续操作
|
||||
*/
|
||||
private void doProject(AfterOpt afterOpt, boolean clearOld) {
|
||||
private void doProject(AfterOpt afterOpt, boolean clearOld, boolean diffSync) {
|
||||
String releaseMethodDataId = this.buildExtraModule.getReleaseMethodDataId();
|
||||
String[] strings = StrUtil.splitToArray(releaseMethodDataId, CharPool.COLON);
|
||||
if (strings == null || strings.length != 2) {
|
||||
throw new JpomRuntimeException(releaseMethodDataId + " error");
|
||||
if (ArrayUtil.length(strings) != 2) {
|
||||
throw new IllegalArgumentException(releaseMethodDataId + " error");
|
||||
}
|
||||
NodeService nodeService = SpringUtil.getBean(NodeService.class);
|
||||
NodeModel nodeModel = nodeService.getByKey(strings[0]);
|
||||
Objects.requireNonNull(nodeModel, "节点不存在");
|
||||
|
||||
if (diffSync) {
|
||||
this.diffSyncProject();
|
||||
return;
|
||||
}
|
||||
File zipFile = BuildUtil.isDirPackage(this.resultFile);
|
||||
boolean unZip = true;
|
||||
if (zipFile == null) {
|
||||
|
@ -86,6 +86,8 @@ public class BuildInfoModel extends BaseWorkspaceModel {
|
||||
private String triggerToken;
|
||||
/**
|
||||
* 额外信息,JSON 字符串格式
|
||||
*
|
||||
* @see io.jpom.build.BuildExtraModule
|
||||
*/
|
||||
private String extraData;
|
||||
/**
|
||||
|
@ -80,6 +80,14 @@ public class BuildHistoryLog extends BaseWorkspaceModel {
|
||||
* 发布到ssh中的目录
|
||||
*/
|
||||
private String releasePath;
|
||||
/**
|
||||
* 触发构建类型 触发类型{0,手动,1 触发器,2 自动触发}
|
||||
*/
|
||||
private Integer triggerBuildType;
|
||||
/**
|
||||
* 增量同步
|
||||
*/
|
||||
private Boolean diffSync;
|
||||
/**
|
||||
* 关联的构建id
|
||||
*
|
||||
@ -96,10 +104,6 @@ public class BuildHistoryLog extends BaseWorkspaceModel {
|
||||
* @see BuildInfoModel#getBuildId()
|
||||
*/
|
||||
private Integer buildNumberId;
|
||||
/**
|
||||
* 触发构建类型 触发类型{0,手动,1 触发器,2 自动触发}
|
||||
*/
|
||||
private Integer triggerBuildType;
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
@ -150,6 +154,14 @@ public class BuildHistoryLog extends BaseWorkspaceModel {
|
||||
return hasLog;
|
||||
}
|
||||
|
||||
public Boolean getDiffSync() {
|
||||
return diffSync;
|
||||
}
|
||||
|
||||
public void setDiffSync(Boolean diffSync) {
|
||||
this.diffSync = diffSync;
|
||||
}
|
||||
|
||||
public void setHasLog(Boolean hasLog) {
|
||||
this.hasLog = hasLog;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
package io.jpom.model.log;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import io.jpom.model.BaseWorkspaceModel;
|
||||
import io.jpom.model.data.MonitorModel;
|
||||
import io.jpom.service.h2db.TableName;
|
||||
@ -110,6 +111,10 @@ public class MonitorNotifyLog extends BaseWorkspaceModel {
|
||||
return status;
|
||||
}
|
||||
|
||||
public boolean isStatus() {
|
||||
return ObjectUtil.defaultIfNull(status, false);
|
||||
}
|
||||
|
||||
public void setStatus(Boolean status) {
|
||||
this.status = status;
|
||||
}
|
||||
@ -183,14 +188,6 @@ public class MonitorNotifyLog extends BaseWorkspaceModel {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public Boolean isStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(boolean status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModifyUser(String modifyUser) {
|
||||
|
||||
|
@ -40,6 +40,7 @@ import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -51,6 +52,7 @@ import java.util.Map;
|
||||
public abstract class BaseProxyHandler extends BaseHandler {
|
||||
|
||||
private final NodeUrl nodeUrl;
|
||||
private boolean init;
|
||||
|
||||
public BaseProxyHandler(NodeUrl nodeUrl) {
|
||||
this.nodeUrl = nodeUrl;
|
||||
@ -75,6 +77,13 @@ public abstract class BaseProxyHandler extends BaseHandler {
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
this.init(session);
|
||||
}
|
||||
|
||||
private void init(WebSocketSession session) throws URISyntaxException, IOException {
|
||||
if (init) {
|
||||
return;
|
||||
}
|
||||
Map<String, Object> attributes = session.getAttributes();
|
||||
NodeModel nodeModel = (NodeModel) attributes.get("nodeInfo");
|
||||
UserModel userInfo = (UserModel) attributes.get("userInfo");
|
||||
@ -90,10 +99,12 @@ public abstract class BaseProxyHandler extends BaseHandler {
|
||||
if (this.showHelloMsg()) {
|
||||
session.sendMessage(new TextMessage(StrUtil.format("欢迎加入:{} 会话id:{} ", userInfo.getName(), session.getId())));
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
|
||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
|
||||
this.init(session);
|
||||
String msg = message.getPayload();
|
||||
Map<String, Object> attributes = session.getAttributes();
|
||||
ProxySession proxySession = (ProxySession) attributes.get("proxySession");
|
||||
|
@ -29,6 +29,7 @@ import io.jpom.plugin.Feature;
|
||||
import io.jpom.socket.BaseProxyHandler;
|
||||
import io.jpom.socket.ConsoleCommandOp;
|
||||
import io.jpom.socket.ProxySession;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -50,12 +51,17 @@ public class ConsoleHandler extends BaseProxyHandler {
|
||||
return new Object[]{"projectId", attributes.get("projectId"), "copyId", attributes.get("copyId")};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleTextMessage(Map<String, Object> attributes,
|
||||
ProxySession proxySession,
|
||||
JSONObject json,
|
||||
ConsoleCommandOp consoleCommandOp) {
|
||||
if(consoleCommandOp!=ConsoleCommandOp.heart) {
|
||||
if (consoleCommandOp != ConsoleCommandOp.heart) {
|
||||
super.logOpt(attributes, json);
|
||||
}
|
||||
proxySession.send(json.toString());
|
||||
|
@ -15,6 +15,5 @@ ALTER TABLE SSHTERMINALEXECUTELOG
|
||||
ALTER TABLE BUILDHISTORYLOG
|
||||
ADD IF NOT EXISTS triggerBuildType int DEFAULT 0 comment '触发类型{0,手动,1 触发器,2 自动触发}';
|
||||
|
||||
|
||||
ALTER TABLE BUILDHISTORYLOG
|
||||
ADD IF NOT EXISTS triggerBuildType int DEFAULT 0 comment '触发类型{0,手动,1 触发器,2 自动触发}';
|
||||
ADD IF NOT EXISTS diffSync TINYINT COMMENT '增量同步';
|
||||
|
@ -158,11 +158,11 @@ export function getNodeTop(nodeId) {
|
||||
}
|
||||
|
||||
// 获取进程列表
|
||||
export function getProcessList(nodeId) {
|
||||
export function getProcessList(data) {
|
||||
return axios({
|
||||
url: "/node/processList",
|
||||
method: "post",
|
||||
data: { nodeId },
|
||||
data: data,
|
||||
headers: {
|
||||
loading: "no",
|
||||
},
|
||||
|
@ -211,7 +211,25 @@
|
||||
<a-icon type="question-circle" theme="filled" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-switch v-model="tempExtraData.clearOld" checked-children="是" un-checked-children="否" />
|
||||
<a-row>
|
||||
<a-col :span="4">
|
||||
<a-switch v-model="tempExtraData.clearOld" checked-children="是" un-checked-children="否" />
|
||||
</a-col>
|
||||
<div v-if="temp.releaseMethod === 2">
|
||||
<a-col :span="4" style="text-align: right">
|
||||
<a-tooltip v-if="!temp.id">
|
||||
<template slot="title">
|
||||
差异发布是指对应构建产物和项目文件夹里面的文件是否存在差异,如果存在增量差异那么上传或者覆盖文件,如果是项目目录存在构建产物目录不存在对应的文件那么将删除项目目录里面的文件
|
||||
</template>
|
||||
<a-icon type="question-circle" theme="filled" />
|
||||
</a-tooltip>
|
||||
差异发布:
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-switch v-model="tempExtraData.diffSync" checked-children="是" un-checked-children="否" />
|
||||
</a-col>
|
||||
</div>
|
||||
</a-row>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item prop="webhook">
|
||||
<template slot="label">
|
||||
|
@ -395,7 +395,7 @@
|
||||
<template slot="label">
|
||||
是否解压
|
||||
<a-tooltip>
|
||||
<template slot="title"> 如果上传的压缩文件是否自动解压 </template>
|
||||
<template slot="title"> 如果上传的压缩文件是否自动解压 支持的压缩包类型有 tar.bz2, tar.gz, tar, bz2, zip, gz</template>
|
||||
<a-icon type="question-circle" theme="filled" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
@ -7,6 +7,15 @@
|
||||
<div id="top-chart">loading...</div>
|
||||
<a-divider>进程监控表格</a-divider>
|
||||
<!-- 进程表格数据 -->
|
||||
<div ref="filter" class="filter">
|
||||
<a-select @change="loadNodeProcess" v-model="processName" allowClear placeholder="进程类型" class="filter-item">
|
||||
<a-select-option value="java">java</a-select-option>
|
||||
<a-select-option value="python">python</a-select-option>
|
||||
<a-select-option value="mysql">mysql</a-select-option>
|
||||
<a-select-option value="php">php</a-select-option>
|
||||
</a-select>
|
||||
<!-- <a-button type="primary" @click="loadData">切换</a-button> -->
|
||||
</div>
|
||||
<a-table :loading="loading" :columns="columns" :data-source="processList" bordered rowKey="pid" class="node-table" :pagination="false">
|
||||
<a-tooltip slot="port" slot-scope="text" placement="topLeft" :title="text">
|
||||
<span>{{ text }}</span>
|
||||
@ -50,6 +59,7 @@ export default {
|
||||
monitorVisible: false,
|
||||
timeRange: "",
|
||||
historyData: [],
|
||||
processName: "java",
|
||||
columns: [
|
||||
{ title: "进程 ID", dataIndex: "pid", width: 100, ellipsis: true, scopedSlots: { customRender: "pid" } },
|
||||
{ title: "进程名称", dataIndex: "command", width: 150, ellipsis: true, scopedSlots: { customRender: "command" } },
|
||||
@ -190,9 +200,14 @@ export default {
|
||||
// 加载节点进程列表
|
||||
loadNodeProcess() {
|
||||
this.loading = true;
|
||||
getProcessList(this.node.id).then((res) => {
|
||||
getProcessList({
|
||||
nodeId: this.node.id,
|
||||
processName: this.processName,
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.processList = res.data;
|
||||
} else {
|
||||
this.processList = [];
|
||||
}
|
||||
this.loading = false;
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user