Kaynağa Gözat

调整 dagent 模块

reghao 4 yıl önce
ebeveyn
işleme
3ac2c9e095
23 değiştirilmiş dosya ile 264 ekleme ve 265 silme
  1. 2 2
      common/src/main/java/cn/reghao/autodop/common/log/MqttAppender.java
  2. 3 1
      common/src/main/java/cn/reghao/autodop/common/msg/pub/clazz/INodeEventPubClazz.java
  3. 1 1
      common/src/main/java/cn/reghao/autodop/common/msg/pub/constant/NodeEventPubClazz.java
  4. 1 1
      common/src/main/java/cn/reghao/autodop/common/msg/pub/constant/PubClazz.java
  5. 4 4
      common/src/main/java/cn/reghao/autodop/common/msg/rpc/clazz/IAppRpcClazz.java
  6. 1 1
      common/src/main/java/cn/reghao/autodop/common/msg/rpc/constant/AppRpcClazz.java
  7. 1 1
      common/src/main/java/cn/reghao/autodop/common/msg/rpc/constant/RpcClazz.java
  8. 1 1
      common/src/main/java/cn/reghao/autodop/common/msg/rpc/dto/app/StatusParam.java
  9. 8 7
      dagent/src/main/java/cn/reghao/autodop/dagent/machine/NodeEventClazzPubImpl.java
  10. 2 2
      dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/MqttRpcListener.java
  11. 30 25
      dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/impl/AppRpcClazzDispatcher.java
  12. 45 114
      dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/impl/AppRpcClazzImpl.java
  13. 6 6
      dagent/src/main/java/cn/reghao/autodop/dagent/spring/DagentLifecycle.java
  14. 0 70
      dagent/src/main/resources/logback-spring.xml.bak
  15. 3 5
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/controller/page/MachineStatPageController.java
  16. 7 7
      dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/MqttSubListener.java
  17. 6 6
      dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/impl/pub/NodeEventPubClazzDispatcher.java
  18. 5 5
      dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/impl/pub/NodeEventPubClazzImpl.java
  19. 3 3
      dmaster/src/main/java/cn/reghao/autodop/dmaster/spring/DmasterLifecycle.java
  20. 4 2
      dmaster/src/main/resources/templates/app/bd/build.html
  21. 107 0
      dmaster/src/main/resources/templates/machine/host/dagentlog.html
  22. 14 1
      dmaster/src/main/resources/templates/machine/host/index.html
  23. 10 0
      dmaster/src/main/resources/templates/machine/stat/index.html

+ 2 - 2
common/src/main/java/cn/reghao/autodop/common/log/MqttAppender.java

@@ -7,7 +7,7 @@ import cn.reghao.autodop.common.mqtt.DefaultMqttClient;
 import cn.reghao.autodop.common.msg.Message;
 import cn.reghao.autodop.common.msg.MsgQueue;
 import cn.reghao.autodop.common.msg.pub.PubMsg;
-import cn.reghao.autodop.common.msg.pub.constant.NodePubClazz;
+import cn.reghao.autodop.common.msg.pub.constant.NodeEventPubClazz;
 import cn.reghao.autodop.common.msg.pub.dto.node.NodeLogDTO;
 import cn.reghao.jdkutil.serializer.JsonConverter;
 import org.eclipse.paho.client.mqttv3.MqttException;
