From dae144ccf9ad27f7599a97463924562d8cbf5cf6 Mon Sep 17 00:00:00 2001 From: dap1 <15891557205@163.com> Date: Sat, 10 Jun 2023 20:03:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=80=E4=BA=9B=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E7=9A=84=E8=AF=A6=E6=83=85=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/apiAccessLog/AccessLogModal.vue | 27 ++++ .../infra/apiAccessLog/apiAccessLog.data.ts | 104 ++++++++++++- src/views/infra/apiAccessLog/index.vue | 31 +++- src/views/infra/apiErrorLog/ErrorLogModal.vue | 27 ++++ .../infra/apiErrorLog/apiErrorLog.data.ts | 139 ++++++++++++++++++ src/views/infra/apiErrorLog/index.vue | 15 +- .../system/operatelog/operateLog.data.ts | 25 ++-- 7 files changed, 353 insertions(+), 15 deletions(-) create mode 100644 src/views/infra/apiAccessLog/AccessLogModal.vue create mode 100644 src/views/infra/apiErrorLog/ErrorLogModal.vue diff --git a/src/views/infra/apiAccessLog/AccessLogModal.vue b/src/views/infra/apiAccessLog/AccessLogModal.vue new file mode 100644 index 00000000..45a65715 --- /dev/null +++ b/src/views/infra/apiAccessLog/AccessLogModal.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/src/views/infra/apiAccessLog/apiAccessLog.data.ts b/src/views/infra/apiAccessLog/apiAccessLog.data.ts index 12bb65a2..eae52ff0 100644 --- a/src/views/infra/apiAccessLog/apiAccessLog.data.ts +++ b/src/views/infra/apiAccessLog/apiAccessLog.data.ts @@ -1,5 +1,7 @@ import { BasicColumn, FormSchema, useRender } from '@/components/Table' import { DICT_TYPE, getDictOptions } from '@/utils/dict' +import { DescItem } from '@/components/Description/index' +import { h } from 'vue' export const columns: BasicColumn[] = [ { @@ -58,7 +60,7 @@ export const columns: BasicColumn[] = [ ellipsis: true, customRender: ({ record }) => { const success = record.resultCode === 0 - return useRender.renderTag(success ? '成功' : '失败(' + record.resultMsg + ')', success ? '#87d068' : '#f50') + return useRender.renderTag(success ? '成功' : '失败', success ? '#87d068' : '#f50') } } ] @@ -110,3 +112,103 @@ export const searchFormSchema: FormSchema[] = [ colProps: { span: 8 } } ] + +const httpMethods = [ + { value: 'GET', color: '#108ee9' }, + { value: 'POST', color: '#2db7f5' }, + { value: 'PUT', color: 'warning' }, + { value: 'DELETE', color: '#f50' } +] + +export const infoSchema: DescItem[] = [ + { + label: '日志id', + field: 'id' + }, + { + label: '链路id', + field: 'traceId', + show: (data) => data && data.traceId && data.traceId !== '' + }, + { + label: '应用名称', + field: 'applicationName', + labelMinWidth: 100 + }, + { + field: 'userId', + label: '用户id', + render(value, data) { + const tag = useRender.renderDict(data.userType, DICT_TYPE.USER_TYPE) + const uidTag = useRender.renderTag('uid: ' + value) + return h('span', {}, [tag, uidTag]) + } + }, + { + field: 'resultCode', + label: '请求结果', + render(value) { + return useRender.renderTag(value === 0 ? '成功' : '失败', value === 0 ? '#87d068' : '#f50') + } + }, + { + field: 'resultMsg', + label: '响应信息', + show(data) { + return data && data.resultMsg && data.resultMsg !== '' + }, + render(value) { + return h('span', { style: { color: 'red', fontWeight: 'bold' } }, value) + } + }, + { + field: 'userIp', + label: '请求ip' + }, + { + field: 'userAgent', + label: 'userAgent' + }, + { + field: 'beginTime', + label: '请求时间', + render(value) { + return useRender.renderDate(value) + } + }, + { + field: 'requestUrl', + label: '请求路径', + render(_, data) { + if (!data) { + return '' + } + const { requestMethod, requestUrl } = data + const current = httpMethods.find((item) => item.value === requestMethod.toUpperCase()) + const methodTag = current ? useRender.renderTag(requestMethod, current.color) : requestMethod + return h('span', {}, [methodTag, requestUrl]) + } + }, + { + field: 'beginTime', + label: '请求开始时间', + render(value) { + return useRender.renderDate(value) + } + }, + { + field: 'endTime', + label: '请求结束时间', + render(value) { + return useRender.renderDate(value) + } + }, + { + field: 'duration', + label: '请求耗时', + render(value) { + // 为0的话需要转为string 否则不会显示 + return useRender.renderText(String(value), 'ms') + } + } +] diff --git a/src/views/infra/apiAccessLog/index.vue b/src/views/infra/apiAccessLog/index.vue index ce222317..dd9ee2ec 100644 --- a/src/views/infra/apiAccessLog/index.vue +++ b/src/views/infra/apiAccessLog/index.vue @@ -6,16 +6,32 @@ {{ t('action.export') }} + + + + diff --git a/src/views/infra/apiErrorLog/apiErrorLog.data.ts b/src/views/infra/apiErrorLog/apiErrorLog.data.ts index f3191681..bdc55f71 100644 --- a/src/views/infra/apiErrorLog/apiErrorLog.data.ts +++ b/src/views/infra/apiErrorLog/apiErrorLog.data.ts @@ -1,5 +1,8 @@ import { BasicColumn, FormSchema, useRender } from '@/components/Table' import { DICT_TYPE, getDictOptions } from '@/utils/dict' +import { Textarea } from 'ant-design-vue' +import { h } from 'vue' +import { DescItem } from '@/components/Description/index' export const columns: BasicColumn[] = [ { @@ -108,3 +111,139 @@ export const searchFormSchema: FormSchema[] = [ colProps: { span: 8 } } ] + +function renderText(value: string, color: string, bold = true) { + return h('span', { style: { color, fontWeight: bold ? 'bold' : 'normal' } }, value) +} + +const httpMethods = [ + { value: 'GET', color: '#108ee9' }, + { value: 'POST', color: '#2db7f5' }, + { value: 'PUT', color: 'warning' }, + { value: 'DELETE', color: '#f50' } +] + +export const infoSchema: DescItem[] = [ + { + field: 'id', + label: '异常id' + }, + { + field: 'traceId', + label: '链路ID', + show(data) { + return data && data.traceId && data.traceId !== '' + } + }, + { + field: 'applicationName', + label: '应用名称', + labelMinWidth: 100 + }, + { + field: 'processStatus', + label: '处理状态', + render(_, data) { + const { processStatus, processUserId } = data + const tag = useRender.renderDict(processStatus, DICT_TYPE.INFRA_API_ERROR_LOG_PROCESS_STATUS) + if (!processUserId) { + return tag + } + const uidTag = useRender.renderTag('uid: ' + processUserId) + return h('span', {}, [tag, uidTag]) + } + }, + { + field: 'processTime', + label: '处理时间', + show(data) { + return data && data.processTime && data.processTime !== '' + }, + render(value) { + return useRender.renderDate(value) + } + }, + { + field: 'userId', + label: '用户id', + render(value, data) { + const tag = useRender.renderDict(data.userType, DICT_TYPE.USER_TYPE) + const uidTag = useRender.renderTag('uid: ' + value) + return h('span', {}, [tag, uidTag]) + } + }, + { + field: 'userIp', + label: 'ip地址' + }, + { + field: 'requestUrl', + label: '请求地址', + render(_, data) { + if (data) { + const { requestMethod } = data + const current = httpMethods.find((item) => item.value === requestMethod) + const tag = current ? useRender.renderTag(requestMethod, current.color) : requestMethod + return h('span', {}, [tag, data.requestUrl]) + } + } + }, + { + field: 'requestParams', + label: '请求参数', + render(value) { + return useRender.renderJsonPreview(value) + } + }, + { + field: 'userAgent', + label: 'userAgent' + }, + { + field: 'exceptionTime', + label: '异常时间', + render(value) { + return useRender.renderDate(value) + } + }, + { + field: 'exceptionClassName', + label: '异常类名/方法', + render(_, data) { + if (data) { + return renderText(data.exceptionClassName + ' / ' + data.exceptionMethodName, 'red') + } + } + }, + { + field: 'exceptionMessage', + label: '异常信息', + render(value) { + return renderText(value, 'red') + } + }, + { + field: 'exceptionFileName', + label: '异常文件名', + render(_, data) { + if (data) { + return useRender.renderText(data.exceptionFileName, 'Line: ' + data.exceptionLineNumber) + } + } + }, + { + field: 'exceptionName', + label: '异常名称' + }, + { + field: 'exceptionRootCauseMessage', + label: '异常信息' + }, + { + field: 'exceptionStackTrace', + label: '异常堆栈', + render(value) { + return h(Textarea, { value, readonly: true, style: { minHeight: '300px' } }) + } + } +] diff --git a/src/views/infra/apiErrorLog/index.vue b/src/views/infra/apiErrorLog/index.vue index b018151c..ddd53998 100644 --- a/src/views/infra/apiErrorLog/index.vue +++ b/src/views/infra/apiErrorLog/index.vue @@ -10,6 +10,11 @@