feat: 网元日志文件获取查看,抓包单独查看
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { request } from '@/plugins/http-fetch';
|
||||
|
||||
/**
|
||||
* 查询文件列表列表
|
||||
* 查询网元端文件列表
|
||||
* @param query 查询参数
|
||||
* @returns object
|
||||
*/
|
||||
@@ -14,7 +14,7 @@ export function listNeFiles(query: Record<string, any>) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 从网元端获取文件
|
||||
* 从网元到本地获取文件
|
||||
* @param query 查询参数
|
||||
* @returns object
|
||||
*/
|
||||
@@ -27,3 +27,24 @@ export function getNeFile(query: Record<string, any>) {
|
||||
timeout: 180_000,
|
||||
});
|
||||
}
|
||||
|
||||
// 从网元到本地获取目录压缩为ZIP
|
||||
export function getNeDirZip(data: Record<string, any>) {
|
||||
return request({
|
||||
url: '/ne/action/pullDirZip',
|
||||
method: 'get',
|
||||
params: data,
|
||||
responseType: 'blob',
|
||||
timeout: 60_000,
|
||||
});
|
||||
}
|
||||
|
||||
// 查看网元端文件内容
|
||||
export function getNeViewFile(data: Record<string, any>) {
|
||||
return request({
|
||||
url: '/ne/action/viewFile',
|
||||
method: 'get',
|
||||
params: data,
|
||||
timeout: 60_000,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,17 +20,6 @@ export function dumpStop(data: Record<string, string>) {
|
||||
});
|
||||
}
|
||||
|
||||
// 网元抓包PACP 下载
|
||||
export function dumpDownload(data: Record<string, any>) {
|
||||
return request({
|
||||
url: '/trace/tcpdump/download',
|
||||
method: 'get',
|
||||
params: data,
|
||||
responseType: 'blob',
|
||||
timeout: 60_000,
|
||||
});
|
||||
}
|
||||
|
||||
// UPF标准版内部抓包
|
||||
export function traceUPF(data: Record<string, string>) {
|
||||
return request({
|
||||
|
||||
@@ -1110,8 +1110,8 @@ export default {
|
||||
fileUPFTip: 'UPF internal packet capture and analysis packet',
|
||||
textStart: "Start",
|
||||
textStop: "Stop",
|
||||
textLog: "Log",
|
||||
textLogMsg: "Log Info",
|
||||
textLog: "LogFile",
|
||||
textLogMsg: "LogFile Info",
|
||||
textDown: "Download",
|
||||
downTip: "Are you sure you want to download the {title} capture data file?",
|
||||
downOk: "{title} file download complete",
|
||||
|
||||
@@ -1110,8 +1110,8 @@ export default {
|
||||
fileUPFTip: 'UPF内部抓包分析包',
|
||||
textStart: "开始",
|
||||
textStop: "停止",
|
||||
textLog: "日志",
|
||||
textLogMsg: "日志信息",
|
||||
textLog: "日志文件",
|
||||
textLogMsg: "日志文件信息",
|
||||
textDown: "下载",
|
||||
downTip: "确认要下载 {title} 抓包数据文件吗?",
|
||||
downOk: "{title} 文件下载完成",
|
||||
|
||||
@@ -204,11 +204,13 @@ function fnDirCD(dir: string, index?: number) {
|
||||
|
||||
/**网元类型选择对应修改 */
|
||||
function fnNeChange(keys: any, _: any) {
|
||||
if (!Array.isArray(keys)) return;
|
||||
const neType = keys[0];
|
||||
const neId = keys[1];
|
||||
// 不是同类型时需要重新加载
|
||||
if (Array.isArray(keys) && queryParams.neType !== keys[0]) {
|
||||
const neType = keys[0];
|
||||
if (queryParams.neType !== neType || queryParams.neId !== neId) {
|
||||
queryParams.neType = neType;
|
||||
queryParams.neId = keys[1];
|
||||
queryParams.neId = neId;
|
||||
if (neType === 'IMS') {
|
||||
nePathArr.value = ['/var/log/ims'];
|
||||
queryParams.search = '';
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Modal, message } from 'ant-design-vue/lib';
|
||||
import { parseDateToStr } from '@/utils/date-utils';
|
||||
import { getNeFile, listNeFiles } from '@/api/tool/neFile';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import ViewDrawer from '@/views/logManage/neFile/components/ViewDrawer.vue';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
import useTabsStore from '@/store/modules/tabs';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
@@ -218,16 +219,18 @@ function fnDirCD(dir: string, index?: number) {
|
||||
|
||||
/**网元类型选择对应修改 */
|
||||
function fnNeChange(keys: any, _: any) {
|
||||
if (!Array.isArray(keys)) return;
|
||||
const neType = keys[0];
|
||||
const neId = keys[1];
|
||||
// 不是同类型时需要重新加载
|
||||
if (Array.isArray(keys) && queryParams.neType !== keys[0]) {
|
||||
const neType = keys[0];
|
||||
if (queryParams.neType !== neType || queryParams.neId !== neId) {
|
||||
queryParams.neType = neType;
|
||||
queryParams.neId = keys[1];
|
||||
queryParams.neId = neId;
|
||||
if (neType === 'UPF' && tmp.value) {
|
||||
nePathArr.value = ['/tmp'];
|
||||
queryParams.search = `${neType}_${keys[1]}`;
|
||||
queryParams.search = `${neType}_${neId}`;
|
||||
} else {
|
||||
nePathArr.value = [`/tmp/omc/tcpdump/${neType.toLowerCase()}/${keys[1]}`];
|
||||
nePathArr.value = [`/tmp/omc/tcpdump/${neType.toLowerCase()}/${neId}`];
|
||||
queryParams.search = '';
|
||||
}
|
||||
fnGetList(1);
|
||||
@@ -270,6 +273,25 @@ function fnGetList(pageNum?: number) {
|
||||
});
|
||||
}
|
||||
|
||||
/**抽屉状态 */
|
||||
const viewDrawerState = reactive({
|
||||
visible: false,
|
||||
/**文件路径 /var/log/amf.log */
|
||||
filePath: '',
|
||||
/**网元类型 */
|
||||
neType: '',
|
||||
/**网元ID */
|
||||
neId: '',
|
||||
});
|
||||
|
||||
/**打开抽屉查看 */
|
||||
function fnDrawerOpen(row: Record<string, any>) {
|
||||
viewDrawerState.filePath = [...nePathArr.value, row.fileName].join('/');
|
||||
viewDrawerState.neType = neTypeSelect.value[0];
|
||||
viewDrawerState.neId = neTypeSelect.value[1];
|
||||
viewDrawerState.visible = !viewDrawerState.visible;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 获取网元网元列表
|
||||
neInfoStore.fnNelist().then(res => {
|
||||
@@ -375,6 +397,16 @@ onMounted(() => {
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'fileName'">
|
||||
<a-space :size="8" align="center">
|
||||
<a-tooltip
|
||||
v-if="
|
||||
record.fileType === 'file' && record.fileName.endsWith('.log')
|
||||
"
|
||||
>
|
||||
<template #title>{{ t('common.viewText') }}</template>
|
||||
<a-button type="link" @click.prevent="fnDrawerOpen(record)">
|
||||
<template #icon><ProfileOutlined /></template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-button
|
||||
type="link"
|
||||
:loading="downLoading"
|
||||
@@ -398,6 +430,14 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
|
||||
<!-- 文件内容查看抽屉 -->
|
||||
<ViewDrawer
|
||||
v-model:visible="viewDrawerState.visible"
|
||||
:file-path="viewDrawerState.filePath"
|
||||
:ne-type="viewDrawerState.neType"
|
||||
:ne-id="viewDrawerState.neId"
|
||||
></ViewDrawer>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ import { useRoute, useRouter } from 'vue-router';
|
||||
import { message, Modal } from 'ant-design-vue/lib';
|
||||
import { ColumnsType } from 'ant-design-vue/lib/table';
|
||||
import { PageContainer } from 'antdv-pro-layout';
|
||||
import { dumpStart, dumpStop, dumpDownload, traceUPF } from '@/api/trace/pcap';
|
||||
import { dumpStart, dumpStop, traceUPF } from '@/api/trace/pcap';
|
||||
import { listAllNeInfo } from '@/api/ne/neInfo';
|
||||
import { getNeFile } from '@/api/tool/neFile';
|
||||
import { getNeDirZip, getNeFile, getNeViewFile } from '@/api/tool/neFile';
|
||||
import saveAs from 'file-saver';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
@@ -31,7 +31,7 @@ type ModalStateType = {
|
||||
/**任务编号 */
|
||||
taskCode: string;
|
||||
/**任务日志,upf标准版为空字符串 */
|
||||
logMsg: string;
|
||||
taskFiles: string[];
|
||||
/**提交表单参数 */
|
||||
data: {
|
||||
neType: string;
|
||||
@@ -65,7 +65,14 @@ type ModalStateType = {
|
||||
/**详情框是否显示 */
|
||||
visibleByView: boolean;
|
||||
/**详情框内容 */
|
||||
logMsg: string;
|
||||
viewFrom: {
|
||||
neType: string;
|
||||
neId: string;
|
||||
path: string;
|
||||
action: string;
|
||||
files: string[];
|
||||
content: string;
|
||||
};
|
||||
};
|
||||
|
||||
/**对话框对象信息状态 */
|
||||
@@ -106,7 +113,14 @@ let modalState: ModalStateType = reactive({
|
||||
},
|
||||
],
|
||||
visibleByView: false,
|
||||
logMsg: '',
|
||||
viewFrom: {
|
||||
neType: '',
|
||||
neId: '',
|
||||
path: '',
|
||||
action: '',
|
||||
files: [],
|
||||
content: '',
|
||||
},
|
||||
});
|
||||
|
||||
/**表格状态类型 */
|
||||
@@ -194,7 +208,7 @@ function fnGetList() {
|
||||
cmdStart: start,
|
||||
cmdStop: stop,
|
||||
taskCode: '',
|
||||
logMsg: '',
|
||||
taskFiles: [],
|
||||
data: {
|
||||
neType: item.neType,
|
||||
neId: item.neId,
|
||||
@@ -218,7 +232,7 @@ function fnSelectCmd(id: any, option: any) {
|
||||
modalState.from[id].cmdStop = option.stop;
|
||||
// 重置任务
|
||||
modalState.from[id].taskCode = '';
|
||||
modalState.from[id].logMsg = '';
|
||||
modalState.from[id].taskFiles = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,7 +355,7 @@ function fnRecordStop(row?: Record<string, any>) {
|
||||
if (res.status === 'fulfilled') {
|
||||
const resV = res.value;
|
||||
fromArr[idx].loading = false;
|
||||
fromArr[idx].logMsg = '';
|
||||
fromArr[idx].taskFiles = [];
|
||||
if (fromArr[idx].cmdStop) {
|
||||
fromArr[idx].taskCode = '';
|
||||
}
|
||||
@@ -350,7 +364,7 @@ function fnRecordStop(row?: Record<string, any>) {
|
||||
if (fromArr[idx].cmdStop) {
|
||||
fromArr[idx].taskCode = resV.data;
|
||||
} else {
|
||||
fromArr[idx].logMsg = resV.msg;
|
||||
fromArr[idx].taskFiles = resV.data;
|
||||
}
|
||||
message.success({
|
||||
content: t('views.traceManage.pcap.stopOk', { title }),
|
||||
@@ -422,10 +436,15 @@ function fnDownPCAP(row?: Record<string, any>) {
|
||||
)
|
||||
);
|
||||
} else {
|
||||
const { neType, neId } = from.data;
|
||||
const path = `/tmp/omc/tcpdump/${neType.toLowerCase()}/${neId}/${taskCode}`;
|
||||
reqArr.push(
|
||||
dumpDownload(
|
||||
Object.assign({ taskCode: taskCode, delTemp: true }, from.data)
|
||||
)
|
||||
getNeDirZip({
|
||||
neType,
|
||||
neId,
|
||||
path,
|
||||
delTemp: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -497,8 +516,42 @@ function fnBatchOper(key: string) {
|
||||
function fnModalVisibleByVive(id: string | number) {
|
||||
const from = modalState.from[id];
|
||||
if (!from) return;
|
||||
const { neType, neId } = from.data;
|
||||
const path = `/tmp/omc/tcpdump/${neType.toLowerCase()}/${neId}/${
|
||||
from.taskCode
|
||||
}`;
|
||||
const files = from.taskFiles.filter(f => f.endsWith('log'));
|
||||
modalState.viewFrom.neType = neType;
|
||||
modalState.viewFrom.neId = neId;
|
||||
modalState.viewFrom.path = path;
|
||||
modalState.viewFrom.files = [...files];
|
||||
fnViveTab(files[0]);
|
||||
modalState.visibleByView = true;
|
||||
modalState.logMsg = from.logMsg;
|
||||
}
|
||||
|
||||
/**对话框tab查看 */
|
||||
function fnViveTab(action: any) {
|
||||
console.log('fnViveTab', action);
|
||||
if (modalState.viewFrom.action === action) return;
|
||||
modalState.viewFrom.action = action;
|
||||
modalState.viewFrom.content = '';
|
||||
const { neType, neId, path } = modalState.viewFrom;
|
||||
getNeViewFile({
|
||||
neId,
|
||||
neType,
|
||||
path,
|
||||
fileName: action,
|
||||
}).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
modalState.viewFrom.content = res.data;
|
||||
} else {
|
||||
modalState.viewFrom.content = '';
|
||||
message.warning({
|
||||
content: `${res.msg}`,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -507,7 +560,8 @@ function fnModalVisibleByVive(id: string | number) {
|
||||
*/
|
||||
function fnModalCancel() {
|
||||
modalState.visibleByView = false;
|
||||
modalState.logMsg = '';
|
||||
modalState.viewFrom.action = '';
|
||||
modalState.viewFrom.files = [];
|
||||
}
|
||||
|
||||
/**跳转文件数据页面 */
|
||||
@@ -651,7 +705,7 @@ onMounted(() => {
|
||||
placement="topRight"
|
||||
v-if="
|
||||
!modalState.from[record.id].loading &&
|
||||
!!modalState.from[record.id].logMsg
|
||||
modalState.from[record.id].taskFiles.length > 0
|
||||
"
|
||||
>
|
||||
<template #title>
|
||||
@@ -694,21 +748,39 @@ onMounted(() => {
|
||||
<!-- 日志信息框 -->
|
||||
<ProModal
|
||||
:drag="true"
|
||||
:fullscreen="true"
|
||||
:borderDraw="true"
|
||||
:width="800"
|
||||
:visible="modalState.visibleByView"
|
||||
:footer="false"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:body-style="{ padding: '12px' }"
|
||||
:body-style="{ padding: '0 12px 12px' }"
|
||||
:title="t('views.traceManage.pcap.textLogMsg')"
|
||||
@cancel="fnModalCancel"
|
||||
>
|
||||
<a-textarea
|
||||
v-model:value="modalState.logMsg"
|
||||
:auto-size="{ minRows: 2, maxRows: 18 }"
|
||||
:disabled="true"
|
||||
style="color: rgba(0, 0, 0, 0.85)"
|
||||
/>
|
||||
<a-tabs
|
||||
v-model:activeKey="modalState.viewFrom.action"
|
||||
tab-position="top"
|
||||
size="small"
|
||||
@tabClick="fnViveTab"
|
||||
>
|
||||
<a-tab-pane
|
||||
v-for="fileName in modalState.viewFrom.files"
|
||||
:key="fileName"
|
||||
:tab="fileName"
|
||||
:destroyInactiveTabPane="false"
|
||||
>
|
||||
<a-spin :spinning="!modalState.viewFrom.content">
|
||||
<a-textarea
|
||||
:value="modalState.viewFrom.content"
|
||||
:auto-size="{ minRows: 2 }"
|
||||
:disabled="true"
|
||||
style="color: rgba(0, 0, 0, 0.85)"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</ProModal>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user