@@ -41,7 +41,7 @@ public class MqttAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
     protected void append(ILoggingEvent event) {
         NodeLogDTO nodeLogDTO = nodeLogDTO(event);
         String jsonPayload = JsonConverter.objectToJson(nodeLogDTO);
-        PubMsg pubMsg = PubMsg.pubMsg(NodePubClazz.class.getSimpleName(), NodePubClazz.log.name(), jsonPayload);
+        PubMsg pubMsg = PubMsg.pubMsg(NodeEventPubClazz.class.getSimpleName(), NodeEventPubClazz.log.name(), jsonPayload);
         Message message = Message.pubMsg(pubMsg);
         try {
             mqttClient.pub(topic, 1, JsonConverter.objectToJson(message));

+ 3 - 1
common/src/main/java/cn/reghao/autodop/common/msg/pub/clazz/INodePubClazz.java → common/src/main/java/cn/reghao/autodop/common/msg/pub/clazz/INodeEventPubClazz.java

@@ -5,10 +5,12 @@ import cn.reghao.jdkutil.machine.data.detail.MachineDetail;
 import cn.reghao.jdkutil.machine.data.stat.MachineStat;
 
 /**
+ * 节点事件
+ *
  * @author reghao
  * @date 2021-09-15 09:19:14
  */
-public interface INodePubClazz {
+public interface INodeEventPubClazz {
     void start(MachineDetail machineDetail);
     void heartbeat(MachineStat machineStat);
     void shutdown(MachineStat machineStat);

+ 1 - 1
common/src/main/java/cn/reghao/autodop/common/msg/pub/constant/NodePubClazz.java → common/src/main/java/cn/reghao/autodop/common/msg/pub/constant/NodeEventPubClazz.java

@@ -4,6 +4,6 @@ package cn.reghao.autodop.common.msg.pub.constant;
  * @author reghao
  * @date 2021-09-15 09:19:14
  */
-public enum NodePubClazz {
+public enum NodeEventPubClazz {
     start, heartbeat, shutdown, log
 }

+ 1 - 1
common/src/main/java/cn/reghao/autodop/common/msg/pub/constant/PubClazz.java

@@ -5,5 +5,5 @@ package cn.reghao.autodop.common.msg.pub.constant;
  * @date 2021-09-15 11:51:17
  */
 public enum PubClazz {
-    NodePubClazz,
+    NodeEventPubClazz,
 }

+ 4 - 4
common/src/main/java/cn/reghao/autodop/common/msg/rpc/clazz/IAppRpcClazz.java

@@ -11,9 +11,9 @@ import cn.reghao.autodop.common.msg.rpc.dto.app.StatusResult;
  */
 public interface IAppRpcClazz {
     DeployResult deploy(DeployParam deployParam);
-    StatusResult status(StatusParam statusParam);
-    StatusResult restart(StatusParam statusParam);
-    StatusResult stop(StatusParam statusParam);
-    StatusResult start(StatusParam statusParam);
+    StatusResult restart(StatusParam statusParam) throws Exception;
+    StatusResult stop(StatusParam statusParam) throws Exception;
+    StatusResult start(StatusParam statusParam) throws Exception;
+    StatusResult status(StatusParam statusParam) throws Exception;
     void log();
 }

+ 1 - 1
common/src/main/java/cn/reghao/autodop/common/msg/rpc/constant/AppRpcClazz.java

@@ -5,5 +5,5 @@ package cn.reghao.autodop.common.msg.rpc.constant;
  * @date 2020-12-25 19:15:00
  */
 public enum AppRpcClazz {
-    deploy, status, restart, stop, start, log,
+    deploy, restart, stop, start, status, log,
 }

+ 1 - 1
common/src/main/java/cn/reghao/autodop/common/msg/rpc/constant/RpcClazz.java

@@ -5,5 +5,5 @@ package cn.reghao.autodop.common.msg.rpc.constant;
  * @date 2021-09-14 18:15:05
  */
 public enum RpcClazz {
-    AppRpcClazz,
+    AppRpcClazz
 }

+ 1 - 1
common/src/main/java/cn/reghao/autodop/common/msg/rpc/dto/app/StatusParam.java

@@ -14,6 +14,6 @@ import lombok.NoArgsConstructor;
 @AllArgsConstructor
 @Data
 public class StatusParam {
-    private String packerType;
+    private String packType;
     private String appId;
 }

+ 8 - 7
dagent/src/main/java/cn/reghao/autodop/dagent/machine/NodeClazzPubImpl.java → dagent/src/main/java/cn/reghao/autodop/dagent/machine/NodeEventClazzPubImpl.java

@@ -5,7 +5,7 @@ import cn.reghao.autodop.common.mqtt.DefaultMqttClient;
 import cn.reghao.autodop.common.msg.Message;
 import cn.reghao.autodop.common.msg.MsgQueue;
 import cn.reghao.autodop.common.msg.pub.PubMsg;
-import cn.reghao.autodop.common.msg.pub.constant.NodePubClazz;
+import cn.reghao.autodop.common.msg.pub.constant.NodeEventPubClazz;
 import cn.reghao.autodop.common.util.thread.ThreadPoolWrapper;
 import cn.reghao.jdkutil.machine.data.detail.MachineDetail;
 import cn.reghao.jdkutil.machine.data.stat.MachineStat;
@@ -21,23 +21,23 @@ import java.util.concurrent.TimeUnit;
  * @date 2021-09-03 09:22:42
  */
 @Slf4j
-public class NodeClazzPubImpl {
+public class NodeEventClazzPubImpl {
     private final ScheduledExecutorService scheduler;
     private final DefaultMqttClient mqttClient;
     private final Machine machine;
     private final String pubClazz;
     
-    public NodeClazzPubImpl(DefaultMqttClient mqttClient, Machine machine) {
+    public NodeEventClazzPubImpl(DefaultMqttClient mqttClient, Machine machine) {
         this.scheduler = ThreadPoolWrapper.scheduledThreadPool("heartbeat", 1);
         this.mqttClient = mqttClient;
         this.machine = machine;
-        this.pubClazz = NodePubClazz.class.getSimpleName();
+        this.pubClazz = NodeEventPubClazz.class.getSimpleName();
     }
     
     public void nodeStart() {
         MachineDetail machineDetail = machine.detail();
         String jsonPayload = JsonConverter.objectToJson(machineDetail);
-        PubMsg pubMsg = PubMsg.pubMsg(pubClazz, NodePubClazz.start.name(), jsonPayload);
+        PubMsg pubMsg = PubMsg.pubMsg(pubClazz, NodeEventPubClazz.start.name(), jsonPayload);
         pub(pubMsg);
     }
 
@@ -45,7 +45,7 @@ public class NodeClazzPubImpl {
         ThreadPoolWrapper.shutdownScheduler(scheduler);
         MachineStat machineStat = machine.stat();
         String jsonPayload = JsonConverter.objectToJson(machineStat);
-        PubMsg pubMsg = PubMsg.pubMsg(pubClazz, NodePubClazz.shutdown.name(), jsonPayload);
+        PubMsg pubMsg = PubMsg.pubMsg(pubClazz, NodeEventPubClazz.shutdown.name(), jsonPayload);
         pub(pubMsg);
     }
 
@@ -54,6 +54,7 @@ public class NodeClazzPubImpl {
     }
 
     public void nodeLog() {
+        // 使用 MqttAppender 发送日志
     }
     
     private void pub(PubMsg pubMsg) {
@@ -71,7 +72,7 @@ public class NodeClazzPubImpl {
         public void run() {
             MachineStat machineStat = machine.stat();
             String jsonPayload = JsonConverter.objectToJson(machineStat);
-            PubMsg pubMsg = PubMsg.pubMsg(pubClazz, NodePubClazz.heartbeat.name(), jsonPayload);
+            PubMsg pubMsg = PubMsg.pubMsg(pubClazz, NodeEventPubClazz.heartbeat.name(), jsonPayload);
             pub(pubMsg);
         }
     }

+ 2 - 2
dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/RpcListener.java → dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/MqttRpcListener.java

@@ -25,12 +25,12 @@ import java.lang.management.ManagementFactory;
  */
 @Slf4j
 @Component
-public class RpcListener implements MqttCallback {
+public class MqttRpcListener implements MqttCallback {
     private final long startTime;
     private final DefaultMqttClient mqttClient;
     private final AppRpcClazzDispatcher appRpcClazzDispatcher;
 
-    public RpcListener(DefaultMqttClient mqttClient, AppRpcClazzDispatcher appRpcClazzDispatcher) {
+    public MqttRpcListener(DefaultMqttClient mqttClient, AppRpcClazzDispatcher appRpcClazzDispatcher) {
         this.startTime = ManagementFactory.getRuntimeMXBean().getStartTime();
         this.mqttClient = mqttClient;
         this.appRpcClazzDispatcher = appRpcClazzDispatcher;

+ 30 - 25
dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/impl/AppRpcClazzDispatcher.java

@@ -28,31 +28,36 @@ public class AppRpcClazzDispatcher implements ClazzDispatcher<RpcMsg, RpcMsg> {
         String jsonParam = rpcMsg.getJsonParam();
         StatusParam statusParam;
         StatusResult statusResult;
-        switch (AppRpcClazz.valueOf(method)) {
-            case deploy:
-                DeployParam deployParam = JsonConverter.jsonToObject(jsonParam, DeployParam.class);
-                DeployResult deployResult = appRpcClazz.deploy(deployParam);
-                return rpcMsg.success(JsonConverter.objectToJson(deployResult));
-            case status:
-                statusParam = JsonConverter.jsonToObject(jsonParam, StatusParam.class);
-                statusResult = appRpcClazz.status(statusParam);
-                return rpcMsg.success(JsonConverter.objectToJson(statusResult));
-            case restart:
-                statusParam = JsonConverter.jsonToObject(jsonParam, StatusParam.class);
-                statusResult = appRpcClazz.restart(statusParam);
-                return rpcMsg.success(JsonConverter.objectToJson(statusResult));
-            case stop:
-                statusParam = JsonConverter.jsonToObject(jsonParam, StatusParam.class);
-                statusResult = appRpcClazz.stop(statusParam);
-                return rpcMsg.success(JsonConverter.objectToJson(statusResult));
-            case start:
-                statusParam = JsonConverter.jsonToObject(jsonParam, StatusParam.class);
-                statusResult = appRpcClazz.start(statusParam);
-                return rpcMsg.success(JsonConverter.objectToJson(statusResult));
-            case log:
-            default:
-                String err = String.format("找不到 %s 方法", method);
-                return rpcMsg.error(err);
+        try {
+            switch (AppRpcClazz.valueOf(method)) {
+                case deploy:
+                    DeployParam deployParam = JsonConverter.jsonToObject(jsonParam, DeployParam.class);
+                    DeployResult deployResult = appRpcClazz.deploy(deployParam);
+                    return rpcMsg.success(JsonConverter.objectToJson(deployResult));
+                case status:
+                    statusParam = JsonConverter.jsonToObject(jsonParam, StatusParam.class);
+                    statusResult = appRpcClazz.status(statusParam);
+                    return rpcMsg.success(JsonConverter.objectToJson(statusResult));
+                case restart:
+                    statusParam = JsonConverter.jsonToObject(jsonParam, StatusParam.class);
+                    statusResult = appRpcClazz.restart(statusParam);
+                    return rpcMsg.success(JsonConverter.objectToJson(statusResult));
+                case stop:
+                    statusParam = JsonConverter.jsonToObject(jsonParam, StatusParam.class);
+                    statusResult = appRpcClazz.stop(statusParam);
+                    return rpcMsg.success(JsonConverter.objectToJson(statusResult));
+                case start:
+                    statusParam = JsonConverter.jsonToObject(jsonParam, StatusParam.class);
+                    statusResult = appRpcClazz.start(statusParam);
+                    return rpcMsg.success(JsonConverter.objectToJson(statusResult));
+                case log:
+                    // TODO 待实现
+                default:
+                    String err = String.format("AppRpcClazz 中找不到 %s 方法", method);
+                    return rpcMsg.error(err);
+            }
+        } catch (Exception e) {
+            return rpcMsg.error(e.getMessage());
         }
     }
 }

+ 45 - 114
dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/impl/AppRpcClazzImpl.java

@@ -2,6 +2,7 @@ package cn.reghao.autodop.dagent.mqttsub.impl;
 
 import cn.reghao.autodop.common.machine.Machine;
 import cn.reghao.autodop.common.msg.rpc.clazz.IAppRpcClazz;
+import cn.reghao.autodop.common.msg.rpc.constant.AppRpcClazz;
 import cn.reghao.autodop.common.msg.rpc.dto.app.*;
 import cn.reghao.autodop.common.util.ExceptionUtil;
 import cn.reghao.autodop.dagent.app.AppService;
@@ -47,147 +48,77 @@ public class AppRpcClazzImpl implements IAppRpcClazz {
                     deployResult.setAppStatus(appStatus);
                     break;
                 default:
-                    String msg = "打包类型 " + deployParam.getPackType() + " 不存在";
+                    String msg = String.format("应用包类型 %s 不存在", deployParam.getPackType());
                     deployResult.setResult(Result.result(ResultStatus.ERROR, msg));
             }
         } catch (Exception e) {
             deployResult.setResult(Result.result(ResultStatus.FAIL, ExceptionUtil.errorMsg(e)));
         }
-        
-        //return RpcResultMsg.success(JsonConverter.objectToJson(deployResult));
         return deployResult;
     }
 
     @Override
-    public StatusResult status(StatusParam statusParam) {
+    public StatusResult restart(StatusParam statusParam) throws Exception {
         String appId = statusParam.getAppId();
-        String packerType = statusParam.getPackerType();
-
-        StatusResult statusResult;
-        try {
-            switch (PackType.valueOf(packerType)) {
-                case docker:
-                    statusResult = dockerAppServiceImpl.status(appId);
-                    break;
-                case zip:
-                    statusResult = zipAppServiceImpl.status(appId);
-                    break;
-                default:
-                    return null;
-                    //return RpcResultMsg.error("打包类型 " + statusParam.getPackerType() + " 不存在");
-            }
-        } catch (Exception e) {
-            return null;
-            //return RpcResultMsg.fail(ExceptionUtil.errorMsg(e));
-        }
-        
-        //return RpcResultMsg.success(JsonConverter.objectToJson(appStatus));
-        return statusResult;
+        String packType = statusParam.getPackType();
+        return appOps(appId, AppRpcClazz.restart.name(), packType);
     }
 
     @Override
-    public StatusResult restart(StatusParam statusParam) {
+    public StatusResult stop(StatusParam statusParam) throws Exception {
         String appId = statusParam.getAppId();
-        String packerType = statusParam.getPackerType();
-
-        /*StatusResult appStatus;
-        try {
-            switch (PackType.valueOf(packerType)) {
-                case docker:
-                    appStatus = dockerAppServiceImpl.restart(appId);
-                    break;
-                case zip:
-                    appStatus = zipAppServiceImpl.restart(appId);
-                    break;
-                default:
-                    return RpcResultMsg.error("打包类型 " + statusParam.getPackerType() + " 不存在");
-            }
-        } catch (Exception e) {
-            return RpcResultMsg.fail(ExceptionUtil.errorMsg(e));
-        }
-        
-        return RpcResultMsg.success(JsonConverter.objectToJson(appStatus));*/
-        return null;
+        String packType = statusParam.getPackType();
+        return appOps(appId, AppRpcClazz.stop.name(), packType);
     }
 
     @Override
-    public StatusResult stop(StatusParam statusParam) {
+    public StatusResult start(StatusParam statusParam) throws Exception {
         String appId = statusParam.getAppId();
-        String packerType = statusParam.getPackerType();
-
-        /*StatusResult appStatus;
-        try {
-            switch (PackType.valueOf(packerType)) {
-                case docker:
-                    appStatus = dockerAppServiceImpl.stop(appId);
-                    break;
-                case zip:
-                    appStatus = zipAppServiceImpl.stop(appId);
-                    break;
-                default:
-                    return RpcResultMsg.error("打包类型 " + statusParam.getPackerType() + " 不存在");
-            }
-        } catch (Exception e) {
-            return RpcResultMsg.fail(ExceptionUtil.errorMsg(e));
-        }
-
-        return RpcResultMsg.success(JsonConverter.objectToJson(appStatus));*/
-        return null;
+        String packType = statusParam.getPackType();
+        return appOps(appId, AppRpcClazz.start.name(), packType);
     }
 
     @Override
-    public StatusResult start(StatusParam statusParam) {
+    public StatusResult status(StatusParam statusParam) throws Exception {
         String appId = statusParam.getAppId();
-        String packerType = statusParam.getPackerType();
+        String packType = statusParam.getPackType();
+        return appOps(appId, AppRpcClazz.status.name(), packType);
+    }
 
-        /*StatusResult appStatus;
-        try {
-            switch (PackType.valueOf(packerType)) {
-                case docker:
-                    appStatus = dockerAppServiceImpl.start(appId);
-                    break;
-                case zip:
-                    appStatus = zipAppServiceImpl.start(appId);
-                    break;
-                default:
-                    return RpcResultMsg.error("打包类型 " + statusParam.getPackerType() + " 不存在");
-            }
-        } catch (Exception e) {
-            return RpcResultMsg.fail(ExceptionUtil.errorMsg(e));
+    private StatusResult appOps(String appId, String ops, String packType) throws Exception {
+        switch (AppRpcClazz.valueOf(ops)) {
+            case restart:
+                if (packType.equals(PackType.docker.name())) {
+                    return dockerAppServiceImpl.restart(appId);
+                } else {
+                    return zipAppServiceImpl.restart(appId);
+                }
+            case stop:
+                if (packType.equals(PackType.docker.name())) {
+                    return dockerAppServiceImpl.stop(appId);
+                } else {
+                    return zipAppServiceImpl.stop(appId);
+                }
+            case start:
+                if (packType.equals(PackType.docker.name())) {
+                    return dockerAppServiceImpl.start(appId);
+                } else {
+                    return zipAppServiceImpl.start(appId);
+                }
+            case status:
+                if (packType.equals(PackType.docker.name())) {
+                    return dockerAppServiceImpl.status(appId);
+                } else {
+                    return zipAppServiceImpl.status(appId);
+                }
+            default:
+                String msg = String.format("应用状态操作类型 %s 不存在", ops);
+                throw new Exception(msg);
         }
-
-        return RpcResultMsg.success(JsonConverter.objectToJson(appStatus));*/
-        return null;
     }
 
     @Override
     public void log() {
-        /*AppLogArgs appLogArgs = (AppLogArgs) param;
-        String packerType = appLogArgs.getPackerType();
-        long count = appLogArgs.getLogConfigs().stream().filter(LogConfig::getIsDir).count();
-        try {
-            switch (PackType.valueOf(packerType)) {
-                case docker:
-                    if (count > 0) {
-                        List<LogFile> logFiles = dockerAppServiceImpl.logFiles(appLogArgs);
-                        return RpcResultMsg.success(JsonConverter.objectToJson(logFiles));
-                    } else {
-                        List<String> logContent = dockerAppServiceImpl.logContent(appLogArgs);
-                        return RpcResultMsg.success(JsonConverter.objectToJson(logContent));
-                    }
-                case zip:
-                    if (count > 0) {
-                        List<LogFile> logFiles = zipAppServiceImpl.logFiles(appLogArgs);
-                        return RpcResultMsg.success(JsonConverter.objectToJson(logFiles));
-                    } else {
-                        List<String> logContent = zipAppServiceImpl.logContent(appLogArgs);
-                        return RpcResultMsg.success(JsonConverter.objectToJson(logContent));
-                    }
-                default:
-                    return RpcResultMsg.error("打包类型 " + appLogArgs.getPackerType() + " 不存在");
-            }
-        } catch (Exception e) {
-            return RpcResultMsg.fail(ExceptionUtil.errorMsg(e));
-        }*/
+        // TODO 应用日志待实现
     }
 }

+ 6 - 6
dagent/src/main/java/cn/reghao/autodop/dagent/spring/DagentLifecycle.java

@@ -7,8 +7,8 @@ import cn.reghao.autodop.common.machine.Machine;
 import cn.reghao.autodop.common.mqtt.DefaultMqttClient;
 import cn.reghao.autodop.common.msg.MsgQueue;
 import cn.reghao.autodop.common.msg.pub.dto.node.constant.AppId;
-import cn.reghao.autodop.dagent.machine.NodeClazzPubImpl;
-import cn.reghao.autodop.dagent.mqttsub.RpcListener;
+import cn.reghao.autodop.dagent.machine.NodeEventClazzPubImpl;
+import cn.reghao.autodop.dagent.mqttsub.MqttRpcListener;
 import cn.reghao.autodop.common.log.LoggerConfig;
 import lombok.extern.slf4j.Slf4j;
 import org.eclipse.paho.client.mqttv3.MqttException;
@@ -30,13 +30,13 @@ import java.util.List;
 @Configuration
 public class DagentLifecycle implements ApplicationRunner, DisposableBean {
     private final DefaultMqttClient mqttClient;
-    private final RpcListener rpcListener;
-    private final NodeClazzPubImpl nodeClazzPub;
+    private final MqttRpcListener rpcListener;
+    private final NodeEventClazzPubImpl nodeClazzPub;
 
-    public DagentLifecycle(DefaultMqttClient mqttClient, RpcListener rpcListener, Machine machine) {
+    public DagentLifecycle(DefaultMqttClient mqttClient, MqttRpcListener rpcListener, Machine machine) {
         this.mqttClient = mqttClient;
         this.rpcListener = rpcListener;
-        this.nodeClazzPub = new NodeClazzPubImpl(mqttClient, machine);
+        this.nodeClazzPub = new NodeEventClazzPubImpl(mqttClient, machine);
         initLogger();
     }
 

+ 0 - 70
dagent/src/main/resources/logback-spring.xml.bak

@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<configuration>
-    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
-        <layout class="ch.qos.logback.classic.PatternLayout">
-            <pattern>
-                %d{HH:mm:ss.SSS} [%thread] %-5level %c %M %L - %msg%n
-            </pattern>
-        </layout>
-    </appender>
-
-    <!-- info 日志文件 -->
-    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <level>ERROR</level>
-            <onMatch>DENY</onMatch>
-            <onMismatch>ACCEPT</onMismatch>
-        </filter>
-        <encoder>
-            <pattern>
-                %d{HH:mm:ss.SSS} %-5level %c %M %L - %msg%n
-            </pattern>
-            <charset>UTF-8</charset>
-        </encoder>
-        <!-- 滚动策略 -->
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <fileNamePattern>
-                logs/info.%d.log
-            </fileNamePattern>
-        </rollingPolicy>
-    </appender>
-
-    <!-- error 日志文件 -->
-    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
-            <level>ERROR</level>
-        </filter>
-        <encoder>
-            <pattern>
-                %d{HH:mm:ss.SSS} %-5level %c %M %L - %msg%n
-            </pattern>
-            <charset>UTF-8</charset>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <fileNamePattern>
-                logs/error.%d.log
-            </fileNamePattern>
-        </rollingPolicy>
-    </appender>
-
-    <springProfile name="dev">
-        <root level="info">
-            <appender-ref ref="consoleLog"/>
-        </root>
-    </springProfile>
-
-    <springProfile name="test">
-        <root level="info">
-            <appender-ref ref="fileInfoLog"/>
-            <appender-ref ref="fileErrorLog"/>
-        </root>
-    </springProfile>
-
-    <springProfile name="prod">
-        <root level="info">
-            <appender-ref ref="fileInfoLog"/>
-            <appender-ref ref="fileErrorLog"/>
-        </root>
-    </springProfile>
-</configuration>

+ 3 - 5
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/controller/page/MachineStatPageController.java

@@ -18,10 +18,8 @@ import org.springframework.web.bind.annotation.RequestParam;
 @RequestMapping("/machine/stat")
 public class MachineStatPageController {
     @ApiOperation(value = "机器状态列表页面")
-    @GetMapping("/")
-    public String statusPage(@RequestParam(value = "env", required = false) String env,
-                             @RequestParam(value = "machineIpv4", required = false) String machineIpv4,
-                             Model model) {
+    @GetMapping
+    public String statPage() {
         /*if (env == null) {
             env = EnvList.test.name();
         }
@@ -38,6 +36,6 @@ public class MachineStatPageController {
         model.addAttribute("env", env);
         model.addAttribute("page", page);
         model.addAttribute("list", pageList.getList());*/
-        return "/machine/status";
+        return "/machine/stat/index";
     }
 }

+ 7 - 7
dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/MessageListener.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/MqttSubListener.java

@@ -8,7 +8,7 @@ import cn.reghao.autodop.common.msg.pub.constant.PubClazz;
 import cn.reghao.autodop.common.msg.rpc.RpcMsg;
 import cn.reghao.autodop.common.msg.rpc.constant.RpcClazz;
 import cn.reghao.autodop.dmaster.mqttsub.impl.rpcresult.AppRpcClazzResultDispatcher;
-import cn.reghao.autodop.dmaster.mqttsub.impl.pub.NodePubClazzDispatcher;
+import cn.reghao.autodop.dmaster.mqttsub.impl.pub.NodeEventPubClazzDispatcher;
 import cn.reghao.jdkutil.serializer.JsonConverter;
 import lombok.extern.slf4j.Slf4j;
 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
@@ -24,15 +24,15 @@ import org.springframework.stereotype.Component;
  */
 @Slf4j
 @Component
-public class MessageListener implements MqttCallback {
-    private final NodePubClazzDispatcher nodePubClazzDispatcher;
+public class MqttSubListener implements MqttCallback {
+    private final NodeEventPubClazzDispatcher nodeEventPubClazzDispatcher;
     private final AppRpcClazzResultDispatcher appRpcClazzResultDispatcher;
     private final DefaultMqttClient defaultMqttClient;
 
-    public MessageListener(NodePubClazzDispatcher nodePubClazzDispatcher,
+    public MqttSubListener(NodeEventPubClazzDispatcher nodeEventPubClazzDispatcher,
                            AppRpcClazzResultDispatcher appRpcClazzResultDispatcher,
                            DefaultMqttClient defaultMqttClient) {
-        this.nodePubClazzDispatcher = nodePubClazzDispatcher;
+        this.nodeEventPubClazzDispatcher = nodeEventPubClazzDispatcher;
         this.appRpcClazzResultDispatcher = appRpcClazzResultDispatcher;
         this.defaultMqttClient = defaultMqttClient;
     }
@@ -67,8 +67,8 @@ public class MessageListener implements MqttCallback {
         String method = pubMsg.getMethod();
         String jsonPayload = pubMsg.getJsonPayload();
         switch (PubClazz.valueOf(clazz)) {
-            case NodePubClazz:
-                nodePubClazzDispatcher.dispatch(pubMsg);
+            case NodeEventPubClazz:
+                nodeEventPubClazzDispatcher.dispatch(pubMsg);
                 break;
             default:
                 ;

+ 6 - 6
dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/impl/pub/NodePubClazzDispatcher.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/impl/pub/NodeEventPubClazzDispatcher.java

@@ -2,7 +2,7 @@ package cn.reghao.autodop.dmaster.mqttsub.impl.pub;
 
 import cn.reghao.autodop.common.msg.ClazzDispatcher;
 import cn.reghao.autodop.common.msg.pub.PubMsg;
-import cn.reghao.autodop.common.msg.pub.constant.NodePubClazz;
+import cn.reghao.autodop.common.msg.pub.constant.NodeEventPubClazz;
 import cn.reghao.autodop.common.msg.pub.dto.node.NodeLogDTO;
 import cn.reghao.jdkutil.machine.data.detail.MachineDetail;
 import cn.reghao.jdkutil.machine.data.stat.MachineStat;
@@ -16,10 +16,10 @@ import org.springframework.stereotype.Component;
  */
 @Slf4j
 @Component
-public class NodePubClazzDispatcher implements ClazzDispatcher<PubMsg, Void> {
-    private final NodePubClazzImpl nodePubClazz;
+public class NodeEventPubClazzDispatcher implements ClazzDispatcher<PubMsg, Void> {
+    private final NodeEventPubClazzImpl nodePubClazz;
 
-    public NodePubClazzDispatcher(NodePubClazzImpl nodePubClazz) {
+    public NodeEventPubClazzDispatcher(NodeEventPubClazzImpl nodePubClazz) {
         this.nodePubClazz = nodePubClazz;
     }
 
@@ -27,7 +27,7 @@ public class NodePubClazzDispatcher implements ClazzDispatcher<PubMsg, Void> {
     public Void dispatch(PubMsg pubMsg) {
         String method = pubMsg.getMethod();
         String jsonPayload = pubMsg.getJsonPayload();
-        switch (NodePubClazz.valueOf(method)) {
+        switch (NodeEventPubClazz.valueOf(method)) {
             case start:
                 MachineDetail machineDetail = JsonConverter.jsonToObject(jsonPayload, MachineDetail.class);
                 nodePubClazz.start(machineDetail);
@@ -52,7 +52,7 @@ public class NodePubClazzDispatcher implements ClazzDispatcher<PubMsg, Void> {
     }
 
     public void process(String method, String jsonPayload) {
-        switch (NodePubClazz.valueOf(method)) {
+        switch (NodeEventPubClazz.valueOf(method)) {
             case start:
                 MachineDetail machineDetail = JsonConverter.jsonToObject(jsonPayload, MachineDetail.class);
                 nodePubClazz.start(machineDetail);

+ 5 - 5
dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/impl/pub/NodePubClazzImpl.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/impl/pub/NodeEventPubClazzImpl.java

@@ -1,6 +1,6 @@
 package cn.reghao.autodop.dmaster.mqttsub.impl.pub;
 
-import cn.reghao.autodop.common.msg.pub.clazz.INodePubClazz;
+import cn.reghao.autodop.common.msg.pub.clazz.INodeEventPubClazz;
 import cn.reghao.autodop.common.msg.pub.dto.node.NodeLogDTO;
 import cn.reghao.autodop.common.msg.pub.dto.node.constant.NodeStatus;
 import cn.reghao.autodop.dmaster.machine.db.crud.MachineHostCrud;
@@ -20,16 +20,16 @@ import org.springframework.stereotype.Service;
  * @date 2021-10-15 16:39:48
  */
 @Service
-public class NodePubClazzImpl implements INodePubClazz {
+public class NodeEventPubClazzImpl implements INodeEventPubClazz {
     private final MachineInfoQuery infoQuery;
     private final MachineInfoCrud infoCrud;
     private final MachineHostQuery hostQuery;
     private final MachineHostCrud hostCrud;
     private final NodeLogCrud nodeLogCrud;
 
-    public NodePubClazzImpl(MachineInfoQuery infoQuery, MachineInfoCrud infoCrud,
-                            MachineHostQuery hostQuery, MachineHostCrud hostCrud,
-                            NodeLogCrud nodeLogCrud) {
+    public NodeEventPubClazzImpl(MachineInfoQuery infoQuery, MachineInfoCrud infoCrud,
+                                 MachineHostQuery hostQuery, MachineHostCrud hostCrud,
+                                 NodeLogCrud nodeLogCrud) {
         this.infoQuery = infoQuery;
         this.infoCrud = infoCrud;
         this.hostQuery = hostQuery;

+ 3 - 3
dmaster/src/main/java/cn/reghao/autodop/dmaster/spring/DmasterLifecycle.java

@@ -9,7 +9,7 @@ import cn.reghao.autodop.common.msg.MsgQueue;
 import cn.reghao.autodop.dmaster.app.model.constant.EnvList;
 import cn.reghao.autodop.dmaster.app.model.po.config.build.BuildDir;
 import cn.reghao.autodop.dmaster.app.service.config.BuildDirService;
-import cn.reghao.autodop.dmaster.mqttsub.MessageListener;
+import cn.reghao.autodop.dmaster.mqttsub.MqttSubListener;
 import cn.reghao.autodop.dmaster.machine.db.crud.NodeLogCrud;
 import cn.reghao.autodop.dmaster.sys.db.crud.SysEnvCrud;
 import cn.reghao.autodop.dmaster.sys.db.query.SysEnvQuery;
@@ -32,13 +32,13 @@ import java.util.List;
 @Slf4j
 @Component
 public class DmasterLifecycle implements ApplicationRunner, DisposableBean {
-    private final MessageListener messageListener;
+    private final MqttSubListener messageListener;
     private final DefaultMqttClient mqttClient;
     private final BuildDirService buildDirService;
     private SysEnvQuery sysEnvQuery;
     private final SysEnvCrud sysEnvCrud;
 
-    public DmasterLifecycle(NodeLogCrud nodeLogCrud, MessageListener messageListener, BuildDirService buildDirService,
+    public DmasterLifecycle(NodeLogCrud nodeLogCrud, MqttSubListener messageListener, BuildDirService buildDirService,
                             DefaultMqttClient mqttClient, SysEnvQuery sysEnvQuery, SysEnvCrud sysEnvCrud) {
         this.messageListener = messageListener;
         this.buildDirService = buildDirService;

+ 4 - 2
dmaster/src/main/resources/templates/app/bd/build.html

@@ -47,7 +47,7 @@
                     <th class="sortable" data-field="httpPort">HTTP 端口</th>
                     <th class="sortable" data-field="commitId">当前构建版本</th>
                     <th class="sortable" data-field="commitTime">提交时间</th>
-                    <th class="sortable" data-field="result">构建结果</th>
+                    <th class="sortable" data-field="result">结果</th>
                     <th class="sortable" data-field="buildTime">构建时间</th>
                     <!--<th class="sortable" data-field="packagePath">包路径</th>-->
                     <th class="sortable" data-field="buildBy">构建用户</th>
@@ -79,6 +79,8 @@
                         <a class="ajax-post" th:href="@{'/api/app/bd/build?appId='+${item.appId}}">构建</a>
                         <a class="open-popup" data-title="应用部署" th:attr="data-url=@{'/app/deploy/'+${item.appId}}"
                            data-size="1000,500" href="#">部署</a>
+                        <a class="open-popup" data-title="构建历史" th:attr="data-url=@{'/app/deploy/'+${item.appId}}"
+                           data-size="1000,500" href="#">构建历史</a>
                     </td>
                 </tr>
                 </tbody>
@@ -103,7 +105,7 @@
         if (text === '成功') {
             $(this).css("color", "#009688")
         } else {
-            $(this).css("color", "#ff4500")
+            $(this).css("color", "#ff0000")
         }
     })
 </script>

+ 107 - 0
dmaster/src/main/resources/templates/machine/host/dagentlog.html

@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body>
+    <div class="timo-detail-page">
+        <div class="timo-detail-title">操作系统</div>
+        <table class="layui-table timo-detail-table">
+            <thead>
+            <tr>
+                <th data-field="name">名字</th>
+                <th data-field="arch">架构</th>
+                <th data-field="version">版本</th>
+                <th data-field="byteOrder">字节序</th>
+                <th data-field="bootTime">启动时间</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr>
+                <td th:text="${machine.name}"></td>
+                <td th:text="${machine.arch}"></td>
+                <td th:text="${machine.version}"></td>
+                <td th:text="${machine.byteOrder}"></td>
+                <td th:text="${machine.bootTime}"></td>
+            </tr>
+            </tbody>
+        </table>
+        <div class="timo-detail-title">网络</div>
+        <table class="layui-table timo-detail-table">
+            <thead>
+            <tr>
+                <th data-field="iface">网卡接口</th>
+                <th data-field="mac">MAC 地址</th>
+                <th data-field="ipv4">IPv4 地址</th>
+                <th data-field="pubicIpv4">IPv4 公网地址</th>
+                <th data-field="ipv6">IPv6 地址</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr th:each="item:${machine.networkInfos}">
+                <td th:text="${item.iface}"></td>
+                <td th:text="${item.mac}"></td>
+                <td th:text="${item.ipv4}"></td>
+                <td th:text="${item.publicIpv4}"></td>
+                <td th:text="${item.ipv6}"></td>
+            </tr>
+            </tbody>
+        </table>
+        <div class="timo-detail-title">CPU</div>
+        <table class="layui-table timo-detail-table">
+            <thead>
+            <tr>
+                <th data-field="vendor">品牌</th>
+                <th data-field="modelName">型号</th>
+                <th data-field="physicalCore">物理核</th>
+                <th data-field="logicalCore">逻辑核</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr>
+                <td th:text="${machine.vendor}"></td>
+                <td th:text="${machine.modelName}"></td>
+                <td th:text="${machine.physicalCore}"></td>
+                <td th:text="${machine.logicalCore}"></td>
+            </tr>
+            </tbody>
+        </table>
+        <div class="timo-detail-title">内存</div>
+        <table class="layui-table timo-detail-table">
+            <thead>
+            <tr>
+                <th data-field="memTotal">物理内存总量</th>
+                <th data-field="swapTotal">Swap 分区总量</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr>
+                <td th:text="${machine.memTotal}"></td>
+                <td th:text="${machine.swapTotal}"></td>
+            </tr>
+            </tbody>
+        </table>
+        <div class="timo-detail-title">磁盘</div>
+        <table class="layui-table timo-detail-table">
+            <thead>
+            <tr>
+                <th data-field="vendor">磁盘路径</th>
+                <th data-field="modelName">挂载分区</th>
+                <th data-field="physicalCore">文件系统</th>
+                <th data-field="logicalCore">磁盘总量</th>
+                <th data-field="logicalCore">inode 总量</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr th:each="item:${machine.diskInfoVOs}">
+                <td th:text="${item.diskPath}"></td>
+                <td th:text="${item.mountedOn}"></td>
+                <td th:text="${item.fsType}"></td>
+                <td th:text="${item.total}"></td>
+                <td th:text="${item.inodeTotal}"></td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+<script th:replace="/common/template :: script"></script>
+</body>
+</html>

+ 14 - 1
dmaster/src/main/resources/templates/machine/host/index.html

@@ -62,7 +62,7 @@
                         <i class="layui-icon layui-icon-ok"></i></label></td>
                     <td th:text="${item.machineIpv4}">机器地址</td>
                     <td th:text="${item.bootTime}">启动时间</td>
-                    <td th:text="${item.status}">当前状态</td>
+                    <td class="machine-status" th:text="${item.status}">当前状态</td>
                     <td th:text="${item.lastCheck}">上次心跳时间</td>
                     <td th:text="${item.osArch}">系统架构</td>
                     <td th:text="${item.osName}">系统名字</td>
@@ -76,8 +76,12 @@
                            th:attr="data-url=@{'/machine/host/sshauth/'+${item.machineId}}" href="#">设置</a>
                     </td>
                     <td>
+                        <!--<a class="open-popup" data-title="机器管理" th:attr="data-url=@{'/machine/stat'}"
+                           data-size="max" href="#">管理</a>-->
                         <a class="open-popup" data-title="WebTerminal" th:attr="data-url=@{'/machine/host/webssh/'+${item.machineId}}"
                            href="#">SSH 终端</a>
+                        <a class="open-popup" data-title="dagent 日志" th:attr="data-url=@{'/machine/host/detail/'+${item.machineId}}"
+                           data-size="960,480" href="#">dagent 日志</a>
                         <a class="open-popup" data-title="机器详细信息" th:attr="data-url=@{'/machine/host/detail/'+${item.machineId}}"
                            data-size="960,480" href="#">详细</a>
                         <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.machineId} + ' 机器?'"
@@ -100,6 +104,15 @@
         url = '?env=' + param
         window.location.href = window.location.pathname + url;
     }
+
+    $(".machine-status").each(function () {
+        var text = $(this).text().trim()
+        if (text === 'Online') {
+            $(this).css("color", "#009688")
+        } else {
+            $(this).css("color", "#ff0000")
+        }
+    })
 </script>
 </body>
 </html>

+ 10 - 0
dmaster/src/main/resources/templates/machine/stat/index.html

@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body>
+    <div class="timo-detail-page">
+    </div>
+<script th:replace="/common/template :: script"></script>
+</body>
+</html>