From 964328372dc41ea5f74e18b1eb86066f8b8320bc Mon Sep 17 00:00:00 2001
From: GavinXiao <2749984520@qq.com>
Date: Thu, 2 Apr 2026 17:51:17 +0800
Subject: [PATCH 1/2] feat(TAP-10773): API audit metric optimization
---
.gitignore | 4 +-
apps/daas/src/i18n/langs/en.js | 15 +-
apps/daas/src/i18n/langs/zh-CN.js | 16 +-
apps/daas/src/i18n/langs/zh-TW.js | 15 +-
.../daas/src/views/data-server-audit/Info.vue | 518 +++++++++++++++++-
5 files changed, 544 insertions(+), 24 deletions(-)
diff --git a/.gitignore b/.gitignore
index 8e51bc962..4345dcdd9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,4 +30,6 @@ pnpm-debug.log*
output.js
webpack.confi.production.js
-build/deploy.sh
\ No newline at end of file
+build/deploy.sh
+
+daas-components.d.ts
\ No newline at end of file
diff --git a/apps/daas/src/i18n/langs/en.js b/apps/daas/src/i18n/langs/en.js
index 21d7ddb00..e9b387fd9 100644
--- a/apps/daas/src/i18n/langs/en.js
+++ b/apps/daas/src/i18n/langs/en.js
@@ -405,6 +405,8 @@ export default {
apiaudit_visitor: 'Client Name',
apiaudit_ip: 'Visitor IP',
apiaudit_interview_time: 'Access Time',
+ apiaudit_interview_time_req: 'Request Time',
+ apiaudit_interview_time_db: 'Database Time',
apiaudit_interview_time_start: 'Access start time',
apiaudit_interview_time_end: 'Access end time',
apiaudit_visit_result: 'Result',
@@ -412,11 +414,13 @@ export default {
apiaudit_log_info: 'Log details',
apiaudit_parameter: 'parameter',
apiaudit_link: 'Link',
+ apiaudit_access_records_byte: 'Response Size',
apiaudit_access_records: 'Return the number of rows',
apiaudit_total_records: 'Match rows',
- apiaudit_average_access_rate: 'API access rate',
- apiaudit_access_time: 'Request access time',
- apiaudit_average_response_time: 'Database response time',
+ apiaudit_average_access_db_rate: 'Database Response Rate',
+ apiaudit_average_access_time: 'API Response Time',
+ apiaudit_access_time: 'Total Request Time',
+ apiaudit_average_response_time: 'Database Time Consumption',
apiaudit_success: 'success',
apiaudit_placeholder: 'Please enter name/ID',
apiaudit_client_name_placeholder: 'Please enter client name',
@@ -429,6 +433,11 @@ export default {
connection_reload_schema_confirm_msg:
'If there are too many schemas in this library, it may take a long time. Make sure to refresh the schema of the data source',
connection_reload_schema_fail: 'Schema load failed',
+ apiaudit_time_line:"Time Line",
+ apiaudit_req_start_point: "Request start",
+ apiaudit_req_end_point: "Request to end",
+ apiaudit_db_start_point: "Database response starts",
+ apiaudit_db_end_point: "Database response completed",
//Dag
//Task edit缓存节点提示
task_list_status_all: 'All status',
diff --git a/apps/daas/src/i18n/langs/zh-CN.js b/apps/daas/src/i18n/langs/zh-CN.js
index 36e6a33dd..4ea0e0a8c 100644
--- a/apps/daas/src/i18n/langs/zh-CN.js
+++ b/apps/daas/src/i18n/langs/zh-CN.js
@@ -391,6 +391,8 @@ export default {
apiaudit_visitor: '客户端名称',
apiaudit_ip: '访问人员IP',
apiaudit_interview_time: '访问时间',
+ apiaudit_interview_time_req: '请求时间',
+ apiaudit_interview_time_db: '数据库时间',
apiaudit_interview_time_start: '访问开始时间',
apiaudit_interview_time_end: '访问结束时间',
apiaudit_visit_result: '访问结果',
@@ -399,13 +401,21 @@ export default {
apiaudit_parameter: '参数',
apiaudit_link: '链接',
apiaudit_access_records: '返回行数',
+ apiaudit_access_records_byte: '响应大小',
apiaudit_total_records: '匹配行数',
- apiaudit_average_access_rate: 'API 访问速率',
- apiaudit_access_time: '请求访问耗时',
- apiaudit_average_response_time: '数据库响应时间',
+ apiaudit_average_access_db_rate: '数据库响应速率',
+ apiaudit_average_access_time: 'API响应耗时',
+ apiaudit_access_time: '请求总耗时',
+ apiaudit_average_response_time: '数据库耗时',
apiaudit_success: '成功',
apiaudit_placeholder: '请输入名称/ID',
apiaudit_client_name_placeholder: '请输入客户端名称',
+ apiaudit_time_line:"时间线",
+ apiaudit_req_start_point: "请求开始",
+ apiaudit_req_end_point: "请求结束",
+ apiaudit_db_start_point: "数据库响应开始",
+ apiaudit_db_end_point: "数据库响应结束",
+
// 连接
connection_list_form_database_type: '数据库类型',
connection_list_name: '连接名',
diff --git a/apps/daas/src/i18n/langs/zh-TW.js b/apps/daas/src/i18n/langs/zh-TW.js
index 3a81b1147..d05dc2f93 100644
--- a/apps/daas/src/i18n/langs/zh-TW.js
+++ b/apps/daas/src/i18n/langs/zh-TW.js
@@ -392,6 +392,8 @@ export default {
apiaudit_visitor: '客戶端名稱',
apiaudit_ip: '訪問人員IP',
apiaudit_interview_time: '訪問時間',
+ apiaudit_interview_time_req: '請求時間',
+ apiaudit_interview_time_db: '資料庫時間',
apiaudit_interview_time_start: '訪問開始時間',
apiaudit_interview_time_end: '訪問結束時間',
apiaudit_visit_result: '訪問結果',
@@ -400,13 +402,20 @@ export default {
apiaudit_parameter: '參數',
apiaudit_link: '鏈接',
apiaudit_access_records: '返回行數',
+ apiaudit_access_records_byte: '響應大小',
apiaudit_total_records: '匹配行數',
- apiaudit_average_access_rate: 'API 訪問速率',
- apiaudit_access_time: '請求訪問耗時',
- apiaudit_average_response_time: '數據庫回應時間',
+ apiaudit_average_access_db_rate: '數據庫響應速率',
+ apiaudit_average_access_time: 'API響應耗時',
+ apiaudit_access_time: '請求總耗時',
+ apiaudit_average_response_time: '資料庫耗時',
apiaudit_success: '成功',
apiaudit_placeholder: '請輸入名稱/ID',
apiaudit_client_name_placeholder: '請輸入客戶端名稱',
+ apiaudit_time_line:"時間線",
+ apiaudit_req_start_point: "請求開始",
+ apiaudit_req_end_point: "請求結束",
+ apiaudit_db_start_point: "資料庫響應開始",
+ apiaudit_db_end_point: "資料庫響應結束",
// 連接
connection_list_form_database_type: '數據庫類型',
connection_list_name: '連接名',
diff --git a/apps/daas/src/views/data-server-audit/Info.vue b/apps/daas/src/views/data-server-audit/Info.vue
index 610d5b2d7..6be794a44 100644
--- a/apps/daas/src/views/data-server-audit/Info.vue
+++ b/apps/daas/src/views/data-server-audit/Info.vue
@@ -13,31 +13,216 @@ export default {
return {
auditData: null,
loading: true,
+ hoverTimelineSeg: null,
+ timelineTooltipPopperOptions: {
+ modifiers: [
+ {
+ name: 'offset',
+ options: { offset: [0, 8] },
+ },
+ {
+ name: 'flip',
+ options: {
+ fallbackPlacements: [
+ 'top-start',
+ 'top-end',
+ 'bottom',
+ 'bottom-start',
+ 'bottom-end',
+ ],
+ },
+ },
+ {
+ name: 'preventOverflow',
+ options: { padding: 8 },
+ },
+ ],
+ },
list: [
+ {
+ label: this.$t('apiaudit_total_records'),
+ key: 'totalRows',
+ value: 0,
+ },
{
label: this.$t('apiaudit_access_records'),
key: 'visitTotalCount',
value: 0,
},
{
- label: this.$t('apiaudit_total_records'),
- key: 'totalRows',
+ label: this.$t('apiaudit_access_records_byte'),
+ key: 'responseBytes',
value: 0,
},
+ { label: this.$t('apiaudit_access_time'), key: 'latency', value: 0 },
{
- label: this.$t('apiaudit_average_access_rate'),
- key: 'speed',
+ label: this.$t('apiaudit_average_access_time'),
+ key: 'httpTime',
value: 0,
},
- { label: this.$t('apiaudit_access_time'), key: 'latency', value: 0 },
{
label: this.$t('apiaudit_average_response_time'),
key: 'dataQueryTotalTime',
value: 0,
},
+ {
+ label: this.$t('apiaudit_average_access_db_rate'),
+ key: 'dbRate',
+ value: 0,
+ },
],
}
},
+ computed: {
+ timelinePoints() {
+ if (!this.auditData) return []
+
+ const callStart = Number(this.auditData.callStart)
+ const callEnd = Number(this.auditData.callEnd)
+ const dbStart = Number(this.auditData.dataQueryFromTime)
+ const dbEnd = Number(this.auditData.dataQueryEndTime)
+
+ const reqOk =
+ Number.isFinite(callStart) &&
+ Number.isFinite(callEnd) &&
+ callEnd >= callStart
+ const dbOk =
+ reqOk &&
+ Number.isFinite(dbStart) &&
+ Number.isFinite(dbEnd) &&
+ dbEnd >= dbStart &&
+ dbStart >= callStart &&
+ dbEnd <= callEnd
+
+ const reqPoints = [
+ {
+ key: 'callStart',
+ label: this.$t('apiaudit_req_start_point'),
+ ts: this.auditData.callStart,
+ text: this.auditData.callStartTime || '-',
+ type: 'req',
+ },
+ {
+ key: 'callEnd',
+ label: this.$t('apiaudit_req_end_point'),
+ ts: this.auditData.callEnd,
+ text: this.auditData.callEndTime || '-',
+ type: 'req',
+ },
+ ]
+
+ if (!dbOk) {
+ return [
+ { ...reqPoints[0], left: 0 },
+ { ...reqPoints[1], left: 100 },
+ ]
+ }
+
+ const points = [
+ reqPoints[0],
+ {
+ key: 'dataQueryFromTime',
+ label: this.$t('apiaudit_db_start_point'),
+ ts: this.auditData.dataQueryFromTime,
+ text: this.auditData.dataQueryFrom || '-',
+ type: 'db',
+ },
+ {
+ key: 'dataQueryEndTime',
+ label: this.$t('apiaudit_db_end_point'),
+ ts: this.auditData.dataQueryEndTime,
+ text: this.auditData.dataQueryEnd || '-',
+ type: 'db',
+ },
+ reqPoints[1],
+ ]
+
+ const d0 = Math.max(0, dbStart - callStart)
+ const d1 = Math.max(0, dbEnd - dbStart)
+ const d2 = Math.max(0, callEnd - dbEnd)
+ const total = d0 + d1 + d2
+
+ let w0 = 33.3333
+ let w1 = 33.3333
+ if (total > 0) {
+ w0 = (d0 / total) * 100
+ w1 = (d1 / total) * 100
+ }
+
+ const lefts = [0, w0, w0 + w1, 100]
+ return points.map((p, i) => ({ ...p, left: lefts[i] }))
+ },
+ timelineSegments() {
+ if (!this.auditData) return []
+
+ const callStart = Number(this.auditData.callStart)
+ const dbStart = Number(this.auditData.dataQueryFromTime)
+ const dbEnd = Number(this.auditData.dataQueryEndTime)
+ const callEnd = Number(this.auditData.callEnd)
+
+ const reqOk =
+ Number.isFinite(callStart) &&
+ Number.isFinite(callEnd) &&
+ callEnd >= callStart
+ const dbOk =
+ reqOk &&
+ Number.isFinite(dbStart) &&
+ Number.isFinite(dbEnd) &&
+ dbEnd >= dbStart &&
+ dbStart >= callStart &&
+ dbEnd <= callEnd
+
+ if (!dbOk) {
+ return [
+ {
+ key: 'req',
+ type: reqOk ? 'req' : 'other',
+ width: 100,
+ startText: this.auditData.callStartTime || '-',
+ endText: this.auditData.callEndTime || '-',
+ },
+ ]
+ }
+
+ let w0 = 33.3333
+ let w1 = 33.3333
+ let w2 = 33.3334
+
+ const d0 = Math.max(0, dbStart - callStart)
+ const d1 = Math.max(0, dbEnd - dbStart)
+ const d2 = Math.max(0, callEnd - dbEnd)
+ const total = d0 + d1 + d2
+ if (total > 0) {
+ w0 = (d0 / total) * 100
+ w1 = (d1 / total) * 100
+ w2 = 100 - w0 - w1
+ }
+
+ return [
+ {
+ key: 'req-pre',
+ type: 'req',
+ width: w0,
+ startText: this.auditData.callStartTime || '-',
+ endText: this.auditData.dataQueryFrom || '-',
+ },
+ {
+ key: 'db',
+ type: 'db',
+ width: w1,
+ startText: this.auditData.dataQueryFrom || '-',
+ endText: this.auditData.dataQueryEnd || '-',
+ },
+ {
+ key: 'req-post',
+ type: 'req',
+ width: w2,
+ startText: this.auditData.dataQueryEnd || '-',
+ endText: this.auditData.callEndTime || '-',
+ },
+ ]
+ },
+ },
created() {
this.getData()
},
@@ -54,8 +239,23 @@ export default {
this.auditData.createAt = data.createAt
? dayjs(data.createAt).format('YYYY-MM-DD HH:mm:ss')
: '-'
- this.auditData.reqTime = this.auditData.reqTime
- ? dayjs(this.auditData.reqTime).format('YYYY-MM-DD HH:mm:ss')
+ this.auditData.callStartTime = this.auditData.callStart
+ ? dayjs(this.auditData.callStart).format(
+ 'YYYY-MM-DD HH:mm:ss.SSS',
+ )
+ : '-'
+ this.auditData.callEndTime = this.auditData.callEnd
+ ? dayjs(this.auditData.callEnd).format('YYYY-MM-DD HH:mm:ss.SSS')
+ : '-'
+ this.auditData.dataQueryFrom = this.auditData.dataQueryFromTime
+ ? dayjs(this.auditData.dataQueryFromTime).format(
+ 'YYYY-MM-DD HH:mm:ss.SSS',
+ )
+ : '-'
+ this.auditData.dataQueryEnd = this.auditData.dataQueryEndTime
+ ? dayjs(this.auditData.dataQueryEndTime).format(
+ 'YYYY-MM-DD HH:mm:ss.SSS',
+ )
: '-'
const jsonData = this.auditData.body
? this.auditData.body
@@ -71,7 +271,7 @@ export default {
this.auditData.jsonParam.json = jsonData
this.auditData.jsonParam.validation = true
} catch (error) {
- console.log(`parseJsonData error: ${error}`)
+ console.error(`parseJsonData error: ${error}`)
}
this.list.forEach((item) => {
@@ -135,6 +335,38 @@ export default {
console.error('JSON处理失败:', error)
}
},
+ isTimelinePointActive(pointIndex) {
+ if (
+ this.hoverTimelineSeg === null ||
+ this.hoverTimelineSeg === undefined
+ ) {
+ return false
+ }
+ return (
+ pointIndex === this.hoverTimelineSeg ||
+ pointIndex === this.hoverTimelineSeg + 1
+ )
+ },
+ timelineTooltipPlacement(pointIndex) {
+ if (
+ this.hoverTimelineSeg === null ||
+ this.hoverTimelineSeg === undefined ||
+ !this.isTimelinePointActive(pointIndex)
+ ) {
+ return 'top'
+ }
+
+ const startIndex = this.hoverTimelineSeg
+ const endIndex = this.hoverTimelineSeg + 1
+ const startLeft = Number(this.timelinePoints?.[startIndex]?.left)
+ const endLeft = Number(this.timelinePoints?.[endIndex]?.left)
+ const segWidth = endLeft - startLeft
+ const shouldSplit =
+ Number.isFinite(segWidth) && segWidth >= 0 && segWidth <= 18
+
+ if (!shouldSplit) return 'top'
+ return pointIndex === endIndex ? 'bottom' : 'top'
+ },
},
}
@@ -161,10 +393,6 @@ export default {
>{{ $t('apiaudit_link') }}:
{{ auditData.apiPath || '-' }}
-