diff --git a/public/config.json b/public/config.json index 490693c8..c852aa67 100644 --- a/public/config.json +++ b/public/config.json @@ -1 +1 @@ -{"baseUrl": "http://192.168.44.53:8090/", "version": "2.0.2021.05.11.19.43"} \ No newline at end of file +{"baseUrl": "http://192.168.44.53:8090/", "version": "2.0.2021.05.11.19.43","performanceEndTimeInterval": 86400} \ No newline at end of file diff --git a/src/assets/css/components/views/entityExplorer/entityList/detail-overview.scss b/src/assets/css/components/views/entityExplorer/entityList/detail-overview.scss index cfdf9c75..e00d709f 100644 --- a/src/assets/css/components/views/entityExplorer/entityList/detail-overview.scss +++ b/src/assets/css/components/views/entityExplorer/entityList/detail-overview.scss @@ -167,6 +167,11 @@ padding-left: 5px; } } + .row__charts { + width:80px; + height:20px; + padding-bottom: 5px; + } .row__desc { color: #666666; } diff --git a/src/permission.js b/src/permission.js index d49ce0f7..e05ebeed 100644 --- a/src/permission.js +++ b/src/permission.js @@ -20,6 +20,7 @@ router.beforeEach(async (to, from, next) => { if (!axios.defaults.baseURL) { const config = await getConfigJson() axios.defaults.baseURL = config.baseUrl + axios.defaults.performanceEndTimeInterval = config.performanceEndTimeInterval } if (localStorage.getItem(storageKey.token)) { // 加载i18n diff --git a/src/utils/api.js b/src/utils/api.js index 0d2ce3c1..04873c73 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -121,9 +121,9 @@ export const api = { listBasic: '/interface/detection/performance/list/basic', listCount: '/interface/detection/performance/list/count', overviewBasic: '/interface/detection/performance/detail/overview/basic', - dnsErrorMetric: '/interface/detection/performance/detail/overview/metric', - httpErrorMetric: '/interface/detection/performance/detail/overview/metric', - highDnsResponseTimeMetric: '/interface/detection/performance/detail/overview/metric' + dnsErrorMetric: '/interface/detection/performance/detail/overview/metric/dnsError', + httpErrorMetric: '/interface/detection/performance/detail/overview/metric/httpError', + highDnsResponseTimeMetric: '/interface/detection/performance/detail/overview/metric/highDnsResponseTime' } }, // Dashboard diff --git a/src/utils/constants.js b/src/utils/constants.js index 55b4e4d8..6be0a9ac 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -25,7 +25,8 @@ export const storageKey = { entitySearchHistory: 'cn-entity-search-history', echartLegendFontSize: 'echartLegendFontSize', echartLabelFontSize: 'echartLabelFontSize', - tokenExpireCurrentPath: 'token-expire-current-path' + tokenExpireCurrentPath: 'token-expire-current-path', + performanceEndTimeInterval: 'performance-endTime-interval' } // 统一定义跳转来源 diff --git a/src/views/entityExplorer/entityList/detailOverview/App.vue b/src/views/entityExplorer/entityList/detailOverview/App.vue index 86b78953..5724b7f5 100644 --- a/src/views/entityExplorer/entityList/detailOverview/App.vue +++ b/src/views/entityExplorer/entityList/detailOverview/App.vue @@ -43,14 +43,14 @@
{{$t('overall.sent')}}:{{unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ')}}ps
-
+
{{$t('overall.received')}}:{{unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ')}}ps
-
+
@@ -157,6 +157,11 @@
{{performance.eventSeverity}}
{{performance.eventType}}
+
+ +
+
+
@@ -195,7 +200,6 @@ :entity="entityCopy" :query-params="queryParams" :hide-header="true" - :loading="loadingMap" @getCurrentTimeRange="getCurrentTimeRange" >
@@ -299,8 +303,7 @@ export default { loadingOut: false, loadingIn: false, loadingAlert: false, - loadingSecurityEvents: false, - loadingMap: false + loadingSecurityEvents: false } } }, @@ -314,17 +317,21 @@ export default { } return queryParams }, + getPerformanceQueryParams () { + const queryParams = { + appName: this.entity.appName + } + return queryParams + }, handleRelationData (result) { this.entityData.domainCount = result.domainCount this.entityData.ipCount = result.ipCount }, chartGetMap () { - this.loadingMap = true get((this.trafficUrlMap), this.getQueryParams()).then(response => { if (response.code === 200) { this.chartData = response.data.result } - this.loadingMap = false }) }, queryRelated () { @@ -334,9 +341,9 @@ export default { }, mounted () { this.queryParams = this.getQueryParams() - this.chartGetMap() this.$nextTick(() => { setTimeout(() => { + this.chartGetMap() this.queryRelated() }, 250) }) diff --git a/src/views/entityExplorer/entityList/detailOverview/Domain.vue b/src/views/entityExplorer/entityList/detailOverview/Domain.vue index 11d8e4c4..a22fa3ce 100644 --- a/src/views/entityExplorer/entityList/detailOverview/Domain.vue +++ b/src/views/entityExplorer/entityList/detailOverview/Domain.vue @@ -47,14 +47,14 @@
{{$t('overall.sent')}}:{{unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ')}}ps
-
+
{
{{$t('overall.received')}}:{{unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ')}}ps
-
+
@@ -161,6 +161,10 @@
{{performance.eventSeverity}}
{{performance.eventType}}
+
+ +
+
@@ -319,6 +323,12 @@ export default { } return queryParams }, + getPerformanceQueryParams () { + const queryParams = { + domain: this.entity.domainName + } + return queryParams + }, handleRelationData (result) { this.entityData.appCount = result.appCount this.entityData.ipCount = result.ipCount diff --git a/src/views/entityExplorer/entityList/detailOverview/Ip.vue b/src/views/entityExplorer/entityList/detailOverview/Ip.vue index 84d2916e..74d5287c 100644 --- a/src/views/entityExplorer/entityList/detailOverview/Ip.vue +++ b/src/views/entityExplorer/entityList/detailOverview/Ip.vue @@ -44,7 +44,7 @@
-
+
@@ -70,14 +70,14 @@
{{$t('overall.sent')}}:{{unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ')}}ps
-
+
{{$t('overall.received')}}:{{unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ')}}ps
-
+
@@ -184,6 +184,10 @@
{{performance.eventSeverity}}
{{performance.eventType}}
+
+ +
+
@@ -385,6 +389,12 @@ export default { } return queryParams }, + getPerformanceQueryParams () { + const queryParams = { + serverIp: this.entity.ipAddr + } + return queryParams + }, handleRelationData (result) { this.entityData.appCount = result.appCount this.entityData.domainCount = result.domainCount diff --git a/src/views/entityExplorer/entityList/detailOverview/entityDetailMixin.js b/src/views/entityExplorer/entityList/detailOverview/entityDetailMixin.js index 99cbdca2..1e0151c8 100644 --- a/src/views/entityExplorer/entityList/detailOverview/entityDetailMixin.js +++ b/src/views/entityExplorer/entityList/detailOverview/entityDetailMixin.js @@ -2,9 +2,14 @@ import _ from 'lodash' import { get } from '@/utils/http' import * as echarts from 'echarts' import { entityListLineOption } from '@/views/charts/charts/chart-options' -import { riskLevelMapping, unitTypes } from '@/utils/constants' +import { riskLevelMapping, unitTypes, storageKey } from '@/utils/constants' import unitConvert from '@/utils/unit-convert' -import { shallowRef } from 'vue' +import { shallowRef, markRaw } from 'vue' +import { metricOption } from '@/views/detections/options/detectionOptions' +import { sortBy, reverseSortBy } from '@/utils/tools' +import { getSecond } from '@/utils/date-util' +import { api } from '@/utils/api' +import axios from 'axios' export default { props: { @@ -27,6 +32,8 @@ export default { receivedChart: null }, chartOption: null, + performanceChartBasicOption: null, + performanceChartOption: null, queryParams: {}, echartsArray: [], performanceData: [], @@ -35,13 +42,16 @@ export default { securityPageSize: 5, performancePageSize: 5, pageNo: 1 - } + }, + metricChart: null, + performanceChartList: [], + loadingPerformance: [] } }, computed: { entityName () { let name - switch (this.entityData.entityType) { + switch (this.entity.entityType) { case ('ip'): { name = this.entity.ipAddr break @@ -179,7 +189,85 @@ export default { }, 250) }) }, + queryEntityDetailPerformanceChart (performanceList, startIndex) { + if (performanceList && performanceList.length > 0) { + const self = this + const performanceEndTimeInterval = axios.defaults.performanceEndTimeInterval + const allTime = Number(performanceEndTimeInterval || 86401) + performanceList.forEach((item, i) => { + const index = startIndex + i + this.loadingPerformance[index] = true + const startTime = getSecond(item.startTime) + const endTime = getSecond(item.startTime) + allTime + const nowTime = getSecond(new Date()) + this.searchStartTime = startTime - allTime / 2 + this.searchEndTime = _.min([nowTime, endTime + allTime / 2]) + let url + if (item.eventType === 'dns error') { + url = api.detection.performanceEvent.dnsErrorMetric + } else if (item.eventType === 'http error') { + url = api.detection.performanceEvent.httpErrorMetric + } else if (item.eventType === 'high dns response time') { + url = api.detection.performanceEvent.highDnsResponseTimeMetric + } + + if (url) { + get(url, { + ...self.getPerformanceQueryParams(), + startTime: self.searchStartTime, + endTime: self.searchEndTime, + eventType: item.eventType + }).then((response) => { + if (response.code === 200) { + const metricDataList = response.data.result[0] && response.data.result[0].values + this.$nextTick(() => { + if (metricDataList && metricDataList.length > 0) { + metricDataList.sort(reverseSortBy(0))// 将返回的数据按时间降序排序,方便找到实线和虚线的交点 + // let endIndex = (self.metricList). findIndex ((item) => item[0] <= 1435781434781 ); + let endIndex = (metricDataList).findIndex((item) => item[0] <= endTime) + endIndex = metricDataList.length - endIndex + + metricDataList.sort(sortBy(0))// 将返回的数据按时间升序排序,方便找到实线和虚线的交点 + // let startIndex = (self.metricList). findIndex ((item) => item[0] >= 1435781432781 ); + const startIndex = metricDataList.findIndex((item) => item[0] >= startTime) + + const performanceChartOption = _.cloneDeep(metricOption) + if (startIndex > -1 && endIndex > -1) { + performanceChartOption.series[0].data = metricDataList.slice(0, startIndex).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.number]) + performanceChartOption.series[1].data = metricDataList.slice(startIndex - 1, endIndex).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.number]) + performanceChartOption.series[2].data = metricDataList.slice(endIndex - 1, metricDataList.length).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.number]) + } + const metricChart = markRaw(echarts.init(document.getElementById(`entityPerformanceChart${self.entityName}_${index}`))) + performanceChartOption && metricChart.setOption(performanceChartOption) + self.performanceChartList.push(metricChart) + this.echartsArray.push(shallowRef(metricChart)) + } else { + const chartDom = document.getElementById(`entityPerformanceChart${self.entityName}${index}`) + chartDom.innerHTML = '-' + } + }) + } + }).catch(error => { + console.log(error) + const chartDom = document.getElementById(`entityPerformanceChart${self.entityName}${index}`) + chartDom.innerHTML = '-' + }).finally(() => { + setTimeout(() => { + try { + this.$nextTick(() => { + self.performanceChartList.forEach(item => { + item && item.resize() + }) + this.loadingPerformance[index] = false + }) + } catch (e) {} + }, 250) + }) + } + }) + } + }, queryEntityDetailRelation () { get(this.relationUrl, this.getQueryParams()).then(response => { if (response.code === 200) { @@ -310,6 +398,11 @@ export default { this.entityData.performanceNum = response.data.result.length this.performanceData = response.data.result this.entityData.performanceList = this.getTargetPageData(1, this.showMore.performancePageSize, this.performanceData) + this.$nextTick(() => { + setTimeout(() => { + this.queryEntityDetailPerformanceChart(this.entityData.performanceList, 0) + }, 200) + }) } this.loadingAlert = false }) @@ -328,8 +421,16 @@ export default { }, performanceShowMore (num) { + const startIndex = this.showMore.performancePageSize this.showMore.performancePageSize += num this.entityData.performanceList = this.getTargetPageData(this.showMore.pageNo, this.showMore.performancePageSize, this.performanceData) + this.$nextTick(() => { + setTimeout(() => { + if (this.entityData.performanceList && this.entityData.performanceList.length > 0) { + this.queryEntityDetailPerformanceChart(this.entityData.performanceList.slice(startIndex, this.entityData.performanceList.length), startIndex) + } + }, 200) + }) }, securityShowMore (num) { @@ -436,5 +537,11 @@ export default { }, beforeUnmount () { window.removeEventListener('resize', this.debounceFunc) + if (this.performanceChartList) { + this.performanceChartList.forEach(item => { + item.dispose() + item = null + }) + } } }