🔨 添加执行超时.

This commit is contained in:
lijiahang
2024-03-19 19:28:21 +08:00
parent 29e3565af9
commit d4039501b2
13 changed files with 105 additions and 40 deletions

View File

@@ -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<LogDomRef>): Promise<void>;
// 自适应
fit(): void;
// 关闭 client
closeClient(): void;

View File

@@ -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<string, LogAppenderConf>;
private readonly appenderRel: Record<string, LogAppenderConf>;
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);
}
// 关闭

View File

@@ -6,7 +6,35 @@
class="log-view">
<!-- 面板头部 -->
<div class="log-header">
header
<!-- 左侧信息 -->
<div class="log-header-left">
<a-space :size="12">
<!-- 状态 -->
<a-tag :color="getDictValue(execHostStatusKey, host.status, 'color')">
{{ getDictValue(execHostStatusKey, host.status) }}
</a-tag>
<!-- exitStatus -->
<a-tag v-if="host.exitStatus || host.exitStatus === 0"
:color="host.exitStatus === 0 ? 'arcoblue' : 'orangered'"
title="exit status">
<template #icon>
<icon-check v-if="host.exitStatus === 0" />
<icon-exclamation v-else />
</template>
<span class="tag-value">{{ host.exitStatus }}</span>
</a-tag>
<!-- 持续时间 -->
<a-tag color="arcoblue" title="持续时间">
<template #icon>
<icon-loading v-if="host.status === execHostStatus.WAITING || host.status === execHostStatus.RUNNING" />
<icon-clock-circle v-else />
</template>
<span class="tag-value">{{ formatDuration(host.startTime, host.finishTime) || '0s' }}</span>
</a-tag>
</a-space>
</div>
<!-- 右侧操作 -->
<div class="log-header-right">TODO</div>
</div>
<!-- 日志面板 -->
<div class="log-wrapper">
@@ -25,10 +53,13 @@
<script lang="ts" setup>
import type { VNodeRef } from 'vue';
import type { ExecCommandResponse, ExecCommandHostResponse } from '@/api/exec/exec';
import type { LogDomRef, ILogAppender } from '@/components/view/log-appender/appender.const';
import type { ExecCommandResponse } from '@/api/exec/exec';
import type { LogDomRef, ILogAppender } from '@/components/xtrem/log-appender/appender.const';
import { nextTick, ref } from 'vue';
import LogAppender from '@/components/view/log-appender/log-appender';
import { formatDuration } from '@/utils';
import { execHostStatus, execHostStatusKey } from '@/views/exec/exec-log/types/const';
import { useDictStore } from '@/store';
import LogAppender from '@/components/xtrem/log-appender/log-appender';
import 'xterm/css/xterm.css';
const props = defineProps<{
@@ -36,6 +67,8 @@
command: ExecCommandResponse;
}>();
const { getDictValue } = useDictStore();
const logRefs = ref<Array<LogDomRef>>([]);
const appender = ref<ILogAppender>();
@@ -80,7 +113,25 @@
.log-header {
width: 100%;
height: @header-height;
background: green;
padding: 8px;
border-radius: 4px 4px 0 0;
display: flex;
justify-content: space-between;
align-items: center;
background: var(--color-bg-1);
color: var(--color-text-1);
:deep(.arco-tag-icon) {
font-size: 14px;
}
.tag-value {
font-weight: 600;
}
&-right {
}
}
.log-wrapper {

View File

@@ -27,6 +27,7 @@
import { execStatus } from '@/views/exec/exec-log/types/const';
import LogPanelHost from './log-panel-host.vue';
import LogPanelView from './log-panel-view.vue';
import { useDictStore } from '@/store';
const emits = defineEmits(['back']);
@@ -65,7 +66,7 @@
if (hostStatus) {
host.status = hostStatus.status;
host.startTime = hostStatus.startTime;
host.finishTime = hostStatus.finishTime;
host.finishTime = hostStatus.finishTime || Date.now();
host.exitStatus = hostStatus.exitStatus;
host.errorMessage = hostStatus.errorMessage;
}
@@ -116,7 +117,6 @@
.host-container, .log-container {
height: 100%;
padding: 16px;
border-radius: 4px;
position: relative;
background: var(--color-bg-2);
@@ -124,6 +124,7 @@
.host-container {
width: @host-width;
padding: 16px;
margin-right: 16px;
}

View File

@@ -76,7 +76,7 @@
hostId: 4,
hostName: 'main-44',
hostAddress: '192.412.53.2',
status: 'FAILED'
status: 'TIMEOUT'
},]
} as ExecCommandResponse);
});

View File

@@ -221,7 +221,7 @@
const emits = defineEmits(['viewCommand', 'viewParams', 'viewLog', 'openClear']);
// TODO 日志 清理 ctrl日志 ctrl重新执行
// TODO 日志 ctrl日志 ctrl重新执行
const pagination = usePagination();
const rowSelection = useRowSelection();

View File

@@ -24,6 +24,8 @@ export const execHostStatus = {
COMPLETED: 'COMPLETED',
// 执行失败
FAILED: 'FAILED',
// 执行超时
TIMEOUT: 'TIMEOUT',
// 已中断
INTERRUPTED: 'INTERRUPTED',
};

View File

@@ -68,7 +68,7 @@
<script lang="ts" setup>
import type { OperatorLogQueryRequest, OperatorLogQueryResponse } from '@/api/user/operator-log';
import { ref, onMounted, onBeforeMount } from 'vue';
import { ref, onMounted } from 'vue';
import { operatorLogModuleKey, operatorLogTypeKey, operatorRiskLevelKey, operatorLogResultKey, dictKeys } from '../types/const';
import columns from '../types/table.columns';
import { getLogDetail } from '../types/const';
@@ -146,14 +146,12 @@
fetchTableData
});
// 加载字典值
onBeforeMount(async () => {
// 初始化
onMounted(async () => {
// 加载字典值
const dictStore = useDictStore();
await dictStore.loadKeys(dictKeys);
});
// 初始化
onMounted(() => {
// 设置表格列
let cols = columns.map(s => {
return { ...s };
}).filter(s => s.dataIndex !== 'username');
@@ -168,6 +166,7 @@
cols = cols.filter(s => s.dataIndex !== 'handle');
}
tableColumns.value = cols;
// 加载数据
fetchTableData();
});