index.vue 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092
  1. <template>
  2. <BasicLayout>
  3. <template #wrapper>
  4. <el-card class="box-card" style="flex:1;">
  5. <div class="container" :class="collapsed==true?&quot;collapsed&quot;:&quot;&quot;">
  6. <div class="box left-box">
  7. <div id="btn-box" class="btn-box" @click="toggleBox()">
  8. <!-- <img :src='togglePng' style='display:block;width:100%' @click='toggleBox()'/> -->
  9. </div>
  10. <div style="padding:10px 10px 10px 0px;background:#fff;">
  11. <div class="box-content">
  12. <div class="flex_box">
  13. <el-tooltip class="item" effect="dark" content="应用层" placement="right">
  14. <div class="left_side y" />
  15. </el-tooltip>
  16. <div class="right_side">
  17. <div class="apdex-box">
  18. <div
  19. class="apdex-con"
  20. :class="ApdexNum>=0.94?'gc'
  21. :(ApdexNum>=0.85&&ApdexNum<0.94)?'bc'
  22. :(ApdexNum>=0.7&&ApdexNum<0.85)?'grc'
  23. :(ApdexNum>=0.5&&ApdexNum<0.7)?'oc'
  24. :'rc'"
  25. >
  26. {{ ApdexNum>=0.94?'性能极佳':(ApdexNum>=0.85 && ApdexNum<0.94)?"性能较好":(ApdexNum>=0.7&&ApdexNum<0.85)?"性能一般":(ApdexNum>=0.5&&ApdexNum<0.7)?"性能一般":"性能不佳" }}
  27. </div>
  28. <div class="ray-box">
  29. <el-button>x-ray</el-button>
  30. </div>
  31. </div>
  32. <div class="card-box">
  33. <h6 class="h6">应用黄金指标(RED)</h6>
  34. <div class="Apply_r">
  35. <el-row type="flex" justify="space-between" :gutter="10" style="margin-bottom:18px;margin-top: 8px;">
  36. <el-col :span="6" :lg="6" :md="6" :sm="6">
  37. <!-- <el-col :span="12" :lg="12" :md="12" :sm="12"> -->
  38. <div class="Apply_r_list">
  39. <p class="value">
  40. {{ (item.apdex==undefined?0:parseFloat(item.apdex).toFixed(2)) }} <img class="arrow" :src="item.apdexFlag==true?g_up:red_down">
  41. </p>
  42. <p class="label">
  43. Apdex
  44. </p>
  45. </div>
  46. </el-col>
  47. <el-col :span="6" :lg="6" :md="6" :sm="6">
  48. <div class="Apply_r_list">
  49. <p class="value">
  50. {{ item.latency==undefined?0:parseFloat(item.latency).toFixed(2) }} <img class="arrow" :src="item.latencyFlag==true?red_up:g_down">
  51. </p>
  52. <p class="label">
  53. 响应时间(ms)
  54. </p>
  55. </div>
  56. </el-col>
  57. <el-col :span="6" :lg="6" :md="6" :sm="6">
  58. <div class="Apply_r_list">
  59. <p class="value">
  60. {{ item.rate==undefined?0:parseFloat(item.rate).toFixed(2) }} <img class="arrow" :src="item.rateFlag==true?g_up:red_down">
  61. </p>
  62. <p class="label">
  63. 吞吐率(rpm)
  64. </p>
  65. </div>
  66. </el-col>
  67. <el-col :span="6" :lg="6" :md="6" :sm="6">
  68. <div class="Apply_r_list">
  69. <p class="value">
  70. {{ item.errorRate==undefined?0:parseFloat(item.errorRate).toFixed(2) }} <img class="arrow" :src="item.errorRateFlag==true?red_up:g_down">
  71. </p>
  72. <p class="label">
  73. 错误率(%)
  74. </p>
  75. </div>
  76. </el-col>
  77. </el-row>
  78. </div>
  79. <div class="interface-box" style="padding:10px 0 0 0">
  80. <h6 class="h6">慢业务TOP5</h6>
  81. <el-table
  82. v-loading="loading2"
  83. :data="slowBusiInterData"
  84. @row-click="handleRowClickBusiness"
  85. >
  86. <el-table-column header-align="left" label="起始服务" prop="service_name" align="left" :show-overflow-tooltip="true" />
  87. <el-table-column header-align="left" label="错误率(%)" prop="error_rate" align="left" :show-overflow-tooltip="true">
  88. <template slot-scope="scope">{{ (scope.row.error_rate*100).toFixed(2) }}%</template>
  89. </el-table-column>
  90. <el-table-column header-align="left" label="平均延迟(ms)" prop="duration" align="left">
  91. <template slot-scope="scope">
  92. <el-tag v-if="scope.row.duration>=2000" type="danger">{{ Number(scope.row.duration).toFixed(2) }}</el-tag>
  93. <el-tag v-if="scope.row.duration<2000" type="info">{{ Number(scope.row.duration).toFixed(2) }}</el-tag>
  94. </template>
  95. </el-table-column>
  96. </el-table>
  97. <div class="look-more" @click="goPath(&quot;/business-analysis/analysis/index&quot;)">查看更多<i class="el-icon-d-arrow-right" /></div>
  98. </div>
  99. </div>
  100. </div>
  101. </div>
  102. <div class="flex_box">
  103. <el-tooltip class="item" effect="dark" content="服务层" placement="right">
  104. <div class="left_side g" />
  105. </el-tooltip>
  106. <div class="right_side">
  107. <div class="service-box">
  108. <h6 class="h6">服务性能</h6>
  109. <div id="serviceBox" class="serviceBox" />
  110. <div class="look-more" @click="goPath(&quot;/service/service/index&quot;)">查看更多<i class="el-icon-d-arrow-right" /></div>
  111. </div>
  112. <div class="interface-box">
  113. <h6 class="h6">慢接口TOP5</h6>
  114. <el-table
  115. v-loading="loading3"
  116. :data="slowTopList"
  117. @row-click="handleRowClickInterFace"
  118. >
  119. <el-table-column header-align="left" label="接口名称" prop="name" align="left" :show-overflow-tooltip="true" />
  120. <el-table-column header-align="left" label="所属服务" prop="service_name" align="left" :show-overflow-tooltip="true" />
  121. <!-- <el-table-column header-align="left" label="Route" prop="route" align="left" :show-overflow-tooltip="true">
  122. <template slot-scope="scope">
  123. <span>{{scope.row.route}}</span>
  124. </template>
  125. </el-table-column> -->
  126. <el-table-column header-align="left" label="请求方法" prop="method" align="left" :show-overflow-tooltip="true" />
  127. <!-- <el-table-column header-align="center" label="错误率" prop="error_rate" width='80' align="center" :show-overflow-tooltip="true">
  128. <template slot-scope="scope">
  129. <el-tag>{{ scope.row.rpm == undefined?0:Number(scope.row.error_rate).toFixed(2)}}</el-tag>
  130. </template>
  131. </el-table-column> -->
  132. <el-table-column header-align="center" label="延迟(ms)" prop="duration" align="center">
  133. <template slot-scope="scope">
  134. <!-- <el-tag>{{ scope.row.duration!= undefined?Number(scope.row.duration).toFixed(2):0}}</el-tag> -->
  135. <el-tag v-if="scope.row.duration>=2000" type="danger">{{ Number(scope.row.duration).toFixed(2) }}</el-tag>
  136. <el-tag v-if="scope.row.duration<2000" type="info">{{ Number(scope.row.duration).toFixed(2) }}</el-tag>
  137. </template>
  138. </el-table-column>
  139. </el-table>
  140. <div class="look-more" @click="goPath(&quot;/service/Interface/index&quot;)">查看更多<i class="el-icon-d-arrow-right" /></div>
  141. </div>
  142. </div>
  143. </div>
  144. <div class="flex_box">
  145. <el-tooltip class="item" effect="dark" content="基础设施层" placement="right">
  146. <div class="left_side b" />
  147. </el-tooltip>
  148. <div class="right_side">
  149. <div class="basic-box">
  150. <h6 class="h6">慢查询TOP5</h6>
  151. <el-table
  152. v-loading="loading"
  153. :data="dbslowtopList"
  154. @row-click="handleRowClick"
  155. >
  156. <el-table-column header-align="left" label="查询方法" prop="span_name" align="left" :show-overflow-tooltip="true" />
  157. <el-table-column header-align="left" label="服务名" prop="service_name" align="left" :show-overflow-tooltip="true">
  158. <template slot-scope="scope">
  159. <span>{{ scope.row.service_name }}</span>
  160. </template>
  161. </el-table-column>
  162. <el-table-column header-align="center" label="SQL语句" prop="statement" align="center" :show-overflow-tooltip="true">
  163. <template slot-scope="scope">
  164. <!-- <el-tag>{{ scope.row.statement }}</el-tag> -->
  165. <span>{{ scope.row.statement }}</span>
  166. </template>
  167. </el-table-column>
  168. <el-table-column header-align="center" label="查询时长(ms)" width="120" prop="duration" align="center">
  169. <template slot-scope="scope">
  170. <el-tag>{{ scope.row.duration== undefined?0:Number(scope.row.duration).toFixed(2) }}</el-tag>
  171. </template>
  172. </el-table-column>
  173. </el-table>
  174. <div class="look-more" @click="goPath(&quot;/service/Interface/index&quot;)">查看更多<i class="el-icon-d-arrow-right" /></div>
  175. </div>
  176. </div>
  177. </div>
  178. </div>
  179. </div>
  180. </div>
  181. <div class="box right-box" style="position:relative;padding:10px;background:#fff;height:calc(100vh - 60px);">
  182. <span id="fullscreen_button" class="title_href">
  183. <svg-icon :icon-class="isFull?'exit-fullscreen':'fullscreen'" @click.native.prevent="clickFull" />
  184. </span>
  185. <div v-loading="loading" style="height:calc(100vh - 60px);">
  186. <iframe
  187. id="topoFrame"
  188. ref="topoFrame"
  189. :src="topoUrl"
  190. style="width:100%;height:calc(100vh - 110px);min-height:600px"
  191. scrolling="auto"
  192. frameBorder="no"
  193. border="0"
  194. marginWidth="0"
  195. marginHeight="0"
  196. />
  197. </div>
  198. </div>
  199. </div>
  200. <div class="topoWrap">
  201. <el-dialog
  202. :visible.sync="VisibleTopo"
  203. :fullscreen="true"
  204. center
  205. >
  206. <div v-loading="loading" style="height:calc(100vh - 10px);">
  207. <iframe
  208. ref="topoFrame"
  209. :src="topoUrl"
  210. style="width:100%;height:calc(100vh - 10px);min-height:700px"
  211. scrolling="auto"
  212. frameBorder="no"
  213. border="0"
  214. marginWidth="0"
  215. marginHeight="0"
  216. />
  217. </div>
  218. </el-dialog>
  219. </div>
  220. </el-card>
  221. </template>
  222. </BasicLayout>
  223. </template>
  224. <script>
  225. import storage from '@/utils/storage'
  226. // import NoData from '@/views/NoData/nodata'
  227. import { serviceBar } from '@/api/service'
  228. import { slowTopUrlMapping, getSlowInterfaceData, listBizStats } from '@/api/mapping'
  229. import { dbslowtop } from '@/api/trace'
  230. import { appsScore } from '@/api/apps'
  231. export default {
  232. // components: {
  233. // NoData
  234. // },
  235. data() {
  236. return {
  237. loading: false,
  238. activeName: 'first',
  239. isFull: false,
  240. VisibleTopo: false,
  241. topoUrl: '/ui/index.html',
  242. sendObj: {},
  243. appName: '',
  244. appId: '',
  245. appItem: {},
  246. collapsed: false,
  247. ApdexNum: 1,
  248. apdex: 0,
  249. item: {
  250. apdex: 0,
  251. latency: 0,
  252. rate: 0,
  253. errorRate: 0
  254. },
  255. bellpin: require('../../../assets/apply/bellpin.png'),
  256. green_down: require('../../../assets/apply/green_down.png'),
  257. green_up: require('../../../assets/apply/green_up.png'),
  258. g_down: require('../../../assets/apply/g_down.jpg'),
  259. g_up: require('../../../assets/apply/g_up.jpg'),
  260. red_down: require('../../../assets/apply/red_down.png'),
  261. red_up: require('../../../assets/apply/red_up.png'),
  262. orange_down: require('../../../assets/apply/orange_down.png'),
  263. orange_up: require('../../../assets/apply/orange_up.png'),
  264. more: require('../../../assets/apply/more.png'),
  265. pushpin: require('../../../assets/apply/pushpin.png'),
  266. green_circle: require('../../../assets/apply/green_circle.png'),
  267. orange_circle: require('../../../assets/apply/orange_circle.png'),
  268. blue_circle: require('../../../assets/apply/blue_circle.png'),
  269. gray_circle: require('../../../assets/apply/gray_circle.png'),
  270. red_circle: require('../../../assets/apply/red_circle.png'),
  271. panelImageURL: require('../../../assets/apply/custom-gauge-panel.png'),
  272. togglePng: require('../../../assets/apply/toggle.png'),
  273. serviceBarQuery: {
  274. start_time: '',
  275. end_time: '',
  276. app_alias: ''
  277. },
  278. serviceBarObj: {},
  279. timer: null,
  280. slowTopQuery: {
  281. app_id: 1,
  282. limit: 5,
  283. start_time: '',
  284. end_time: ''
  285. },
  286. slowTopList: [],
  287. dbslowtopQuery: {
  288. app_alias: '',
  289. limit: 5,
  290. start_time: '',
  291. end_time: ''
  292. },
  293. dbslowtopList: [],
  294. queryScore: {
  295. interval: 5,
  296. req_applist: []
  297. },
  298. slowBusiInterData: [], // 慢业务接口data
  299. loading2: false,
  300. slowBinsTopQuery: {
  301. start_time: '',
  302. end_time: ''
  303. },
  304. loading3: false
  305. }
  306. },
  307. watch: {
  308. '$store.state.time.globalTimes': {
  309. handler(newValue, oldValue) {
  310. var live = false
  311. if (newValue) {
  312. this.topoUrl = ''
  313. this.topoUrl = '/ui/index.html'
  314. this.serviceBarQuery.start_time = newValue.startTime
  315. this.serviceBarQuery.end_time = newValue.endTime
  316. this.slowTopQuery.start_time = newValue.startTime
  317. this.slowTopQuery.end_time = newValue.endTime
  318. this.dbslowtopQuery.start_time = newValue.startTime
  319. this.dbslowtopQuery.end_time = newValue.endTime
  320. this.slowBinsTopQuery.start_time = newValue.startTime
  321. this.slowBinsTopQuery.end_time = newValue.endTime
  322. this.queryScore.interval = newValue.interval
  323. this.getAppsScore() // 应用黄金指标(RED)
  324. this.getdbslowtop() // 慢查询TOP5
  325. this.getServiceBar() // 服务性能
  326. this.getslowTopUrlMapping() // 慢接口TOP5
  327. this.getSlowInterfaceFn()// 慢业务TOP5
  328. }
  329. if (newValue.timeOut) {
  330. if (newValue.timeOut == 1) {
  331. live = false
  332. clearInterval(this.timer)
  333. } else {
  334. live = true
  335. clearInterval(this.timer)
  336. this.Refresh(newValue.timeOut)
  337. }
  338. this.topoUrl = ''
  339. console.log('watch----if000-----this.changeQuery-', newValue.startTime, newValue.endTime)
  340. this.changeQuery('/business-analysis/topology/index', newValue.startTime, newValue.endTime, live)
  341. this.topoUrl = '/ui/index.html'
  342. } else {
  343. live = false
  344. this.topoUrl = ''
  345. console.log('watch----else-----this.changeQuery-', newValue.startTime, newValue.endTime)
  346. this.changeQuery('/business-analysis/topology/index', newValue.startTime, newValue.endTime, live)
  347. this.topoUrl = '/ui/index.html'
  348. }
  349. },
  350. deep: true
  351. },
  352. item: {
  353. handler(newVal, oldVal) {
  354. if (newVal.apdex != undefined && oldVal.apdex != undefined) {
  355. if (parseFloat(newVal.apdex) > parseFloat(oldVal.apdex)) {
  356. newVal.apdexFlag = true
  357. } else {
  358. newVal.apdexFlag = false
  359. }
  360. }
  361. if (newVal.latency != undefined && oldVal.latency != undefined) {
  362. if (parseFloat(newVal.latency) > parseFloat(oldVal.latency)) {
  363. newVal.latencyFlag = true
  364. } else {
  365. newVal.latencyFlag = false
  366. }
  367. }
  368. if (newVal.rate != undefined && oldVal.rate != undefined) {
  369. if (parseFloat(newVal.rate) > parseFloat(oldVal.rate)) {
  370. newVal.rateFlag = true
  371. } else {
  372. newVal.rateFlag = false
  373. }
  374. }
  375. if (newVal.errorRate != undefined && oldVal.errorRate != undefined) {
  376. if (parseFloat(newVal.errorRate) > parseFloat(oldVal.errorRate)) {
  377. newVal.aerrorRateFlag = true
  378. } else {
  379. newVal.errorRateFlag = false
  380. }
  381. }
  382. if (newVal) {
  383. this.basicObj = newVal
  384. }
  385. true
  386. }
  387. },
  388. '$store.state.alias.currentAlias': {
  389. handler(newValue, oldValue) {
  390. this.sendObj.app_alias = newValue
  391. this.serviceBarQuery.app_alias = newValue
  392. this.dbslowtopQuery.app_alias = newValue
  393. this.appItem = storage.get('appsItem')
  394. this.slowTopQuery.app_id = this.appItem.id
  395. this.getAppsScore() // 应用黄金指标(RED)
  396. this.getdbslowtop() // 慢查询TOP5
  397. this.getServiceBar() // 服务性能
  398. this.getslowTopUrlMapping() // 慢接口TOP5
  399. this.getSlowInterfaceFn() // 慢业务TOP5
  400. },
  401. deep: true
  402. }
  403. },
  404. created() {
  405. this.appItem = storage.get('appsItem')
  406. const start_time = this.$store.state.time.globalTimes.startTime
  407. const end_time = this.$store.state.time.globalTimes.endTime
  408. if (JSON.stringify(this.appItem) != '{}') {
  409. this.sendObj.app_alias = this.appItem.alias
  410. this.appName = this.appItem.name
  411. this.item.apdex = this.appItem.apdex
  412. this.item.latency = this.appItem.latency
  413. this.item.rate = this.appItem.rate
  414. this.item.errorRate = this.appItem.errorRate
  415. this.serviceBarQuery.app_alias = this.appItem.alias
  416. this.serviceBarQuery.start_time = start_time
  417. this.serviceBarQuery.end_time = end_time
  418. this.getServiceBar() // 服务性能
  419. this.slowTopQuery.app_id = this.appItem.id
  420. this.slowTopQuery.start_time = start_time
  421. this.slowTopQuery.end_time = end_time
  422. this.getslowTopUrlMapping() // 慢接口TOP5
  423. this.dbslowtopQuery.app_alias = this.appItem.alias
  424. this.dbslowtopQuery.start_time = start_time
  425. this.dbslowtopQuery.end_time = end_time
  426. this.getAppsScore() // 应用黄金指标(RED)
  427. this.getdbslowtop() // 慢查询TOP5
  428. this.changeQuery('/business-analysis/topology/index', start_time, end_time, this.appItem.live)
  429. this.getSlowInterfaceFn() // 慢业务TOP5
  430. }
  431. if (this.$route.query.id != undefined) {
  432. this.appId = this.$route.query.id
  433. }
  434. },
  435. beforeDestroy() {
  436. clearInterval(this.timer)
  437. },
  438. methods: {
  439. getAppsScore() { // 应用黄金指标(RED)
  440. this.queryScore.req_applist.push({ app_alias: this.appItem.alias })
  441. appsScore(this.queryScore).then(res => {
  442. if (res.code == 200) {
  443. if (res.data.scores != null && res.data.scores.length > 0) {
  444. this.item = res.data.scores[0]
  445. this.item.apdexFlag = false
  446. this.item.latencyFlag = false
  447. this.item.rateFlag = false
  448. this.item.errorRateFlag = false
  449. this.ApdexNum = parseFloat(this.item.apdex).toFixed(2)
  450. this.apdex = parseFloat(this.item.apdex).toFixed(2) * 100 - 1
  451. }
  452. }
  453. })
  454. },
  455. handleRowClick(row, column, event) {
  456. const datetime = Date.parse(row.datetime) / 1000
  457. const href = this.$router.resolve({
  458. path: '/latency/index',
  459. query: {
  460. id: row.trace_id,
  461. span_id: row.span_id,
  462. datetime: datetime
  463. }
  464. })
  465. window.open(window.location.origin + '/' + href.href, '_blank')
  466. },
  467. handleRowClickInterFace(row, column, event) {
  468. storage.set('row', row)
  469. const href = this.$router.resolve({
  470. path: '/service/InterfaceDetail/index',
  471. query: {
  472. kind: row.route,
  473. method: row.method,
  474. name: row.name,
  475. service_name: row.service_name
  476. }
  477. })
  478. window.open(window.location.origin + '/' + href.href, '_blank')
  479. },
  480. async handleRowClickBusiness(row) {
  481. row.name = row.biz_name
  482. row.id = row.biz_id
  483. const start_time = this.$store.state.time.globalTimes.startTime
  484. const end_time = this.$store.state.time.globalTimes.endTime
  485. const obj = {
  486. biz_id: row.biz_id,
  487. start_time: start_time,
  488. end_time: end_time
  489. }
  490. const res = await listBizStats(obj)
  491. if (res.code == 200) {
  492. row.quantiles = res.data.quantiles
  493. storage.set('detailObj', row)
  494. this.$router.push({
  495. path: '/business-analysis/analysisDetail/index',
  496. query: {
  497. id: row.biz_id,
  498. name: row.biz_name
  499. }
  500. })
  501. }
  502. },
  503. goPath(path) {
  504. this.$router.push({
  505. path: path
  506. })
  507. },
  508. Refresh(timeOut) {
  509. this.timer = setInterval(() => {
  510. this.getServiceBar() // 服务性能
  511. this.getAppsScore() // 应用黄金指标(RED)
  512. this.getslowTopUrlMapping() // 慢接口TOP5
  513. this.getdbslowtop() // 慢查询TOP5
  514. this.getSlowInterfaceFn() // 慢业务TOP5
  515. }, timeOut)
  516. },
  517. toggleBox() {
  518. this.collapsed = !this.collapsed
  519. },
  520. clickFull() {
  521. this.VisibleTopo = true
  522. },
  523. handleClick(tab, event) {},
  524. populateIframeTopo(iframe) {
  525. const xhrTopo = new XMLHttpRequest()
  526. xhrTopo.open('GET', this.topoUrl)
  527. xhrTopo.responseType = 'blob'
  528. xhrTopo.onreadystatechange = () => {
  529. if (xhrTopo.readyState === xhrTopo.DONE) {
  530. if (xhrTopo.status === 200) {
  531. // iframe.src = URL.createObjectURL(xhr.response)
  532. // iframe.src= _this.topoUrl;
  533. }
  534. }
  535. }
  536. xhrTopo.send()
  537. },
  538. changeQuery(router, start_time, end_time, live) {
  539. this.$router.push({
  540. path: router,
  541. query: {
  542. id: this.appItem.id,
  543. app_alias: this.appItem.alias,
  544. start_time: start_time,
  545. end_time: end_time,
  546. item: this.appItem,
  547. live: live
  548. }
  549. }).catch(err => {
  550. console.log(err)
  551. })
  552. },
  553. getServiceBar() { // 服务性能
  554. serviceBar(this.serviceBarQuery, this.serviceBarQuery.app_alias).then(res => {
  555. if (res.code == 200) {
  556. this.serviceBarObj = res.data
  557. this.initServiceChart(this.serviceBarObj)
  558. }
  559. })
  560. },
  561. initServiceChart(data) {
  562. this.compareChart = this.$echarts5.init(document.getElementById('serviceBox'))
  563. const option = {
  564. color: ['#91CC75', '#EE6666', '#5470C6'],
  565. tooltip: {
  566. trigger: 'axis',
  567. axisPointer: {
  568. type: 'cross'
  569. }
  570. },
  571. grid: {
  572. right: '26%',
  573. bottom: '3%'
  574. },
  575. legend: {
  576. data: ['性能', '错误率', '活跃度']
  577. },
  578. xAxis: [
  579. {
  580. type: 'category',
  581. axisTick: {
  582. alignWithLabel: true
  583. },
  584. axisLabel: {
  585. show: false
  586. },
  587. // prettier-ignore
  588. // data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
  589. data: data.serivce_data
  590. }
  591. ],
  592. yAxis: [
  593. {
  594. type: 'value',
  595. name: '性能',
  596. position: 'left',
  597. alignTicks: true,
  598. axisLine: {
  599. show: true,
  600. lineStyle: {
  601. // color: colors[2]
  602. }
  603. },
  604. axisLabel: {
  605. formatter: '{value}'
  606. }
  607. },
  608. {
  609. type: 'value',
  610. name: '错误率',
  611. position: 'right',
  612. alignTicks: true,
  613. axisLine: {
  614. show: true,
  615. lineStyle: {
  616. // color: '#EE6666'
  617. }
  618. },
  619. axisLabel: {
  620. formatter: '{value} %'
  621. }
  622. },
  623. {
  624. type: 'value',
  625. name: '活跃度',
  626. position: 'right',
  627. offset: 45,
  628. alignTicks: true,
  629. axisLine: {
  630. show: true,
  631. lineStyle: {
  632. // color: '#EE6666'
  633. }
  634. },
  635. axisLabel: {
  636. formatter: '{value}'
  637. }
  638. }
  639. ],
  640. series: [
  641. {
  642. name: '性能',
  643. type: 'bar',
  644. data: data.apdex_data
  645. },
  646. {
  647. name: '错误率',
  648. type: 'line',
  649. yAxisIndex: 1,
  650. data: data.faild_data
  651. },
  652. {
  653. name: '活跃度',
  654. type: 'line',
  655. yAxisIndex: 2,
  656. data: data.liveness_data
  657. }
  658. ]
  659. }
  660. this.compareChart.setOption(option)
  661. window.addEventListener('resize', () => {
  662. this.compareChart.resize()
  663. })
  664. const that = this
  665. that.compareChart.off('click')
  666. that.compareChart.on('click', function(params) {
  667. var dataIndex = params.dataIndex
  668. var seriesIndex = params.seriesIndex
  669. var service_name = data.serivce_data[dataIndex]
  670. that.$router.push({
  671. path: '/service/serviceDetail/index',
  672. query: {
  673. service_name: service_name
  674. }
  675. })
  676. })
  677. that.compareChart.on('restore', function(params) {
  678. that.compareChart.setOption(option)
  679. })
  680. },
  681. getslowTopUrlMapping() { // 慢接口TOP5
  682. this.loading3 = true
  683. slowTopUrlMapping(this.slowTopQuery).then(res => {
  684. if (res.code == 200) {
  685. this.slowTopList = res.data
  686. this.loading3 = false
  687. }
  688. })
  689. },
  690. getdbslowtop() {// 慢查询TOP5
  691. this.loading = true
  692. dbslowtop(this.dbslowtopQuery).then(res => {
  693. if (res.code == 200) {
  694. this.dbslowtopList = res.data
  695. this.loading = false
  696. }
  697. })
  698. },
  699. async getSlowInterfaceFn() { // 慢业务TOP5
  700. this.loading2 = true
  701. const res = await getSlowInterfaceData(this.dbslowtopQuery)
  702. this.loading2 = false
  703. if (res && res.code == 200) {
  704. this.slowBusiInterData = res.data
  705. } else {
  706. this.slowBusiInterData = []
  707. }
  708. }
  709. }
  710. }
  711. </script>
  712. <style scoped lang='scss'>
  713. .title_href{
  714. width:32px;
  715. height:32px;
  716. position: absolute;
  717. top:5px;
  718. right:0px;
  719. display: block;
  720. i{
  721. font-size: 16px;
  722. color:#999;
  723. }
  724. }
  725. .topoWrap ::v-deep .el-dialog__header{
  726. padding:0;
  727. padding-bottom: 0;
  728. }
  729. .topoWrap ::v-deep .el-dialog--center .el-dialog__body{
  730. padding:0;
  731. }
  732. .topoWrap ::v-deep .el-dialog__body{
  733. padding:0;
  734. }
  735. ::v-deep .el-tabs__header{
  736. position: fixed;
  737. top:50.5px;
  738. z-index: 99;
  739. background: #fff;
  740. width: 91.3%;
  741. padding-top:16px;
  742. margin-left: -30px;
  743. }
  744. ::v-deep .el-tabs__nav-wrap {
  745. padding-left: 30px;
  746. }
  747. ::v-deep .el-tabs__content {
  748. overflow: hidden;
  749. position: relative;
  750. margin-top: 56px;
  751. }
  752. .box-card ::v-deep .el-card__body{
  753. padding:0!important;
  754. }
  755. .container {
  756. display: flex;
  757. background:rgb(240,241,245);
  758. // margin-top:10px;
  759. }
  760. .left-box {
  761. position: relative;
  762. height:calc(100vh - 60px);
  763. // padding:10px 0px 10px 0;
  764. box-sizing: border-box;
  765. width: 28%; /* 设置左边盒子的初始宽度 */
  766. background-color: #fff;
  767. transition: width 1s ease; /* 添加过渡动画效果 */
  768. margin-right:16px;
  769. border:1px solid #f5f5f5;
  770. // overflow-y: scroll;
  771. overflow: auto;
  772. .box-content{
  773. background: rgb(249, 249, 251);
  774. // padding: 10px;
  775. overflow-y: scroll;
  776. // padding-left:2px;
  777. }
  778. .btn-box{
  779. width:8px;
  780. height: 100%;
  781. position:absolute;
  782. right:-4px;
  783. top:0;
  784. // transform: translate(-50%,0);
  785. z-index: 4;
  786. cursor: pointer;
  787. }
  788. }
  789. .right-box {
  790. flex: 1; /* 让右边盒子自动占据剩下的空间 */
  791. // height: 300px;
  792. background-color: #fff;
  793. }
  794. /* 当左边盒子被收起时的样式 */
  795. .collapsed .left-box {
  796. width: 12px;
  797. margin-right:0;
  798. position: relative;
  799. }
  800. .apdex-box{
  801. padding:10px;
  802. box-sizing: border-box;
  803. color:#fff;
  804. display: flex;
  805. justify-content: space-between;
  806. align-items: center;
  807. .apdex-con{
  808. width:70%;
  809. // padding:10px;
  810. height: 80px;
  811. line-height: 80px;
  812. box-sizing: border-box;
  813. // border:1px solid #8DBC66;
  814. text-align: center;
  815. font-size:36px;
  816. font-weight:500;
  817. margin-right:16px;
  818. }
  819. .ray-box{
  820. width: 29.9%;
  821. height: 80px;
  822. line-height: 80px;
  823. .el-button {
  824. display: inline-block;
  825. width: 100%;
  826. height: 80px;
  827. line-height: 80px;
  828. padding: 0;
  829. border-radius: 0;
  830. }
  831. }
  832. }
  833. .card-box{
  834. padding:10px;
  835. padding-bottom: 0;
  836. box-sizing: border-box;
  837. }
  838. .service-box{
  839. padding:10px;
  840. box-sizing: border-box;
  841. // .h6{
  842. // font-size: 14px;
  843. // }
  844. .serviceBox{
  845. width: 100%;
  846. height:200px;
  847. box-sizing: border-box;
  848. }
  849. }
  850. .interface-box{
  851. padding:10px;
  852. box-sizing: border-box;
  853. }
  854. .basic-box{
  855. padding:10px;
  856. box-sizing: border-box;
  857. }
  858. // .border_tip{
  859. // position: absolute;
  860. // box-sizing: border-box;
  861. // width:10px;
  862. // height: 255px;
  863. // border-radius: 2px;
  864. // border:2px solid yellow;
  865. // left:0;
  866. // top:0;
  867. // }
  868. .border-y{
  869. // border-left: 8px solid rgba(242,203,69,1);
  870. border-left:8px solid #F0DA8E;
  871. // opacity: 0.7;
  872. }
  873. .border-g{
  874. border-left:8px solid #89AF8D;
  875. margin-bottom:8px;
  876. }
  877. .border-b{
  878. border-left:8px solid #A7A29C;
  879. }
  880. .border_tip{
  881. position: absolute;
  882. box-sizing: border-box;
  883. width:8px;
  884. height: 255px;
  885. // border-radius: 4px;
  886. // border:2px solid #F2CB45;
  887. // background:#F2CB45;
  888. background:rgba(242,203,69,1);
  889. left:0;
  890. top:0;
  891. opacity: 0.7;
  892. }
  893. .border_tip_middle{
  894. position: absolute;
  895. box-sizing: border-box;
  896. width:8px;
  897. height: 632px;
  898. // border-radius: 4px;
  899. // border:2px solid #439058;
  900. background:#439058;
  901. left:0;
  902. top:258px;
  903. opacity: 0.7;
  904. }
  905. .border_tip_bottom{
  906. position: absolute;
  907. box-sizing: border-box;
  908. width:8px;
  909. height: 305px;
  910. // border-radius: 4px;
  911. // border:2px solid #847A71;
  912. background:#847A71;
  913. left:0;
  914. top:893px;
  915. opacity: 0.7;
  916. }
  917. .gc{
  918. // background: #66DC4A;
  919. background:#00B54F;
  920. }
  921. .bc{
  922. background: #60B4F9;
  923. }
  924. .grc{
  925. background: #8B8B8B;
  926. }
  927. .oc{
  928. background: #F1A657;
  929. }
  930. .rc{
  931. background: #EA463D;
  932. }
  933. .green{
  934. border: 2px solid #66DC4A;
  935. }
  936. .blue{
  937. border: 2px solid #60B4F9;
  938. }
  939. .gray{
  940. border: 2px solid #8B8B8B;
  941. }
  942. .orange{
  943. border: 2px solid #F1A657;
  944. }
  945. .red{
  946. border: 2px solid #EA463D;
  947. }
  948. .Apply_r{
  949. // display: flex;
  950. // flex-wrap: wrap;
  951. // align-items: center;
  952. // justify-content:space-between;
  953. // display: grid;
  954. // place-items: center; /* 水平垂直居中 */
  955. // padding:0 24px;
  956. .Apply_r_list{
  957. // width: 1.0625rem;
  958. height: 50px;
  959. background: #E3E7ED;
  960. // border-radius: 8px;
  961. text-align: center;
  962. font-family: PingFangSC-Medium, PingFang SC;
  963. font-weight: 500;
  964. color: #4E5969;
  965. font-size: 12px;
  966. box-sizing: border-box;
  967. padding-top:6px;
  968. padding-bottom: 6px;
  969. }
  970. .value{
  971. line-height: 18px;
  972. font-size: 12px;
  973. }
  974. .value,.label{
  975. line-height: 18px;
  976. font-size: 12px;
  977. white-space: nowrap; /* 不换行 */
  978. overflow: hidden; /* 超出部分隐藏 */
  979. text-overflow: ellipsis; /* 显示省略号 */
  980. }
  981. p{
  982. margin-block-start: 0;
  983. margin-block-end: 0;
  984. }
  985. }
  986. .Apply_r_new{
  987. // display: flex;
  988. // flex-wrap: wrap;
  989. // align-items: center;
  990. // justify-content:space-between;
  991. // display: grid;
  992. // place-items: center; /* 水平垂直居中 */
  993. // padding:0 24px;
  994. .Apply_r_list{
  995. // width: 1.0625rem;
  996. height: 50px;
  997. line-height: 50px;
  998. background: #E3E7ED;
  999. // border-radius: 8px;
  1000. text-align: center;
  1001. font-family: PingFangSC-Medium, PingFang SC;
  1002. font-weight: 500;
  1003. color: #4E5969;
  1004. font-size: 12px;
  1005. box-sizing: border-box;
  1006. // padding-top:6px;
  1007. // padding-bottom: 6px;
  1008. }
  1009. .value{
  1010. // line-height: 18px;
  1011. font-size: 12px;
  1012. }
  1013. .value,.label{
  1014. // line-height: 18px;
  1015. font-size: 12px;
  1016. }
  1017. p{
  1018. margin-block-start: 0;
  1019. margin-block-end: 0;
  1020. }
  1021. }
  1022. .arrow{
  1023. width:8px;
  1024. height:10px;
  1025. margin-left:8px;
  1026. }
  1027. .h6{
  1028. font-size: 14px;
  1029. margin-block-start:0;
  1030. margin-block-end: 0;
  1031. margin:16px 0;
  1032. }
  1033. .look-more{
  1034. margin-top:16px;
  1035. color: #1890ff;
  1036. font-size: 12px;
  1037. text-align: right;
  1038. cursor: pointer;
  1039. i{
  1040. line-height: -3;
  1041. vertical-align: middle;
  1042. }
  1043. }
  1044. .flex_box{
  1045. position: relative;
  1046. margin-bottom: 10px;
  1047. }
  1048. .left_side{
  1049. position: absolute;
  1050. top: 0;
  1051. bottom: 0;
  1052. display: inline-block;
  1053. width:8px;
  1054. }
  1055. .y{
  1056. background:#F0DA8E;
  1057. }
  1058. .g{
  1059. background:#89AF8D;
  1060. }
  1061. .b{
  1062. background:#A7A29C;
  1063. }
  1064. .right_side{
  1065. width:calc(100% - 8px);
  1066. display: inline-block;
  1067. margin-left:10px;
  1068. }
  1069. </style>