From 5f355e47f17c627868a4e408d6cbe24c2aef9013 Mon Sep 17 00:00:00 2001 From: aixianling Date: Fri, 10 Feb 2023 16:29:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=8D=E7=AB=AF=E7=9B=91=E6=8E=A7=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sentry/AppApiMonitor/AppApiMonitor.vue | 62 +++++++++++--- ui/lib/js/observer.js | 81 +++++++++++++------ ui/packages/basic/AiTable.vue | 4 +- ui/packages/layout/AiCard.vue | 11 ++- ui/packages/tools/AiEchart.vue | 4 +- 5 files changed, 116 insertions(+), 46 deletions(-) diff --git a/project/oms/apps/sentry/AppApiMonitor/AppApiMonitor.vue b/project/oms/apps/sentry/AppApiMonitor/AppApiMonitor.vue index fd808bf4..3a1040d5 100644 --- a/project/oms/apps/sentry/AppApiMonitor/AppApiMonitor.vue +++ b/project/oms/apps/sentry/AppApiMonitor/AppApiMonitor.vue @@ -1,15 +1,21 @@ @@ -44,15 +58,24 @@ export default { tableData: [], page: {current: 1}, search: {}, - columns: [ - {label: "状态码", prop: "status"}, + sta: {top10: [], distribution: []}, + top10Columns: [ {label: "接口地址", prop: "path"}, + {label: "次数", prop: "total", width: 80, align: 'center'}, + {label: "创建时间", prop: "createTime", width: 160}, + ], + columns: [ + {slot: 'expand'}, + {label: "接口地址", prop: "path"}, + {label: "状态码", prop: "status", width: 100, align: 'center'}, + {label: "创建时间", prop: "createTime", width: 160}, {label: "错误信息", prop: "error"}, + ], + desConfigs: [ {label: "终端", prop: "device"}, - {label: "页面", prop: "url"}, - {label: "用户", prop: "userName"}, {label: "环境", prop: "nodeProcess"}, - {label: "创建时间", prop: "createTime"}, + {label: "页面", prop: "url", isLine: true}, + {label: "错误信息", prop: "error", isLine: true}, ], networkStatus: [ {dictValue: 200, dictName: '200:成功'}, @@ -74,15 +97,28 @@ export default { this.page.total = res.data.total } }) + }, + getStaData() { + this.instance.post("/node/monitorApi/sta").then(res => { + if (res?.data) { + this.sta = res.data + } + }) } }, created() { this.getTableData() + this.getStaData() } } diff --git a/ui/lib/js/observer.js b/ui/lib/js/observer.js index d899ab73..ddb4e448 100644 --- a/ui/lib/js/observer.js +++ b/ui/lib/js/observer.js @@ -1,38 +1,67 @@ -/** - * 获取符合要求的请求 - * @param entries 监测的请求对象 - * @param type 设置满足条件的请求类型 - * @returns {PerformanceEntry[]} - */ -const getRequests = (entries = performance.getEntriesByType('resource'), type = ['xmlhttprequest']) => - entries?.filter(e => type.includes(e.initiatorType)) || [] +import http from "./request" /** * 观察者工具对象,用于前端接口监测 */ + class Observer { constructor() { - this.saveLogs(getRequests()) - this.ins = new PerformanceObserver((list, ob) => { - const watchLogs = getRequests(list.getEntriesByType("resource")) - this.saveLogs(watchLogs) - }) - this.ins.observe({entryTypes: ["resource"]}) + this.initXHRObserver() } - saveLogs(list = []) { - list.map(e => { - if (!/sockjs/.test(e.name)) { - const api = { - status: e.responseStatus, - path: e.name, - url: location.href, - nodeProcess: process.env.NODE_ENV, - } - console.log(api) - // http.post("/node/monitorApi/addOrUpdate", api) + static saveLog(item = {}) { + const api = { + method: item.method, + path: item.url, + url: location.href, + nodeProcess: process.env.NODE_ENV, + status: item.status, + code: item.response?.code, + error: item.response?.code != 0 ? item.response?.data : null, + device: navigator.userAgentData.platform + } + if (!/(sockjs-node|hot-update|monitorApi)/.test(api.path)) { + if (!!this.timer) { + clearTimeout(this.timer) } - }) + this.pending = [this.pending, api].flat().filter(Boolean) + this.timer = setTimeout(() => { + http.post("/admin/apiForward", this.pending, { + withoutToken: true, + params: {url: "http://dvcp.cunwuyun.cn/ns/node/monitorApi/addOrUpdate"} + }).then(res => { + if (res?.code == 0) { + this.pending = [] + } + }) + }, 5000) + } + } + + initXHRObserver() { + const origin = XMLHttpRequest.prototype.open; + XMLHttpRequest.prototype.open = function (...args) { + let send = this.send; + let _this = this + let post_data = [] + this.send = function (...data) { + post_data = data; + return send.apply(_this, data) + } + this.addEventListener("readystatechange", function () { + if (this.readyState === 4) { + // 请求后拦截 + Observer.saveLog({ + url: args[1], + status: this.status, + method: args[0], + data: post_data, + response: JSON.parse(this.response || null) + }) + } + }, false) + return origin.apply(this, args) + } } } diff --git a/ui/packages/basic/AiTable.vue b/ui/packages/basic/AiTable.vue index 32031e09..601d9d9a 100644 --- a/ui/packages/basic/AiTable.vue +++ b/ui/packages/basic/AiTable.vue @@ -149,11 +149,11 @@ export default { checkAll: v => v.chooseList.length == v.tableData.length && v.tableData !== 0, page() { return { - ...this.pageConfig, current: this.current, size: this.size, total: this.total, - pagerCount: this.pagerCount + pagerCount: this.pagerCount, + ...this.pageConfig } }, }, diff --git a/ui/packages/layout/AiCard.vue b/ui/packages/layout/AiCard.vue index fab82f5c..c17cdf9b 100644 --- a/ui/packages/layout/AiCard.vue +++ b/ui/packages/layout/AiCard.vue @@ -1,5 +1,5 @@