diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecHostStatusEnum.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecHostStatusEnum.java index dce4250b..6a059818 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecHostStatusEnum.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecHostStatusEnum.java @@ -38,6 +38,11 @@ public enum ExecHostStatusEnum { */ FAILED(false), + /** + * 执行超时 + */ + TIMEOUT(false), + /** * 中断执行 */ diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecCommandHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecCommandHandler.java index 0d0ef508..e46a8479 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecCommandHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecCommandHandler.java @@ -24,7 +24,6 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Date; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; /** * 命令执行器 @@ -93,7 +92,7 @@ public class ExecCommandHandler implements IExecCommandHandler { this.updateStatus(ExecHostStatusEnum.FAILED, ex); } else if (executor.isTimeout()) { // 更新执行超时 - this.updateStatus(ExecHostStatusEnum.FAILED, new TimeoutException()); + this.updateStatus(ExecHostStatusEnum.TIMEOUT, null); } else { // 更新执行完成 this.updateStatus(ExecHostStatusEnum.COMPLETED, null); @@ -144,6 +143,9 @@ public class ExecCommandHandler implements IExecCommandHandler { // 失败 update.setFinishTime(new Date()); update.setErrorMessage(this.getErrorMessage(ex)); + } else if (ExecHostStatusEnum.TIMEOUT.equals(status)) { + // 超时 + update.setFinishTime(new Date()); } else if (ExecHostStatusEnum.INTERRUPTED.equals(status)) { // 中断 update.setFinishTime(new Date()); @@ -152,8 +154,6 @@ public class ExecCommandHandler implements IExecCommandHandler { log.info("ExecCommandHandler.updateStatus finish id: {}, effect: {}", id, effect); } - // TODO timeout - @Override public void write(String msg) { this.executor.write(msg); @@ -182,9 +182,7 @@ public class ExecCommandHandler implements IExecCommandHandler { Streams.close(executor); Streams.close(sessionStore); Streams.close(logOutputStream); - // TODO TEST 异步关闭日志 execLogManager.asyncCloseTailFile(execHostCommand.getLogPath()); - } /** @@ -195,9 +193,7 @@ public class ExecCommandHandler implements IExecCommandHandler { */ private String getErrorMessage(Exception ex) { String message; - if (ex instanceof TimeoutException) { - message = "执行超时"; - } else if (ex instanceof InvalidArgumentException) { + if (ex instanceof InvalidArgumentException) { message = ex.getMessage(); } else if (ex instanceof ConnectionRuntimeException) { message = "连接失败"; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/ExecLogTailHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/ExecLogTailHandler.java index 9d2b2a53..40044a9e 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/ExecLogTailHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/ExecLogTailHandler.java @@ -6,6 +6,7 @@ import com.orion.ops.framework.websocket.core.utils.WebSockets; import com.orion.ops.module.asset.define.AssetThreadPools; import com.orion.ops.module.asset.entity.dto.ExecHostLogTailDTO; import com.orion.ops.module.asset.entity.dto.ExecLogTailDTO; +import com.orion.ops.module.asset.handler.host.exec.log.constant.LogConst; import com.orion.ops.module.asset.handler.host.exec.log.manager.ExecLogManager; import com.orion.ops.module.asset.handler.host.exec.log.tracker.ExecLogTracker; import lombok.extern.slf4j.Slf4j; @@ -55,6 +56,11 @@ public class ExecLogTailHandler extends AbstractWebSocketHandler { @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) { + String payload = message.getPayload(); + // ping + if (LogConst.PING_PAYLOAD.equals(payload)) { + WebSockets.sendText(session, LogConst.PONG_PAYLOAD); + } } @Override @@ -68,16 +74,12 @@ public class ExecLogTailHandler extends AbstractWebSocketHandler { log.info("ExecLogTailHandler-afterConnectionClosed id: {}, code: {}, reason: {}", id, status.getCode(), status.getReason()); // 关闭会话 ExecLogTailDTO info = WebSockets.getAttr(session, ExtraFieldConst.INFO); - // 移除追踪器 TODO TEST + // 移除追踪器 for (ExecHostLogTailDTO host : info.getHosts()) { execLogManager.removeTracker(this.getTrackerId(id, info, host)); } } - // TODO ws://127.0.0.1:9200/orion/keep-alive/exec/log/ive0btemHxmEY0HyTm5 - // todo 首页元数据加载 - // todo 批量执行的 warn - /** * 获取追踪器 id * diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/constant/LogConst.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/constant/LogConst.java index c4f95f0b..a3118ab4 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/constant/LogConst.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/constant/LogConst.java @@ -9,6 +9,10 @@ package com.orion.ops.module.asset.handler.host.exec.log.constant; */ public interface LogConst { + String PING_PAYLOAD = "p"; + + String PONG_PAYLOAD = "p"; + String SEPARATOR = "|"; int TRACKER_OFFSET_LINE = 200; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/tracker/ExecLogTracker.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/tracker/ExecLogTracker.java index 229925d3..934ed8ec 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/tracker/ExecLogTracker.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/log/tracker/ExecLogTracker.java @@ -56,7 +56,6 @@ public class ExecLogTracker implements IExecLogTracker { // 开始监听文件 tracker.run(); // 监听完成回调 - // TODO test this.close = true; } catch (Exception e) { log.error("exec log tracker error path: {}", absolutePath, e); @@ -80,7 +79,6 @@ public class ExecLogTracker implements IExecLogTracker { @Override public void close() { - // TODO test log.info("ExecLogTracker.close path: {}", absolutePath); if (close) { return; diff --git a/orion-ops-ui/src/components/view/log-appender/appender.const.ts b/orion-ops-ui/src/components/xtrem/log-appender/appender.const.ts similarity index 95% rename from orion-ops-ui/src/components/view/log-appender/appender.const.ts rename to orion-ops-ui/src/components/xtrem/log-appender/appender.const.ts index 0d74d81c..ad327ec7 100644 --- a/orion-ops-ui/src/components/view/log-appender/appender.const.ts +++ b/orion-ops-ui/src/components/xtrem/log-appender/appender.const.ts @@ -8,7 +8,7 @@ import { CanvasAddon } from 'xterm-addon-canvas'; export const AppenderOption: ITerminalOptions = { theme: { foreground: '#FFFFFF', - background: '#212529', + background: '#202020', selectionBackground: '#B5D5FF', }, rightClickSelectsWord: true, @@ -47,9 +47,6 @@ export interface ILogAppender { // 初始化 init(refs: Array): Promise; - // 自适应 - fit(): void; - // 关闭 client closeClient(): void; diff --git a/orion-ops-ui/src/components/view/log-appender/log-appender.ts b/orion-ops-ui/src/components/xtrem/log-appender/log-appender.ts similarity index 87% rename from orion-ops-ui/src/components/view/log-appender/log-appender.ts rename to orion-ops-ui/src/components/xtrem/log-appender/log-appender.ts index 5dee1ac1..7bb3145b 100644 --- a/orion-ops-ui/src/components/view/log-appender/log-appender.ts +++ b/orion-ops-ui/src/components/xtrem/log-appender/log-appender.ts @@ -2,17 +2,19 @@ import type { ExecTailRequest } from '@/api/exec/exec'; import { getExecLogTailToken } from '@/api/exec/exec'; import type { ILogAppender, LogAddons, LogAppenderConf, LogDomRef } from './appender.const'; import { AppenderOption } from './appender.const'; -import { Terminal } from 'xterm'; import { webSocketBaseUrl } from '@/utils/env'; import { Message } from '@arco-design/web-vue'; import { createWebSocket } from '@/utils'; +import { Terminal } from 'xterm'; import { FitAddon } from 'xterm-addon-fit'; import { SearchAddon } from 'xterm-addon-search'; import { CanvasAddon } from 'xterm-addon-canvas'; +import { useDebounceFn } from '@vueuse/core'; +import { addEventListen, removeEventListen } from '@/utils/event'; -// todo ping -// todo SEARCH addon +// todo SEARCH addon setfixed // todo font-size totop copy tobottom selectall clear +// todo 批量执行的 warn // 执行日志 appender 实现 export default class LogAppender implements ILogAppender { @@ -21,13 +23,16 @@ export default class LogAppender implements ILogAppender { private client?: WebSocket; - private appenderRel: Record; + private readonly appenderRel: Record; private keepAliveTask?: number; + private readonly fitFn: () => {}; + constructor(config: ExecTailRequest) { this.config = config; this.appenderRel = {}; + this.fitFn = useDebounceFn(this.fit).bind(this); } // 初始化 @@ -56,6 +61,8 @@ export default class LogAppender implements ILogAppender { addons }; } + // 注册自适应事件 + addEventListen(window, 'resize', this.fitFn); } // 初始化插件 @@ -114,12 +121,15 @@ export default class LogAppender implements ILogAppender { // 关闭 view closeView(): void { + // 关闭 terminal Object.values(this.appenderRel).forEach(s => { s.terminal?.dispose(); if (s.addons) { Object.values(s.addons).forEach(s => s.dispose()); } }); + // 移除自适应事件 + removeEventListen(window, 'resize', this.fitFn); } // 关闭 diff --git a/orion-ops-ui/src/views/exec/exec-command/components/log-panel-view.vue b/orion-ops-ui/src/views/exec/exec-command/components/log-panel-view.vue index dafe64ea..40e2865f 100644 --- a/orion-ops-ui/src/views/exec/exec-command/components/log-panel-view.vue +++ b/orion-ops-ui/src/views/exec/exec-command/components/log-panel-view.vue @@ -6,7 +6,35 @@ class="log-view">
- header + +
+ + + + {{ getDictValue(execHostStatusKey, host.status) }} + + + + + {{ host.exitStatus }} + + + + + {{ formatDuration(host.startTime, host.finishTime) || '0s' }} + + +
+ +
TODO
@@ -25,10 +53,13 @@