Compare commits
148 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0c2cfa5630 | ||
![]() |
5e6e5aa737 | ||
![]() |
a4cd265d45 | ||
![]() |
0ef6b57cae | ||
![]() |
687ae07bb0 | ||
![]() |
0775bf0034 | ||
![]() |
5c322d960f | ||
![]() |
df2d07f508 | ||
![]() |
105450071e | ||
![]() |
39b4626317 | ||
![]() |
0ea8335fee | ||
![]() |
0d2bedf529 | ||
![]() |
b525f84fa0 | ||
![]() |
1fe58f5f6c | ||
![]() |
012ae1db6c | ||
![]() |
79ec865ee7 | ||
![]() |
9ab8ac44bc | ||
![]() |
7a690e6704 | ||
![]() |
65607a5540 | ||
![]() |
5bb4218bfe | ||
![]() |
2b6f3ecaa8 | ||
![]() |
2246a9a045 | ||
![]() |
9318d32b0b | ||
![]() |
8ea50c8680 | ||
![]() |
55b3867bea | ||
![]() |
c33d6c4180 | ||
![]() |
70ea9fd06f | ||
![]() |
2fca7a79a2 | ||
![]() |
f5cfb030a3 | ||
![]() |
fbeeca8d9a | ||
![]() |
ea0f5e5f62 | ||
![]() |
8771ce4a19 | ||
![]() |
99a2461734 | ||
![]() |
fb0817eed8 | ||
![]() |
e164d87209 | ||
![]() |
5c92a46569 | ||
![]() |
aff69c057f | ||
![]() |
7338cec6b4 | ||
![]() |
536df8c052 | ||
![]() |
64d4a2b59b | ||
![]() |
6e1a6cf19b | ||
![]() |
aeddb39637 | ||
![]() |
14fa5d65b6 | ||
![]() |
224e761d70 | ||
![]() |
4c60f69aef | ||
![]() |
0007e3e3ae | ||
![]() |
b6522f4555 | ||
![]() |
bddbe40974 | ||
![]() |
61449f4b17 | ||
![]() |
a92365efcf | ||
![]() |
d65c18bd38 | ||
![]() |
a5b0acda06 | ||
![]() |
e251626374 | ||
![]() |
ed0ec0ac1f | ||
![]() |
1945f23419 | ||
![]() |
d10f4ca0cc | ||
![]() |
a5073dd3d4 | ||
![]() |
ddcc49cb42 | ||
![]() |
ae63538baf | ||
![]() |
d9f819d143 | ||
![]() |
3c8b316b76 | ||
![]() |
6b2b6a5dd2 | ||
![]() |
4e00073ec2 | ||
![]() |
8f179f00a2 | ||
![]() |
fe6e853c57 | ||
![]() |
f664e786ac | ||
![]() |
b6f57aa54e | ||
![]() |
afb70a371b | ||
![]() |
c35bdce399 | ||
![]() |
5419a69700 | ||
![]() |
065337c344 | ||
![]() |
21fe455fd6 | ||
![]() |
88dbee311c | ||
![]() |
9001a96128 | ||
![]() |
e4b2203cf6 | ||
![]() |
54c236bacf | ||
![]() |
f001290658 | ||
![]() |
13b2693f29 | ||
![]() |
731d652a7d | ||
![]() |
7f6e4d09c0 | ||
![]() |
12cd279c90 | ||
![]() |
62eb054ff5 | ||
![]() |
e0bbe99b6c | ||
![]() |
03f321b62a | ||
![]() |
460b24f42c | ||
![]() |
fd2c7ca716 | ||
![]() |
8bc6761468 | ||
![]() |
8746d3c985 | ||
![]() |
c18058765a | ||
![]() |
b9e0eadecb | ||
![]() |
680f1263a5 | ||
![]() |
0e0b4e1ff1 | ||
![]() |
2faeecebcc | ||
![]() |
e25bf9ee8b | ||
![]() |
d0ebdefcee | ||
![]() |
7342036646 | ||
![]() |
8e58f000a0 | ||
![]() |
931cea4c4c | ||
![]() |
ccb4d78f6b | ||
![]() |
860af150f7 | ||
![]() |
7d24e065e9 | ||
![]() |
7aef327d2e | ||
![]() |
f76500bb6e | ||
![]() |
63e01540dc | ||
![]() |
a46b91d1cf | ||
![]() |
5061b19cf7 | ||
![]() |
f809123b4f | ||
![]() |
306508856b | ||
![]() |
867af6924d | ||
![]() |
4ec99fc868 | ||
![]() |
b5c135b811 | ||
![]() |
300ec27ec4 | ||
![]() |
c5d80d96fb | ||
![]() |
001fa25a3b | ||
![]() |
0d82507a87 | ||
![]() |
591484b11c | ||
![]() |
b2ab93926d | ||
![]() |
a1c7a00a83 | ||
![]() |
20e3ef12fe | ||
![]() |
0ea95b1ca6 | ||
![]() |
a18ac3372e | ||
![]() |
c1c086d999 | ||
![]() |
ac57b229fc | ||
![]() |
d8a3c27345 | ||
![]() |
03e1508afc | ||
![]() |
8618a9440e | ||
![]() |
02c5724859 | ||
![]() |
c6d1c49569 | ||
![]() |
8f3ce7d371 | ||
![]() |
2085dc84b9 | ||
![]() |
a4271bb479 | ||
![]() |
832dc1676b | ||
![]() |
780104c5d2 | ||
![]() |
d86543aeed | ||
![]() |
d2eae87957 | ||
![]() |
d9064e8b45 | ||
![]() |
6fb4f074c1 | ||
![]() |
f88c8a9771 | ||
![]() |
1be2792ff4 | ||
![]() |
037c2bbb11 | ||
![]() |
70063c376f | ||
![]() |
e42734ba80 | ||
![]() |
102436ca51 | ||
![]() |
d00fe6df9e | ||
![]() |
6872ad5bf2 | ||
![]() |
3dc929dd53 | ||
![]() |
310fff4b28 | ||
![]() |
63e97edae7 |
2
.github/workflows/nodejs.yml
vendored
@ -37,7 +37,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x, 16.x, 18.x]
|
||||
node-version: [18.x, 20.x, 22.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
|
11
README.md
@ -34,14 +34,15 @@ npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
The default UI address is `http://localhost:8080`.
|
||||
The default UI address is `http://localhost:3000`.
|
||||
|
||||
# Contact Us
|
||||
|
||||
- Submit an [issue](https://github.com/apache/skywalking/issues) if you face some issues. Submit a [discussion](https://github.com/apache/skywalking/discussions) if you want to propose new feature or have any question.
|
||||
- Mailing list: **dev@skywalking.apache.org**. Mail to `dev-subscribe@skywalking.apache.org`, follow the reply to subscribe the mailing list.
|
||||
- Join Slack. Send `Request to join SkyWalking slack` mail to the mail list(`dev@skywalking.apache.org`), we will invite you in.
|
||||
- QQ Group: 392443393, 901167865
|
||||
- Mail list: **dev@skywalking.apache.org**. Mail to `dev-subscribe@skywalking.apache.org`, follow the reply to subscribe to the mail list.
|
||||
- Send `Request to join SkyWalking slack` mail to the mail list(`dev@skywalking.apache.org`), we will invite you in.
|
||||
- For Chinese speaker, send `[CN] Request to join SkyWalking slack` mail to the mail list(`dev@skywalking.apache.org`), we will invite you in.
|
||||
- Twitter, [ASFSkyWalking](https://twitter.com/AsfSkyWalking)
|
||||
- [bilibili B 站 视频](https://space.bilibili.com/390683219)
|
||||
|
||||
# License
|
||||
|
||||
|
@ -17,35 +17,10 @@
|
||||
|
||||
module.exports = {
|
||||
ignores: [(commit) => commit.includes("init")],
|
||||
extends: ["@commitlint/config-conventional"],
|
||||
rules: {
|
||||
"body-leading-blank": [2, "always"],
|
||||
"footer-leading-blank": [1, "always"],
|
||||
"header-max-length": [2, "always", 108],
|
||||
"subject-empty": [2, "never"],
|
||||
"type-empty": [2, "never"],
|
||||
"subject-case": [0],
|
||||
"type-enum": [
|
||||
2,
|
||||
"always",
|
||||
[
|
||||
"feat",
|
||||
"fix",
|
||||
"perf",
|
||||
"style",
|
||||
"docs",
|
||||
"test",
|
||||
"refactor",
|
||||
"build",
|
||||
"ci",
|
||||
"chore",
|
||||
"revert",
|
||||
"wip",
|
||||
"workflow",
|
||||
"types",
|
||||
"release",
|
||||
"merge",
|
||||
],
|
||||
],
|
||||
},
|
||||
};
|
||||
|
10630
package-lock.json
generated
36
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "skywalking-booster-ui",
|
||||
"version": "9.4.0",
|
||||
"version": "10.2.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@ -18,19 +18,17 @@
|
||||
"check-components-types": "if (! git diff --quiet -U0 ./src/types); then echo 'type files are not updated correctly'; git diff -U0 ./src/types; exit 1; fi"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.24.0",
|
||||
"d3": "^7.3.0",
|
||||
"d3-flame-graph": "^4.1.3",
|
||||
"d3-tip": "^0.9.1",
|
||||
"echarts": "^5.2.2",
|
||||
"element-plus": "^2.1.0",
|
||||
"lodash": "^4.17.21",
|
||||
"element-plus": "^2.9.4",
|
||||
"monaco-editor": "^0.34.1",
|
||||
"pinia": "^2.0.28",
|
||||
"vis-timeline": "^7.5.1",
|
||||
"vue": "^3.2.45",
|
||||
"vue-grid-layout": "^3.0.0-beta1",
|
||||
"vue-i18n": "^9.1.9",
|
||||
"vue-i18n": "^9.14.3",
|
||||
"vue-router": "^4.1.6",
|
||||
"vue-types": "^4.1.1"
|
||||
},
|
||||
@ -42,17 +40,16 @@
|
||||
"@types/d3-tip": "^3.5.5",
|
||||
"@types/echarts": "^4.9.12",
|
||||
"@types/jsdom": "^20.0.1",
|
||||
"@types/lodash": "^4.14.179",
|
||||
"@types/node": "^18.11.12",
|
||||
"@types/three": "^0.131.0",
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.0",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vitejs/plugin-vue-jsx": "^4.1.1",
|
||||
"@vue/eslint-config-prettier": "^7.0.0",
|
||||
"@vue/eslint-config-typescript": "^11.0.0",
|
||||
"@vue/test-utils": "^2.2.6",
|
||||
"@vue/tsconfig": "^0.1.3",
|
||||
"@vueuse/core": "^9.6.0",
|
||||
"cypress": "^12.0.2",
|
||||
"cypress": "^13.3.2",
|
||||
"eslint": "^8.22.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"eslint-plugin-vue": "^9.3.0",
|
||||
@ -64,21 +61,21 @@
|
||||
"postcss-html": "^1.3.0",
|
||||
"postcss-scss": "^4.0.2",
|
||||
"prettier": "^2.7.1",
|
||||
"sass": "^1.56.1",
|
||||
"start-server-and-test": "^1.15.2",
|
||||
"sass": "^1.85.0",
|
||||
"start-server-and-test": "^2.0.5",
|
||||
"stylelint": "15.9.0",
|
||||
"stylelint-config-html": "^1.0.0",
|
||||
"stylelint-config-prettier": "9.0.4",
|
||||
"stylelint-config-standard": "^33.0.0",
|
||||
"stylelint-order": "^6.0.3",
|
||||
"typescript": "~4.7.4",
|
||||
"unplugin-auto-import": "^0.7.0",
|
||||
"unplugin-vue-components": "^0.19.2",
|
||||
"vite": "^4.0.5",
|
||||
"typescript": "^5.7.3",
|
||||
"unplugin-auto-import": "^0.18.2",
|
||||
"unplugin-vue-components": "^0.27.3",
|
||||
"vite": "^6.3.4",
|
||||
"vite-plugin-monaco-editor": "^1.1.0",
|
||||
"vite-plugin-svg-icons": "^2.0.1",
|
||||
"vitest": "^0.25.6",
|
||||
"vue-tsc": "^1.0.12"
|
||||
"vitest": "^3.0.5",
|
||||
"vue-tsc": "^2.2.2"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
@ -98,10 +95,7 @@
|
||||
"{!(package)*.json,*.code-snippets,.!(browserslist)*rc}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"package.json": [
|
||||
"prettier --write"
|
||||
],
|
||||
"*.md": [
|
||||
"package.json, *.md": [
|
||||
"prettier --write"
|
||||
]
|
||||
}
|
||||
|
@ -27,10 +27,11 @@ limitations under the License. -->
|
||||
}
|
||||
}, 500);
|
||||
</script>
|
||||
<style>
|
||||
<style lang="scss">
|
||||
#app {
|
||||
color: #2c3e50;
|
||||
color: $font-color;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background-color: $layout-background;
|
||||
}
|
||||
</style>
|
||||
|
@ -12,4 +12,4 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
<svg t="1655799536378" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9286" width="48" height="48"><path d="M563.2 614.4v51.2c0 30.72-20.48 51.2-51.2 51.2s-51.2-20.48-51.2-51.2v-51.2H409.6c-30.72 0-51.2-20.48-51.2-51.2s20.48-51.2 51.2-51.2h51.2V460.8c0-30.72 20.48-51.2 51.2-51.2s51.2 20.48 51.2 51.2v51.2h51.2c30.72 0 51.2 20.48 51.2 51.2s-20.48 51.2-51.2 51.2h-51.2z m51.2-563.2c158.72 15.36 281.6 143.36 281.6 307.2v512c0 56.32-46.08 102.4-102.4 102.4h-563.2c-56.32 0-102.4-46.08-102.4-102.4V153.6c0-56.32 46.08-102.4 102.4-102.4H614.4z m163.84 230.4c-25.6-61.44-76.8-107.52-138.24-122.88v71.68c0 30.72 20.48 51.2 51.2 51.2h87.04zM537.6 153.6h-256c-30.72 0-51.2 20.48-51.2 51.2v614.4c0 30.72 20.48 51.2 51.2 51.2h460.8c30.72 0 51.2-20.48 51.2-51.2V384h-153.6c-56.32 0-102.4-46.08-102.4-102.4V153.6z" fill="#707070" p-id="9287"></path></svg>
|
||||
<svg t="1655799536378" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9286" width="48" height="48"><path d="M563.2 614.4v51.2c0 30.72-20.48 51.2-51.2 51.2s-51.2-20.48-51.2-51.2v-51.2H409.6c-30.72 0-51.2-20.48-51.2-51.2s20.48-51.2 51.2-51.2h51.2V460.8c0-30.72 20.48-51.2 51.2-51.2s51.2 20.48 51.2 51.2v51.2h51.2c30.72 0 51.2 20.48 51.2 51.2s-20.48 51.2-51.2 51.2h-51.2z m51.2-563.2c158.72 15.36 281.6 143.36 281.6 307.2v512c0 56.32-46.08 102.4-102.4 102.4h-563.2c-56.32 0-102.4-46.08-102.4-102.4V153.6c0-56.32 46.08-102.4 102.4-102.4H614.4z m163.84 230.4c-25.6-61.44-76.8-107.52-138.24-122.88v71.68c0 30.72 20.48 51.2 51.2 51.2h87.04zM537.6 153.6h-256c-30.72 0-51.2 20.48-51.2 51.2v614.4c0 30.72 20.48 51.2 51.2 51.2h460.8c30.72 0 51.2-20.48 51.2-51.2V384h-153.6c-56.32 0-102.4-46.08-102.4-102.4V153.6z" p-id="9287"></path></svg>
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@ -12,4 +12,4 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M856.32 428.064a32 32 0 0 0-32 32v163.328H372.48c-0.896 0-1.664 0.448-2.56 0.512v-177.696h244.48a32 32 0 1 0 0-64H130.56c-0.896 0-1.664 0.448-2.56 0.512V231.68h488.16a32 32 0 1 0 0-64H96a32 32 0 0 0-32 32v701.824a32 32 0 0 0 32 32h760.32a32 32 0 0 0 32-32V460.064a32 32 0 0 0-32-32zM128 445.728c0.896 0.064 1.664 0.512 2.56 0.512h175.36v423.264H128V445.728z m241.92 423.776v-182.624c0.896 0.064 1.664 0.512 2.56 0.512h451.84v182.08h-454.4zM960 174.656h-61.376V113.28a32 32 0 1 0-64 0v61.344H752.64a32 32 0 1 0 0 64h81.984v81.984a32 32 0 1 0 64 0V238.656H960a32 32 0 1 0 0-64z" fill="#2c2c2c"></path></svg>
|
||||
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M856.32 428.064a32 32 0 0 0-32 32v163.328H372.48c-0.896 0-1.664 0.448-2.56 0.512v-177.696h244.48a32 32 0 1 0 0-64H130.56c-0.896 0-1.664 0.448-2.56 0.512V231.68h488.16a32 32 0 1 0 0-64H96a32 32 0 0 0-32 32v701.824a32 32 0 0 0 32 32h760.32a32 32 0 0 0 32-32V460.064a32 32 0 0 0-32-32zM128 445.728c0.896 0.064 1.664 0.512 2.56 0.512h175.36v423.264H128V445.728z m241.92 423.776v-182.624c0.896 0.064 1.664 0.512 2.56 0.512h451.84v182.08h-454.4zM960 174.656h-61.376V113.28a32 32 0 1 0-64 0v61.344H752.64a32 32 0 1 0 0 64h81.984v81.984a32 32 0 1 0 64 0V238.656H960a32 32 0 1 0 0-64z"></path></svg>
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB |
18
src/assets/icons/async_profiling.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
|
||||
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M512 992c-83.2 0-166.4-19.2-243.2-64-89.6-51.2-160-134.4-204.8-230.4C25.6 601.6 19.2 486.4 51.2 390.4c25.6-102.4 89.6-192 172.8-256C307.2 70.4 409.6 38.4 518.4 38.4c19.2 0 32 12.8 32 32s-19.2 25.6-38.4 25.6c-89.6 0-179.2 32-256 83.2S128 313.6 108.8 403.2s-12.8 185.6 19.2 268.8c32 83.2 96 153.6 179.2 198.4 76.8 44.8 172.8 64 262.4 51.2 89.6-12.8 172.8-51.2 236.8-115.2s108.8-147.2 115.2-236.8c12.8-89.6-6.4-185.6-51.2-262.4-6.4-12.8-6.4-32 12.8-44.8 12.8-12.8 38.4-6.4 44.8 12.8 51.2 89.6 76.8 198.4 57.6 300.8-12.8 102.4-64 204.8-134.4 275.2-76.8 76.8-172.8 121.6-275.2 134.4-19.2 6.4-44.8 6.4-64 6.4z" p-id="8538"></path><path d="M512 480c-19.2 0-32-12.8-32-32V64c0-19.2 12.8-32 32-32s32 12.8 32 32v384c0 19.2-12.8 32-32 32z" p-id="8539"></path><path d="M512 608c-12.8 0-25.6 0-38.4-6.4-12.8-6.4-19.2-12.8-32-19.2-6.4-12.8-12.8-19.2-19.2-32-6.4-12.8-6.4-25.6-6.4-38.4 0-25.6 12.8-51.2 25.6-70.4 38.4-38.4 102.4-38.4 134.4 0 19.2 19.2 32 44.8 32 70.4 0 25.6-12.8 51.2-25.6 70.4-19.2 12.8-44.8 25.6-70.4 25.6z m0-128c-6.4 0-19.2 6.4-25.6 6.4 0 6.4-6.4 19.2-6.4 25.6v12.8c0 6.4 6.4 6.4 6.4 12.8 0 0 6.4 6.4 12.8 6.4 12.8 6.4 25.6 0 32-6.4 6.4-6.4 12.8-19.2 12.8-25.6 0-6.4-6.4-19.2-6.4-25.6-6.4 0-19.2-6.4-25.6-6.4z" p-id="8540"></path><path d="M512 800c-51.2 0-102.4-12.8-147.2-38.4-57.6-32-96-83.2-121.6-140.8-19.2-57.6-25.6-121.6-6.4-185.6 19.2-64 51.2-115.2 102.4-153.6C384 243.2 448 224 512 224c19.2 0 32 12.8 32 32s-12.8 32-32 32c-51.2 0-96 19.2-134.4 44.8-38.4 32-70.4 76.8-83.2 121.6s-6.4 96 12.8 140.8c19.2 44.8 51.2 83.2 96 108.8 44.8 25.6 89.6 32 140.8 25.6 51.2-6.4 96-32 128-64s57.6-83.2 64-128c6.4-51.2-6.4-96-25.6-140.8-12.8-12.8-6.4-32 6.4-38.4 12.8-6.4 32-6.4 44.8 12.8 32 57.6 44.8 121.6 38.4 179.2-6.4 64-38.4 121.6-83.2 166.4-44.8 44.8-102.4 76.8-166.4 83.2H512z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
16
src/assets/icons/cilium.svg
Normal file
@ -0,0 +1,16 @@
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
|
||||
<svg width="16" height="16" viewBox="20 0 70 72" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="m49.72 45.923-5.505-9.69 5.505-9.69h10.974l5.506 9.69-5.506 9.69H49.72ZM49.72 69.367l-5.505-9.69 5.505-9.689h10.974l5.506 9.69-5.506 9.69H49.72ZM49.72 22.477l-5.505-9.689 5.505-9.69h10.974l5.506 9.69-5.506 9.69H49.72ZM70.06 57.644l-5.506-9.69 5.506-9.69h10.974l5.506 9.69-5.506 9.69H70.06ZM70.06 34.2l-5.506-9.69 5.506-9.69h10.974l5.506 9.69-5.506 9.69H70.06ZM29.357 57.644l-5.506-9.69 5.506-9.69h10.974l5.506 9.69-5.506 9.69H29.357ZM29.357 34.2l-5.506-9.69 5.506-9.69h10.974l5.506 9.69-5.506 9.69H29.357Z" stroke="#141A1F" stroke-width="2.771"/><path d="M10.784 95.947c1.026.007 " fill="#141A1F"/></svg>
|
After Width: | Height: | Size: 1.4 KiB |
38
src/assets/icons/data_processing_engine.svg
Normal file
@ -0,0 +1,38 @@
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
|
||||
<svg width="2400" height="2400" viewBox="0 0 200 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<defs>
|
||||
<marker id="arrowhead" markerWidth="8" markerHeight="8" refX="2" refY="2.5" orient="auto">
|
||||
<polygon points="0 0, 3 2.5, 0 5" fill="white" />
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<line x1="0" y1="20" x2="42" y2="20" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
|
||||
<line x1="0" y1="50" x2="42" y2="50" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
|
||||
<line x1="0" y1="80" x2="42" y2="80" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
|
||||
|
||||
|
||||
<line x1="49" y1="10" x2="139" y2="10" stroke="white" stroke-width="7" />
|
||||
<line x1="49" y1="90" x2="139" y2="90" stroke="white" stroke-width="7" />
|
||||
<line x1="49" y1="10" x2="50" y2="90" stroke="white" stroke-width="7" />
|
||||
|
||||
<ellipse cx="140" cy="50" rx="10" ry="40" fill="none" stroke="white" stroke-width="7" />
|
||||
|
||||
<line x1="147" y1="20" x2="190" y2="20" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
|
||||
<line x1="149" y1="50" x2="190" y2="50" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
|
||||
<line x1="147" y1="80" x2="190" y2="80" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
@ -13,4 +13,4 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
|
||||
<svg t="1654161407133" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1721" width="16" height="16"><path d="M804.224 86.144c0-19.264-15.616-34.944-34.944-34.944l-734.336 0c-19.264 0-34.944 15.68-34.944 34.944l0 82.048 804.224 0 0-82.048zM738.88 602.432c0 47.072-38.176 85.248-85.248 85.248s-85.248-38.176-85.248-85.248c0-47.072 38.176-85.248 85.248-85.248s85.248 38.176 85.248 85.248zM804.992 264.64l0-62.976-804.224 0 0 665.408c0 18.56 14.656 33.472 32.96 34.56l402.24 0c61.12 44.544 136.192 71.168 217.664 71.168 204.544 0 370.368-165.824 370.368-370.368 0-150.592-89.984-279.936-219.008-337.792zM412.096 298.24l30.528 0c-10.624 7.36-20.8 15.36-30.528 23.744l0-23.744zM63.04 298.24l153.024 0 0 153.024-153.024 0 0-153.024zM216.064 805.056l-153.024 0 0-153.024 153.024 0 0 153.024zM219.136 631.232l-153.024 0 0-153.024 153.024 0 0 153.024zM237.568 805.056l0-153.024 49.408 0c7.488 55.936 27.264 107.904 56.832 153.024l-106.24 0zM284.672 631.232l-44.032 0 0-153.024 64.384 0c-13.824 38.848-21.824 80.576-21.824 124.224 0 9.728 0.768 19.264 1.472 28.8zM390.592 341.76c-31.168 31.424-56.512 68.544-74.88 109.44l-78.144 0 0-152.96 153.024 0 0 43.52zM899.136 638.4l-63.36 12.864c-4.288 16.064-10.688 31.296-18.816 45.376l35.712 53.888-50.944 50.944-53.888-35.712c-14.08 8.128-29.312 14.528-45.376 18.816l-12.864 63.36-72 0-12.864-63.36c-16.064-4.288-31.296-10.688-45.376-18.816l-53.888 35.712-50.944-50.944 35.712-53.888c-8.128-14.08-14.528-29.312-18.816-45.376l-63.36-12.864 0-72 63.36-12.864c4.352-16.064 10.688-31.296 18.816-45.312l-35.712-53.952 50.944-50.944 53.888 35.776c14.08-8.128 29.312-14.464 45.376-18.816l12.864-63.36 72 0 12.864 63.36c16.064 4.288 31.296 10.688 45.376 18.816l53.888-35.712 50.944 50.944-35.712 53.824c8.128 14.08 14.528 29.312 18.816 45.376l63.36 12.864 0 72z" p-id="1722" fill="#707070"></path></svg>
|
||||
<svg t="1654161407133" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1721" width="16" height="16"><path d="M804.224 86.144c0-19.264-15.616-34.944-34.944-34.944l-734.336 0c-19.264 0-34.944 15.68-34.944 34.944l0 82.048 804.224 0 0-82.048zM738.88 602.432c0 47.072-38.176 85.248-85.248 85.248s-85.248-38.176-85.248-85.248c0-47.072 38.176-85.248 85.248-85.248s85.248 38.176 85.248 85.248zM804.992 264.64l0-62.976-804.224 0 0 665.408c0 18.56 14.656 33.472 32.96 34.56l402.24 0c61.12 44.544 136.192 71.168 217.664 71.168 204.544 0 370.368-165.824 370.368-370.368 0-150.592-89.984-279.936-219.008-337.792zM412.096 298.24l30.528 0c-10.624 7.36-20.8 15.36-30.528 23.744l0-23.744zM63.04 298.24l153.024 0 0 153.024-153.024 0 0-153.024zM216.064 805.056l-153.024 0 0-153.024 153.024 0 0 153.024zM219.136 631.232l-153.024 0 0-153.024 153.024 0 0 153.024zM237.568 805.056l0-153.024 49.408 0c7.488 55.936 27.264 107.904 56.832 153.024l-106.24 0zM284.672 631.232l-44.032 0 0-153.024 64.384 0c-13.824 38.848-21.824 80.576-21.824 124.224 0 9.728 0.768 19.264 1.472 28.8zM390.592 341.76c-31.168 31.424-56.512 68.544-74.88 109.44l-78.144 0 0-152.96 153.024 0 0 43.52zM899.136 638.4l-63.36 12.864c-4.288 16.064-10.688 31.296-18.816 45.376l35.712 53.888-50.944 50.944-53.888-35.712c-14.08 8.128-29.312 14.528-45.376 18.816l-12.864 63.36-72 0-12.864-63.36c-16.064-4.288-31.296-10.688-45.376-18.816l-53.888 35.712-50.944-50.944 35.712-53.888c-8.128-14.08-14.528-29.312-18.816-45.376l-63.36-12.864 0-72 63.36-12.864c4.352-16.064 10.688-31.296 18.816-45.312l-35.712-53.952 50.944-50.944 53.888 35.776c14.08-8.128 29.312-14.464 45.376-18.816l12.864-63.36 72 0 12.864 63.36c16.064 4.288 31.296 10.688 45.376 18.816l53.888-35.712 50.944 50.944-35.712 53.824c8.128 14.08 14.528 29.312 18.816 45.376l63.36 12.864 0 72z" p-id="1722"></path></svg>
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
@ -12,4 +12,4 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
<svg t="1655695739627" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2218" width="48" height="48"><path d="M173.292308 177.230769C86.646154 265.846154 39.384615 382.030769 39.384615 504.123077 39.384615 531.692308 61.046154 551.384615 86.646154 551.384615s47.261538-21.661538 47.261538-47.261538c-1.969231-96.492308 37.415385-189.046154 106.338462-257.969231s163.446154-106.338462 257.969231-106.338461c27.569231 0 47.261538-21.661538 47.261538-47.261539 0-27.569231-21.661538-47.261538-47.261538-47.261538C378.092308 43.323077 259.938462 90.584615 173.292308 177.230769z m57.107692 326.892308c0 27.569231 19.692308 47.261538 47.261538 47.261538s47.261538-21.661538 47.261539-47.261538c0-45.292308 17.723077-90.584615 51.2-122.092308 33.476923-33.476923 76.8-49.230769 122.092308-51.2 27.569231 0 47.261538-21.661538 47.261538-47.261538 0-27.569231-19.692308-47.261538-47.261538-47.261539-70.892308 0-139.815385 27.569231-191.015385 76.8-7.876923 9.846154-80.738462 82.707692-76.8 191.015385z m665.6-204.8c-17.723077-23.630769-41.353846-51.2-45.292308-55.138462-5.907692-3.938462-13.784615-7.876923-21.661538-7.876923-7.876923 0-15.753846 1.969231-19.692308 7.876923L610.461538 441.107692c-47.261538-39.384615-118.153846-37.415385-163.446153 7.876923-45.292308 45.292308-47.261538 116.184615-7.876923 163.446154l-191.015385 191.015385c-5.907692 5.907692-9.846154 13.784615-9.846154 21.661538 0 9.846154 3.938462 19.692308 11.815385 25.6l53.16923 39.384616c72.861538 57.107692 163.446154 88.615385 259.938462 88.615384 232.369231 0 421.415385-189.046154 421.415385-421.415384 0-94.523077-33.476923-185.107692-88.615385-257.969231z" p-id="2219" fill="#707070"></path></svg>
|
||||
<svg t="1655695739627" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2218" width="48" height="48"><path d="M173.292308 177.230769C86.646154 265.846154 39.384615 382.030769 39.384615 504.123077 39.384615 531.692308 61.046154 551.384615 86.646154 551.384615s47.261538-21.661538 47.261538-47.261538c-1.969231-96.492308 37.415385-189.046154 106.338462-257.969231s163.446154-106.338462 257.969231-106.338461c27.569231 0 47.261538-21.661538 47.261538-47.261539 0-27.569231-21.661538-47.261538-47.261538-47.261538C378.092308 43.323077 259.938462 90.584615 173.292308 177.230769z m57.107692 326.892308c0 27.569231 19.692308 47.261538 47.261538 47.261538s47.261538-21.661538 47.261539-47.261538c0-45.292308 17.723077-90.584615 51.2-122.092308 33.476923-33.476923 76.8-49.230769 122.092308-51.2 27.569231 0 47.261538-21.661538 47.261538-47.261538 0-27.569231-19.692308-47.261538-47.261538-47.261539-70.892308 0-139.815385 27.569231-191.015385 76.8-7.876923 9.846154-80.738462 82.707692-76.8 191.015385z m665.6-204.8c-17.723077-23.630769-41.353846-51.2-45.292308-55.138462-5.907692-3.938462-13.784615-7.876923-21.661538-7.876923-7.876923 0-15.753846 1.969231-19.692308 7.876923L610.461538 441.107692c-47.261538-39.384615-118.153846-37.415385-163.446153 7.876923-45.292308 45.292308-47.261538 116.184615-7.876923 163.446154l-191.015385 191.015385c-5.907692 5.907692-9.846154 13.784615-9.846154 21.661538 0 9.846154 3.938462 19.692308 11.815385 25.6l53.16923 39.384616c72.861538 57.107692 163.446154 88.615385 259.938462 88.615384 232.369231 0 421.415385-189.046154 421.415385-421.415384 0-94.523077-33.476923-185.107692-88.615385-257.969231z" p-id="2219"></path></svg>
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
18
src/assets/icons/hierarchy_topology.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
|
||||
<svg t="1704964118567" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5167">
|
||||
<path d="M900.032 646.016h-56.064V502.976a16 16 0 0 0-16-16H544v-96h62.976c22.144 0 40-17.92 40-40V161.024a40 40 0 0 0-40-40H417.024a40 40 0 0 0-40 40v189.952c0 22.144 17.92 40 40 40H480v96H195.968a16 16 0 0 0-16 16v143.04h-55.936a38.016 38.016 0 0 0-38.016 38.016v176c0 20.928 17.024 37.952 37.952 37.952h176a38.016 38.016 0 0 0 38.016-38.016v-176a38.016 38.016 0 0 0-37.952-37.952h-56V550.976H480v95.04h-56a38.016 38.016 0 0 0-38.016 38.016v176c0 20.928 17.024 37.952 38.016 37.952h176a38.016 38.016 0 0 0 38.016-38.016v-176a38.016 38.016 0 0 0-38.016-37.952H544V550.976h236.032v95.04h-56.064a38.016 38.016 0 0 0-37.952 38.016v176c0 20.928 17.024 37.952 38.016 37.952h176a38.016 38.016 0 0 0 37.952-38.016v-176a38.016 38.016 0 0 0-38.016-37.952zM440.96 184.96h141.952v141.952H441.024V185.024zM278.016 838.016H145.92V705.92h132.032v132.032z m299.968 0H446.08V705.92H577.92v132.032z m300.032 0h-132.032V705.92h132.032v132.032z" p-id="5168"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
138
src/assets/icons/logo-light.svg
Normal file
@ -0,0 +1,138 @@
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400.000000 400.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,400.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1737 3725 c-379 -61 -696 -224 -968 -495 -249 -248 -403 -533 -481
|
||||
-890 -20 -93 -22 -133 -22 -340 0 -207 2 -247 22 -339 48 -217 123 -407 231
|
||||
-581 253 -406 658 -688 1141 -791 91 -20 135 -23 330 -24 172 0 246 4 315 17
|
||||
361 69 669 231 926 487 271 272 438 604 494 983 23 154 16 448 -15 593 -147
|
||||
694 -668 1214 -1366 1365 -130 29 -472 37 -607 15z m461 -131 c24 -3 52 -14
|
||||
63 -25 23 -23 25 -76 3 -100 -15 -17 -15 -19 0 -34 25 -26 20 -82 -10 -112
|
||||
-25 -25 -28 -25 -112 -19 -48 4 -88 8 -89 10 -1 1 4 60 12 131 8 72 15 137 15
|
||||
145 0 17 14 17 118 4z m-359 -30 c30 -22 61 -89 61 -137 0 -48 -22 -102 -48
|
||||
-116 -23 -12 -163 -43 -169 -38 -7 7 -53 280 -48 285 8 9 78 20 130 21 32 1
|
||||
59 -5 74 -15z m564 -8 c7 -8 22 -44 31 -80 l18 -66 62 48 c48 38 66 47 85 43
|
||||
23 -6 18 -12 -58 -71 -76 -61 -83 -69 -98 -122 -12 -43 -21 -58 -34 -58 -28 0
|
||||
-30 14 -10 73 l19 56 -29 93 c-16 51 -29 94 -29 96 0 8 31 0 43 -12z m-858
|
||||
-45 c0 -8 -30 -27 -69 -43 -38 -15 -71 -30 -74 -32 -4 -4 17 -76 22 -76 1 0
|
||||
31 11 66 25 76 30 90 31 90 7 0 -13 -19 -24 -70 -42 -61 -21 -69 -27 -64 -45
|
||||
15 -46 24 -65 32 -65 5 0 42 14 82 30 57 23 75 27 82 18 4 -7 8 -16 8 -19 0
|
||||
-7 -180 -79 -197 -79 -6 0 -28 44 -49 98 -20 53 -43 112 -51 131 -7 19 -11 36
|
||||
-9 38 10 11 173 71 186 70 8 -1 15 -9 15 -16z m-257 -157 c26 -29 28 -61 6
|
||||
-92 -12 -17 -12 -22 -2 -22 7 0 42 -13 77 -29 62 -28 63 -29 41 -44 -21 -15
|
||||
-26 -14 -59 2 -20 10 -53 24 -73 30 -37 12 -37 13 -96 -25 -2 -1 13 -27 32
|
||||
-58 34 -52 35 -56 17 -65 -17 -10 -27 2 -92 101 -39 62 -74 119 -76 128 -2 9
|
||||
14 26 44 44 119 73 138 76 181 30z m-292 -145 c3 -6 -19 -37 -52 -70 l-58 -59
|
||||
29 -30 29 -30 56 55 c48 47 59 54 69 42 10 -12 2 -24 -44 -68 l-56 -52 32 -33
|
||||
32 -33 64 59 c52 47 68 57 78 47 11 -10 -1 -27 -66 -92 l-80 -80 -99 105 c-55
|
||||
58 -100 108 -100 111 0 10 139 139 150 139 5 0 12 -5 16 -11z m1197 -44 c494
|
||||
-74 896 -467 982 -959 19 -113 19 -299 0 -410 -73 -416 -377 -773 -776 -910
|
||||
-142 -48 -213 -59 -384 -59 -175 -1 -241 10 -400 65 -383 131 -680 481 -761
|
||||
893 -22 115 -20 335 5 450 79 372 314 669 656 831 214 102 441 135 678 99z
|
||||
m-1319 -258 c81 -91 95 -110 86 -126 -9 -18 -14 -18 -122 16 -62 19 -117 38
|
||||
-123 41 -10 6 17 -27 109 -133 41 -46 48 -60 39 -73 -13 -20 0 -23 -160 28
|
||||
-89 28 -133 47 -133 56 0 28 27 25 134 -15 73 -26 103 -34 94 -23 -7 9 -43 50
|
||||
-80 91 -55 61 -65 78 -57 93 13 25 30 23 147 -15 l103 -33 -82 82 c-67 67 -80
|
||||
85 -74 103 4 12 10 21 14 19 4 -2 51 -51 105 -111z m2502 -151 c38 -38 44 -77
|
||||
19 -126 -19 -37 -43 -50 -95 -50 -61 0 -100 41 -100 105 0 40 5 52 31 76 46
|
||||
42 99 41 145 -5z m-2677 -171 c16 -8 41 -29 56 -47 24 -29 27 -38 23 -91 -4
|
||||
-54 -8 -63 -41 -93 -32 -30 -44 -34 -90 -34 -126 0 -200 102 -150 207 9 20 30
|
||||
44 47 54 38 23 115 25 155 4z m-145 -306 c35 -16 50 -59 42 -124 l-6 -54 32
|
||||
-5 c18 -3 44 -7 58 -8 19 -2 24 -8 22 -23 -2 -11 -5 -21 -6 -22 -5 -6 -272 30
|
||||
-280 37 -5 5 -4 42 3 87 9 63 16 82 37 101 28 24 60 28 98 11z m2717 -590 c14
|
||||
-7 18 -16 14 -27 -4 -9 -20 -52 -36 -95 l-29 -78 33 -13 c77 -32 72 -34 105
|
||||
51 29 75 55 102 67 70 3 -7 -7 -48 -24 -90 l-29 -76 55 -21 c30 -11 58 -18 62
|
||||
-15 5 2 23 45 41 95 31 87 41 99 68 82 10 -7 2 -36 -32 -126 -25 -65 -47 -120
|
||||
-49 -123 -3 -2 -82 26 -177 62 -95 36 -175 65 -177 65 -9 0 1 33 39 137 24 62
|
||||
44 113 46 113 2 0 12 -5 23 -11z m34 -411 c80 -57 145 -106 145 -109 0 -3 -6
|
||||
-14 -14 -24 -13 -18 -17 -16 -79 28 -36 26 -69 47 -74 47 -10 0 -113 -145
|
||||
-113 -158 0 -7 61 -53 122 -93 14 -9 -11 -52 -26 -46 -10 4 -288 198 -304 212
|
||||
-6 5 18 45 26 45 5 0 36 -21 71 -46 34 -25 64 -44 65 -42 1 2 25 35 52 73 28
|
||||
39 53 75 57 81 4 7 -18 29 -58 55 -35 24 -65 49 -65 55 0 16 23 35 38 29 7 -2
|
||||
78 -51 157 -107z m-2350 -142 c35 -15 65 -59 65 -96 0 -54 -57 -110 -112 -110
|
||||
-13 0 -37 9 -55 20 -69 41 -63 154 9 185 42 18 51 18 93 1z m2003 -75 c8 -5
|
||||
12 -17 10 -27 -3 -14 -11 -18 -33 -17 -82 7 -145 -48 -145 -126 0 -89 73 -161
|
||||
162 -161 43 0 54 4 84 34 27 27 34 42 34 74 0 32 4 41 22 45 29 8 38 1 38 -31
|
||||
-1 -38 -32 -102 -66 -133 -75 -69 -196 -57 -276 28 -27 28 -58 99 -58 132 0
|
||||
65 56 152 115 177 34 15 94 18 113 5z m-247 -340 c79 -74 145 -138 147 -142 2
|
||||
-4 -7 -13 -19 -19 -19 -11 -26 -7 -65 31 l-43 42 -68 -31 -68 -32 -3 -64 c-2
|
||||
-55 -6 -66 -23 -71 -11 -4 -23 -5 -25 -2 -3 2 -9 94 -14 203 -8 180 -7 200 8
|
||||
212 9 7 19 11 23 10 4 -2 71 -63 150 -137z m-321 34 c58 -30 78 -120 40 -182
|
||||
-19 -31 -48 -44 -151 -67 l-26 -6 14 -60 c15 -68 12 -80 -20 -80 -20 0 -24 12
|
||||
-56 173 -19 94 -36 179 -38 188 -4 12 11 19 64 31 90 20 138 21 173 3z m-334
|
||||
-207 c38 -105 71 -195 72 -200 2 -4 -10 -8 -26 -8 -28 0 -32 5 -49 58 l-20 57
|
||||
-79 3 -79 3 -27 -54 c-24 -49 -29 -54 -53 -50 -14 3 -25 9 -23 13 2 3 41 88
|
||||
87 188 112 243 106 244 197 -10z"/>
|
||||
<path d="M2120 3537 c0 -14 -2 -32 -6 -40 -4 -11 6 -16 43 -20 54 -6 83 5 83
|
||||
32 0 27 -24 43 -75 49 -43 4 -45 3 -45 -21z"/>
|
||||
<path d="M2105 3399 c-4 -22 -5 -42 -2 -45 9 -10 77 -16 101 -10 52 13 44 70
|
||||
-12 86 -68 19 -79 14 -87 -31z"/>
|
||||
<path d="M1697 3533 c-13 -3 -17 -11 -14 -26 3 -12 11 -58 18 -102 7 -44 14
|
||||
-81 15 -83 7 -10 96 13 113 29 39 36 21 165 -24 183 -18 7 -80 6 -108 -1z"/>
|
||||
<path d="M1156 3310 l-47 -30 22 -33 c12 -17 24 -34 25 -36 6 -7 94 50 103 67
|
||||
5 10 5 27 0 40 -12 31 -45 28 -103 -8z"/>
|
||||
<path d="M1060 2137 c-20 -10 -25 -20 -25 -52 0 -37 4 -42 53 -75 79 -52 68
|
||||
-97 -21 -88 -23 2 -32 -1 -32 -12 0 -11 14 -16 57 -18 48 -2 60 0 77 19 40 43
|
||||
27 78 -46 125 -71 45 -70 68 5 72 35 2 52 7 52 16 0 26 -78 34 -120 13z"/>
|
||||
<path d="M1230 2020 c0 -123 1 -130 20 -130 17 0 20 7 20 43 l1 42 20 -25 c12
|
||||
-14 27 -33 34 -43 8 -11 22 -17 35 -15 21 3 20 4 -9 43 -38 50 -38 61 0 105
|
||||
29 34 29 35 8 38 -12 2 -26 -4 -34 -15 -7 -10 -22 -29 -34 -43 l-20 -25 -1 78
|
||||
c0 70 -2 77 -20 77 -19 0 -20 -7 -20 -130z"/>
|
||||
<path d="M2030 1976 c0 -130 1 -136 20 -136 20 0 20 5 18 132 -3 117 -5 133
|
||||
-20 136 -16 3 -18 -8 -18 -132z"/>
|
||||
<path d="M2133 2103 c-10 -3 -13 -40 -13 -134 0 -121 1 -129 19 -129 16 0 20
|
||||
8 23 43 l3 42 30 -42 c20 -28 38 -42 53 -43 12 0 22 3 22 6 0 3 -16 26 -35 51
|
||||
l-35 46 35 43 c40 48 42 54 18 54 -10 0 -35 -19 -55 -42 l-37 -43 -1 78 c0 75
|
||||
-2 81 -27 70z"/>
|
||||
<path d="M2310 2090 c0 -13 7 -20 20 -20 13 0 20 7 20 20 0 13 -7 20 -20 20
|
||||
-13 0 -20 -7 -20 -20z"/>
|
||||
<path d="M1410 2073 c0 -5 7 -30 15 -58 9 -27 20 -67 26 -87 5 -22 16 -38 24
|
||||
-38 8 0 15 -4 15 -8 0 -17 -25 -32 -52 -32 -18 0 -28 -5 -28 -15 0 -22 72 -20
|
||||
92 3 9 9 28 60 42 112 15 52 29 103 32 113 5 15 1 18 -17 15 -17 -2 -25 -12
|
||||
-32 -38 -23 -94 -29 -110 -36 -106 -5 3 -11 20 -15 38 -17 85 -27 108 -46 108
|
||||
-11 0 -20 -3 -20 -7z"/>
|
||||
<path d="M1766 2031 c-3 -4 -8 -35 -12 -67 -8 -75 -19 -96 -28 -58 -25 105
|
||||
-26 105 -53 102 -23 -3 -29 -10 -41 -58 -15 -63 -32 -88 -32 -48 0 14 -3 40
|
||||
-7 59 -5 28 -7 30 -14 14 -13 -35 -10 -112 6 -125 29 -24 49 -7 67 55 9 33 17
|
||||
62 18 65 1 3 11 -24 23 -60 19 -57 25 -65 47 -65 22 0 27 7 37 50 7 28 16 71
|
||||
19 98 5 39 4 47 -9 47 -9 0 -18 -4 -21 -9z"/>
|
||||
<path d="M1853 2033 c-7 -2 -13 -12 -13 -20 0 -12 7 -14 31 -9 34 7 69 -8 69
|
||||
-28 0 -8 -17 -16 -42 -20 -53 -9 -68 -21 -68 -57 0 -43 21 -57 90 -56 l60 0 0
|
||||
68 c0 103 -19 130 -90 128 -14 0 -31 -3 -37 -6z m87 -128 c0 -18 -7 -26 -24
|
||||
-31 -30 -7 -46 1 -46 25 0 24 9 31 42 31 23 0 28 -4 28 -25z"/>
|
||||
<path d="M2317 2033 c-4 -3 -7 -48 -7 -100 0 -86 1 -93 20 -93 19 0 20 7 20
|
||||
100 0 77 -3 100 -13 100 -8 0 -17 -3 -20 -7z"/>
|
||||
<path d="M2400 1938 c0 -91 1 -98 20 -98 17 0 19 8 22 78 l3 77 35 0 35 0 3
|
||||
-77 c3 -70 5 -78 22 -78 18 0 20 7 20 78 0 106 -9 117 -94 118 l-66 1 0 -99z"/>
|
||||
<path d="M2642 2025 l-33 -14 4 -73 c2 -40 -1 -84 -7 -97 -9 -20 -6 -27 17
|
||||
-47 51 -43 147 -23 147 30 0 31 -16 43 -78 57 -64 15 -67 29 -7 29 58 0 90 28
|
||||
81 71 -3 15 -1 31 4 34 39 24 -74 32 -128 10z m74 -29 c27 -20 7 -51 -32 -51
|
||||
-23 0 -30 5 -32 24 -6 38 29 52 64 27z m-8 -151 c14 -4 22 -13 20 -23 -4 -22
|
||||
-60 -28 -77 -9 -15 19 -3 49 18 43 9 -2 26 -7 39 -11z"/>
|
||||
<path d="M549 2531 c-50 -50 -35 -120 33 -151 52 -24 80 -25 117 -5 72 37 56
|
||||
137 -26 171 -52 22 -91 18 -124 -15z"/>
|
||||
<path d="M471 2222 c-10 -19 -18 -99 -11 -105 3 -2 24 -7 47 -10 l42 -5 7 54
|
||||
c4 37 2 59 -6 69 -17 21 -67 19 -79 -3z"/>
|
||||
<path d="M2571 750 c0 -25 4 -66 7 -91 l7 -46 57 27 57 27 -65 64 -64 63 1
|
||||
-44z"/>
|
||||
<path d="M2247 708 c-25 -7 -36 -15 -33 -23 2 -7 10 -41 17 -74 l12 -62 31 6
|
||||
c84 17 103 26 114 50 17 37 15 59 -9 89 -23 29 -61 33 -132 14z"/>
|
||||
<path d="M1927 590 l-36 -75 60 -9 c33 -5 62 -7 64 -4 4 4 -4 28 -47 148 -4 9
|
||||
-19 -14 -41 -60z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.9 KiB |
17
src/assets/icons/workflow_scheduler.svg
Executable file
@ -0,0 +1,17 @@
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
<svg t="1712402256302" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1578">
|
||||
<path d="M640 885.589333a39.424 39.424 0 0 1-32.938667 46.634667A483.413333 483.413333 0 0 1 512 938.666667a295.68 295.68 0 0 1-92.117333-16.768 32.085333 32.085333 0 1 1 13.568-62.72 415.658667 415.658667 0 0 0 78.549333 15.36 295.722667 295.722667 0 0 0 75.434667-4.266667c20.181333-9.514667 47.317333-9.216 52.565333 15.36z m-397.824-307.968a160.597333 160.597333 0 0 1 156.842667 164.096 198.314667 198.314667 0 0 1-6.954667 48.426667 154.325333 154.325333 0 0 1-149.930667 115.712 164.266667 164.266667 0 0 1 0-328.192z m539.605333 0a164.266667 164.266667 0 1 1-156.842666 164.096 160.597333 160.597333 0 0 1 156.885333-164.096z m-30.122666-262.058666A344.917333 344.917333 0 0 1 853.333333 497.024c1.109333 16.768-1.749333 38.826667-30.08 41.258667a32.554667 32.554667 0 0 1-33.493333-26.325334 334.848 334.848 0 0 0-80.341333-146.304 34.517333 34.517333 0 0 1-4.992-54.613333 33.408 33.408 0 0 1 47.232 4.693333z m-417.706667-4.48c13.269333 16.64 4.821333 28.501333-8.789333 48.512A422.4 422.4 0 0 0 256 517.802667a33.152 33.152 0 0 1-36.821333 26.709333 31.573333 31.573333 0 0 1-27.52-32.512 89.6 89.6 0 0 1 3.797333-29.226667 402.773333 402.773333 0 0 1 93.312-177.536 30.592 30.592 0 0 1 45.184 5.845334zM512 85.333333a164.266667 164.266667 0 1 1-156.842667 164.096A160.597333 160.597333 0 0 1 512 85.333333z" p-id="1579"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
BIN
src/assets/img/technologies/ACTIVEMQ.png
Executable file → Normal file
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 8.5 KiB |
BIN
src/assets/img/technologies/NETTYHTTP.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
src/assets/img/technologies/SOLONMVC.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
src/assets/img/tools/BROWSER.png
Normal file
After Width: | Height: | Size: 314 B |
BIN
src/assets/img/tools/CILIUM_SERVICE.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
src/assets/img/tools/DATABASE.png
Normal file
After Width: | Height: | Size: 150 B |
BIN
src/assets/img/tools/ELASTICSEARCH.png
Normal file
After Width: | Height: | Size: 150 B |
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 259 B |
BIN
src/assets/img/tools/GENERAL.png
Normal file
After Width: | Height: | Size: 211 B |
BIN
src/assets/img/tools/K8S.png
Normal file
After Width: | Height: | Size: 471 B |
BIN
src/assets/img/tools/K8S_SERVICE.png
Normal file
After Width: | Height: | Size: 471 B |
BIN
src/assets/img/tools/MESH.png
Normal file
After Width: | Height: | Size: 262 B |
BIN
src/assets/img/tools/MESH_CP.png
Normal file
After Width: | Height: | Size: 262 B |
BIN
src/assets/img/tools/MESH_DP.png
Normal file
After Width: | Height: | Size: 262 B |
BIN
src/assets/img/tools/MONGODB.png
Normal file
After Width: | Height: | Size: 150 B |
BIN
src/assets/img/tools/MQ.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
src/assets/img/tools/NGINX.png
Normal file
After Width: | Height: | Size: 263 B |
BIN
src/assets/img/tools/OS_LINUX.png
Normal file
After Width: | Height: | Size: 241 B |
BIN
src/assets/img/tools/POSTGRESQL.png
Normal file
After Width: | Height: | Size: 150 B |
BIN
src/assets/img/tools/RABBITMQ.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
src/assets/img/tools/VIRTUAL_CACHE.png
Normal file
After Width: | Height: | Size: 211 B |
BIN
src/assets/img/tools/VIRTUAL_DATABASE.png
Normal file
After Width: | Height: | Size: 211 B |
BIN
src/assets/img/tools/VIRTUAL_GATEWAY.png
Normal file
After Width: | Height: | Size: 211 B |
@ -451,7 +451,7 @@ limitations under the License. -->
|
||||
}
|
||||
|
||||
.calendar + .calendar {
|
||||
border-left: solid 1px #eaeaea;
|
||||
border-left: solid 1px var(--sw-border-color-light);
|
||||
margin-left: 5px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
@ -464,7 +464,7 @@ limitations under the License. -->
|
||||
}
|
||||
|
||||
.calendar-head a {
|
||||
color: #666;
|
||||
color: var(--sw-topology-color);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
@ -568,7 +568,7 @@ limitations under the License. -->
|
||||
|
||||
.calendar-hour {
|
||||
display: inline-block;
|
||||
border: 1px solid #e6e5e5;
|
||||
border: 1px solid var(--sw-border-color-light);
|
||||
color: #9e9e9e;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
<template>
|
||||
<SelectorLegend
|
||||
:data="option.legend.data"
|
||||
:show="legendSelector.isSelector"
|
||||
:isConfigPage="legendSelector.isConfigPage"
|
||||
:colors="option.color"
|
||||
@change="changeLegend"
|
||||
/>
|
||||
<div class="chart" ref="chartRef" :style="`height:${height};width:${width};`">
|
||||
<div v-if="!available" class="no-data">No Data</div>
|
||||
<div
|
||||
@ -53,6 +60,8 @@ limitations under the License. -->
|
||||
import { addResizeListener, removeResizeListener } from "@/utils/event";
|
||||
import Trace from "@/views/dashboard/related/trace/Index.vue";
|
||||
import associateProcessor from "@/hooks/useAssociateProcessor";
|
||||
import { WidgetType } from "@/views/dashboard/data";
|
||||
import SelectorLegend from "./Legend.vue";
|
||||
|
||||
/*global Nullable, defineProps, defineEmits, Indexable*/
|
||||
const emits = defineEmits(["select"]);
|
||||
@ -63,7 +72,7 @@ limitations under the License. -->
|
||||
const currentParams = ref<Nullable<EventParams>>(null);
|
||||
const showTrace = ref<boolean>(false);
|
||||
const traceOptions = ref<{ type: string; filters?: unknown }>({
|
||||
type: "Trace",
|
||||
type: WidgetType.Trace,
|
||||
});
|
||||
const menuPos = reactive<{ x: number; y: number }>({ x: NaN, y: NaN });
|
||||
const props = defineProps({
|
||||
@ -83,6 +92,10 @@ limitations under the License. -->
|
||||
type: Array as PropType<{ widgetId: string }[]>,
|
||||
default: () => [],
|
||||
},
|
||||
legendSelector: {
|
||||
type: Object as PropType<Indexable>,
|
||||
default: () => ({ isConfigPage: false, isSelector: false }),
|
||||
},
|
||||
});
|
||||
const available = computed(
|
||||
() =>
|
||||
@ -102,6 +115,7 @@ limitations under the License. -->
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
instance.on("click", (params: EventParams) => {
|
||||
currentParams.value = params;
|
||||
if (props.option.series.type === "sankey") {
|
||||
@ -202,6 +216,23 @@ limitations under the License. -->
|
||||
});
|
||||
}
|
||||
|
||||
function changeLegend(names: string[]) {
|
||||
const instance = getInstance();
|
||||
for (const item of props.option.legend.data) {
|
||||
if (names.includes(item.name)) {
|
||||
instance.dispatchAction({
|
||||
type: "legendSelect",
|
||||
name: item.name,
|
||||
});
|
||||
} else {
|
||||
instance.dispatchAction({
|
||||
type: "legendUnSelect",
|
||||
name: item.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.option,
|
||||
(newVal, oldVal) => {
|
||||
@ -234,12 +265,10 @@ limitations under the License. -->
|
||||
.no-data {
|
||||
font-size: $font-size-smaller;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-pack: center;
|
||||
-webkit-box-align: center;
|
||||
color: #666;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
color: var(--text-color-placeholder);
|
||||
}
|
||||
|
||||
.chart {
|
||||
@ -252,11 +281,11 @@ limitations under the License. -->
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
z-index: 9999999;
|
||||
box-shadow: #ddd 1px 2px 10px;
|
||||
box-shadow: var(--sw-topology-box-shadow);
|
||||
transition: all cubic-bezier(0.075, 0.82, 0.165, 1) linear;
|
||||
background-color: rgb(255 255 255);
|
||||
background-color: var(--sw-bg-color-overlay);
|
||||
border-radius: 4px;
|
||||
color: rgb(51 51 51);
|
||||
color: $font-color;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
@ -267,7 +296,7 @@ limitations under the License. -->
|
||||
|
||||
&:hover {
|
||||
color: $active-color;
|
||||
background-color: #eee;
|
||||
background-color: $popper-hover-bg-color;
|
||||
}
|
||||
}
|
||||
</style>
|
74
src/components/Graph/Legend.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
<template>
|
||||
<Selector
|
||||
class="mb-10"
|
||||
multiple
|
||||
:value="legend"
|
||||
size="small"
|
||||
:options="Options"
|
||||
@change="changeLegend"
|
||||
filterable
|
||||
collapseTags
|
||||
collapseTagsTooltip
|
||||
v-if="show"
|
||||
/>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, watch } from "vue";
|
||||
import type { PropType } from "vue";
|
||||
import type { Option } from "@/types/app";
|
||||
import Selector from "./Selector.vue";
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array as PropType<{ name: string }[]>,
|
||||
default: () => [],
|
||||
},
|
||||
colors: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isConfigPage: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["change"]);
|
||||
const legend = ref<string[]>([]);
|
||||
const Options = computed(() =>
|
||||
props.data.map((d: { name: string }, index: number) => ({
|
||||
label: d.name,
|
||||
value: d.name,
|
||||
color: props.colors[index % props.colors.length],
|
||||
})),
|
||||
);
|
||||
|
||||
function changeLegend(opt: Option[]) {
|
||||
legend.value = opt.map((d: Option) => d.value);
|
||||
emits("change", legend.value);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
() => {
|
||||
legend.value = props.data.map((d) => d.name);
|
||||
},
|
||||
);
|
||||
</script>
|
107
src/components/Graph/Selector.vue
Normal file
@ -0,0 +1,107 @@
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. -->
|
||||
<template>
|
||||
<el-select
|
||||
:size="size"
|
||||
v-model="selected"
|
||||
:placeholder="placeholder"
|
||||
@change="changeSelected"
|
||||
:multiple="multiple"
|
||||
:disabled="disabled"
|
||||
:style="{ borderRadius }"
|
||||
:clearable="clearable"
|
||||
:remote="isRemote"
|
||||
:reserve-keyword="isRemote"
|
||||
:remote-method="remoteMethod"
|
||||
:filterable="filterable"
|
||||
:collapse-tags="collapseTags"
|
||||
:collapse-tags-tooltip="collapseTagsTooltip"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, index) in options"
|
||||
:key="`${item.value}${index}`"
|
||||
:label="item.label || ''"
|
||||
:value="item.value || ''"
|
||||
:disabled="item.disabled || false"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<el-tag :color="item.color" class="mr-5" size="small" />
|
||||
<span :style="{ color: item.color }">{{ item.label }}</span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from "vue";
|
||||
import type { PropType } from "vue";
|
||||
|
||||
/*global defineProps, defineEmits, Indexable*/
|
||||
const emit = defineEmits(["change", "query"]);
|
||||
const props = defineProps({
|
||||
options: {
|
||||
type: Array as PropType<
|
||||
({
|
||||
label: string | number;
|
||||
value: string | number;
|
||||
color: string;
|
||||
} & { disabled?: boolean })[]
|
||||
>,
|
||||
default: () => [],
|
||||
},
|
||||
value: {
|
||||
type: [Array, String, Number, undefined] as PropType<any>,
|
||||
default: () => [],
|
||||
},
|
||||
size: { type: null, default: "default" },
|
||||
placeholder: {
|
||||
type: [String, undefined] as PropType<string>,
|
||||
default: "Select a option",
|
||||
},
|
||||
borderRadius: { type: Number, default: 3 },
|
||||
multiple: { type: Boolean, default: false },
|
||||
disabled: { type: Boolean, default: false },
|
||||
clearable: { type: Boolean, default: false },
|
||||
isRemote: { type: Boolean, default: false },
|
||||
filterable: { type: Boolean, default: true },
|
||||
collapseTags: { type: Boolean, default: false },
|
||||
collapseTagsTooltip: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
const selected = ref<string[] | string>(props.value);
|
||||
function changeSelected() {
|
||||
const options = props.options.filter((d: Indexable) =>
|
||||
props.multiple ? selected.value.includes(d.value) : selected.value === d.value,
|
||||
);
|
||||
emit("change", options);
|
||||
}
|
||||
|
||||
function remoteMethod(query: string) {
|
||||
if (props.isRemote) {
|
||||
emit("query", query);
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(data) => {
|
||||
selected.value = data;
|
||||
},
|
||||
);
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-input__inner {
|
||||
border-radius: unset !important;
|
||||
}
|
||||
</style>
|
@ -85,10 +85,10 @@ limitations under the License. -->
|
||||
.bar-select {
|
||||
position: relative;
|
||||
justify-content: space-between;
|
||||
border: 1px solid #ddd;
|
||||
border: 1px solid var(--el-border-color);
|
||||
background: $theme-background;
|
||||
border-radius: 3px;
|
||||
color: #000;
|
||||
color: $font-color;
|
||||
font-size: $font-size-smaller;
|
||||
height: 24px;
|
||||
|
||||
@ -97,8 +97,8 @@ limitations under the License. -->
|
||||
border-radius: 3px;
|
||||
margin: 3px;
|
||||
color: $active-color;
|
||||
background-color: #fafafa;
|
||||
border: 1px solid #e8e8e8;
|
||||
background-color: var(--theme-background);
|
||||
border: 1px solid var(--el-color-primary);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
@ -112,7 +112,7 @@ limitations under the License. -->
|
||||
width: 100%;
|
||||
padding: 2px 10px;
|
||||
overflow: auto;
|
||||
color: #606266;
|
||||
color: var(--sw-setting-color);
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
@ -133,13 +133,13 @@ limitations under the License. -->
|
||||
}
|
||||
|
||||
.opt-wrapper {
|
||||
color: #606266;
|
||||
color: var(--sw-setting-color);
|
||||
position: absolute;
|
||||
top: 26px;
|
||||
left: 0;
|
||||
background-color: $theme-background;
|
||||
box-shadow: 0 1px 6px rgb(99 99 99 / 20%);
|
||||
border: 1px solid #ddd;
|
||||
border: 1px solid var(--el-border-color);
|
||||
width: 100%;
|
||||
border-radius: 0 0 3px 3px;
|
||||
border-right-width: 1px !important;
|
||||
@ -169,7 +169,7 @@ limitations under the License. -->
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #f5f5f5;
|
||||
background-color: var(--layout-background);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -26,10 +26,12 @@ limitations under the License. -->
|
||||
:reserve-keyword="isRemote"
|
||||
:remote-method="remoteMethod"
|
||||
:filterable="filterable"
|
||||
:collapse-tags="collapseTags"
|
||||
:collapse-tags-tooltip="collapseTagsTooltip"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value || ''"
|
||||
v-for="(item, index) in options"
|
||||
:key="`${item.value}${index}`"
|
||||
:label="item.label || ''"
|
||||
:value="item.value || ''"
|
||||
:disabled="item.disabled || false"
|
||||
@ -41,11 +43,6 @@ limitations under the License. -->
|
||||
import { ref, watch } from "vue";
|
||||
import type { PropType } from "vue";
|
||||
|
||||
// interface Option {
|
||||
// label: string | number;
|
||||
// value: string | number;
|
||||
// }
|
||||
|
||||
/*global defineProps, defineEmits, Indexable*/
|
||||
const emit = defineEmits(["change", "query"]);
|
||||
const props = defineProps({
|
||||
@ -73,6 +70,8 @@ limitations under the License. -->
|
||||
clearable: { type: Boolean, default: false },
|
||||
isRemote: { type: Boolean, default: false },
|
||||
filterable: { type: Boolean, default: true },
|
||||
collapseTags: { type: Boolean, default: false },
|
||||
collapseTagsTooltip: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
const selected = ref<string[] | string>(props.value);
|
||||
|
@ -31,7 +31,7 @@ limitations under the License. -->
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, ref } from "vue";
|
||||
import { nextTick, ref, watch } from "vue";
|
||||
import type { PropType } from "vue";
|
||||
import { ElInput } from "element-plus";
|
||||
|
||||
@ -69,10 +69,17 @@ limitations under the License. -->
|
||||
inputValue.value = "";
|
||||
emits("change", dynamicTags.value);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.tags,
|
||||
() => {
|
||||
dynamicTags.value = props.tags || [];
|
||||
},
|
||||
);
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.input-name {
|
||||
width: 300px;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.vertical {
|
||||
|
@ -447,7 +447,7 @@ limitations under the License. -->
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
padding: 5px;
|
||||
border-right: solid 1px #eaeaea;
|
||||
border-right: solid 1px var(--sw-border-color-light);
|
||||
}
|
||||
|
||||
&__shortcut {
|
||||
@ -457,7 +457,7 @@ limitations under the License. -->
|
||||
background-color: transparent;
|
||||
line-height: 34px;
|
||||
font-size: $font-size-smaller;
|
||||
color: #666;
|
||||
color: var(--sw-topology-color);
|
||||
text-align: left;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
@ -532,6 +532,6 @@ limitations under the License. -->
|
||||
}
|
||||
|
||||
.datepicker__buttons .datepicker__button-cancel {
|
||||
background: #666;
|
||||
background: var(--sw-topology-color);
|
||||
}
|
||||
</style>
|
||||
|
@ -18,7 +18,7 @@ import type { App } from "vue";
|
||||
import Icon from "./Icon.vue";
|
||||
import TimePicker from "./TimePicker.vue";
|
||||
import Selector from "./Selector.vue";
|
||||
import Graph from "./Graph.vue";
|
||||
import Graph from "./Graph/Graph.vue";
|
||||
import Radio from "./Radio.vue";
|
||||
import SelectSingle from "./SelectSingle.vue";
|
||||
import Tags from "./Tags.vue";
|
||||
|
@ -26,3 +26,8 @@ export const Languages = [
|
||||
{ label: "Chinese", value: "zh" },
|
||||
{ label: "Spanish", value: "es" },
|
||||
];
|
||||
|
||||
export enum Themes {
|
||||
Dark = "dark",
|
||||
Light = "light",
|
||||
}
|
||||
|
75
src/graphql/base.ts
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Licensed to Apache Software Foundation (ASF) under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Apache Software Foundation (ASF) licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
const Timeout = 2 * 60 * 1000;
|
||||
export let globalAbortController = new AbortController();
|
||||
export function abortRequestsAndUpdate() {
|
||||
globalAbortController.abort(`Request timeout ${Timeout}ms`);
|
||||
globalAbortController = new AbortController();
|
||||
}
|
||||
class HTTPError extends Error {
|
||||
response;
|
||||
|
||||
constructor(response: Response, detailText = "") {
|
||||
super(detailText || response.statusText);
|
||||
|
||||
this.name = "HTTPError";
|
||||
this.response = response;
|
||||
}
|
||||
}
|
||||
|
||||
const BasePath = `/graphql`;
|
||||
|
||||
export async function httpQuery({
|
||||
path = "",
|
||||
method = "GET",
|
||||
json,
|
||||
headers = {},
|
||||
}: {
|
||||
path?: string;
|
||||
method: string;
|
||||
json: unknown;
|
||||
headers: Recordable;
|
||||
}) {
|
||||
const timeoutId = setTimeout(() => {
|
||||
abortRequestsAndUpdate();
|
||||
}, Timeout);
|
||||
const url = `${BasePath}${path}`;
|
||||
const response: Response = await fetch(url, {
|
||||
method,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
accept: "application/json",
|
||||
...headers,
|
||||
},
|
||||
body: JSON.stringify(json),
|
||||
signal: globalAbortController.signal,
|
||||
})
|
||||
.catch((error) => {
|
||||
throw new HTTPError(error);
|
||||
})
|
||||
.finally(() => {
|
||||
clearTimeout(timeoutId);
|
||||
});
|
||||
if (response.ok) {
|
||||
return response.json();
|
||||
} else {
|
||||
console.error(new HTTPError(response));
|
||||
}
|
||||
}
|
@ -14,20 +14,18 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import type { AxiosResponse } from "axios";
|
||||
import axios from "axios";
|
||||
import { cancelToken } from "@/utils/cancelToken";
|
||||
import { httpQuery } from "./base";
|
||||
|
||||
async function query(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
|
||||
const res: AxiosResponse = await axios.post(
|
||||
"/graphql",
|
||||
{ query: param.queryStr, variables: { ...param.conditions } },
|
||||
{ cancelToken: cancelToken() },
|
||||
);
|
||||
if (res.data.errors) {
|
||||
res.data.errors = res.data.errors.map((e: { message: string }) => e.message).join(" ");
|
||||
async function fetchQuery(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
|
||||
const response = await httpQuery({
|
||||
method: "post",
|
||||
json: { query: param.queryStr, variables: { ...param.conditions } },
|
||||
headers: {},
|
||||
});
|
||||
if (response.errors) {
|
||||
response.errors = response.errors.map((e: { message: string }) => e.message).join(" ");
|
||||
}
|
||||
return res;
|
||||
return response;
|
||||
}
|
||||
|
||||
export default query;
|
||||
export default fetchQuery;
|
||||
|
@ -24,6 +24,7 @@ export const Alarm = {
|
||||
message
|
||||
startTime
|
||||
scope
|
||||
name
|
||||
tags {
|
||||
key
|
||||
value
|
||||
@ -43,6 +44,46 @@ export const Alarm = {
|
||||
startTime
|
||||
endTime
|
||||
}
|
||||
snapshot {
|
||||
expression
|
||||
metrics {
|
||||
name
|
||||
results {
|
||||
metric {
|
||||
labels {
|
||||
key
|
||||
value
|
||||
}
|
||||
}
|
||||
values {
|
||||
id
|
||||
owner {
|
||||
scope
|
||||
serviceID
|
||||
serviceName
|
||||
normal
|
||||
serviceInstanceID
|
||||
serviceInstanceName
|
||||
endpointID
|
||||
endpointName
|
||||
}
|
||||
value
|
||||
traceID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
};
|
||||
export const AlarmTagKeys = {
|
||||
variable: "$duration: Duration!",
|
||||
query: `
|
||||
tagKeys: queryAlarmTagAutocompleteKeys(duration: $duration)`,
|
||||
};
|
||||
|
||||
export const AlarmTagValues = {
|
||||
variable: "$tagKey: String!, $duration: Duration!",
|
||||
query: `
|
||||
tagValues: queryAlarmTagAutocompleteValues(tagKey: $tagKey, duration: $duration)`,
|
||||
};
|
||||
|
80
src/graphql/fragments/async-profile.ts
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export const GetAsyncTaskList = {
|
||||
variable: "$request: AsyncProfilerTaskListRequest!",
|
||||
query: `
|
||||
asyncTaskList: queryAsyncProfilerTaskList(request: $request) {
|
||||
errorReason
|
||||
tasks {
|
||||
id
|
||||
serviceId
|
||||
serviceInstanceIds
|
||||
createTime
|
||||
events
|
||||
duration
|
||||
execArgs
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
||||
export const GetAsyncProfileTaskProcess = {
|
||||
variable: "$taskId: String!",
|
||||
query: `
|
||||
taskProgress: queryAsyncProfilerTaskProgress(taskId: $taskId) {
|
||||
logs {
|
||||
id
|
||||
instanceId
|
||||
instanceName
|
||||
operationType
|
||||
operationTime
|
||||
}
|
||||
errorInstanceIds
|
||||
successInstanceIds
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
||||
export const CreateAsyncProfileTask = {
|
||||
variable: "$asyncProfilerTaskCreationRequest: AsyncProfilerTaskCreationRequest!",
|
||||
query: `
|
||||
task: createAsyncProfilerTask(asyncProfilerTaskCreationRequest: $asyncProfilerTaskCreationRequest) {
|
||||
id
|
||||
errorReason
|
||||
code
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
||||
export const GetAsyncProfileAnalyze = {
|
||||
variable: "$request: AsyncProfilerAnalyzationRequest!",
|
||||
query: `
|
||||
analysisResult: queryAsyncProfilerAnalyze(request: $request) {
|
||||
tree {
|
||||
type
|
||||
elements {
|
||||
id
|
||||
parentId
|
||||
symbol: codeSignature
|
||||
dumpCount: total
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
@ -14,22 +14,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export const TypeOfMetrics = {
|
||||
variable: "$name: String!",
|
||||
query: `typeOfMetrics(name: $name)`,
|
||||
};
|
||||
|
||||
export const listMetrics = {
|
||||
variable: "$regex: String",
|
||||
query: `
|
||||
metrics: listMetrics(regex: $regex) {
|
||||
value: name
|
||||
label: name
|
||||
type
|
||||
catalog
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
||||
export const getAllTemplates = {
|
||||
query: `
|
||||
|
@ -24,6 +24,7 @@ export const Services = {
|
||||
group
|
||||
layers
|
||||
normal
|
||||
shortName
|
||||
}
|
||||
`,
|
||||
};
|
||||
@ -72,9 +73,9 @@ export const Processes = {
|
||||
};
|
||||
|
||||
export const Endpoints = {
|
||||
variable: "$serviceId: ID!, $keyword: String!",
|
||||
variable: "$serviceId: ID!, $keyword: String!, $duration: Duration, $limit: Int!",
|
||||
query: `
|
||||
pods: findEndpoint(serviceId: $serviceId, keyword: $keyword, limit: 20) {
|
||||
pods: findEndpoint(serviceId: $serviceId, keyword: $keyword, limit: $limit, duration: $duration) {
|
||||
id
|
||||
value: name
|
||||
label: name
|
||||
|
@ -23,6 +23,7 @@ export const ServicesTopology = {
|
||||
name
|
||||
type
|
||||
isReal
|
||||
layers
|
||||
}
|
||||
calls {
|
||||
id
|
||||
@ -99,3 +100,56 @@ export const ProcessTopology = {
|
||||
}
|
||||
`,
|
||||
};
|
||||
export const HierarchyServiceTopology = {
|
||||
variable: "$serviceId: ID!, $layer: String!",
|
||||
query: `
|
||||
hierarchyServiceTopology: getServiceHierarchy(serviceId: $serviceId, layer: $layer) {
|
||||
relations {
|
||||
upperService {
|
||||
id
|
||||
name
|
||||
layer
|
||||
normal
|
||||
}
|
||||
lowerService {
|
||||
id
|
||||
name
|
||||
layer
|
||||
normal
|
||||
}
|
||||
}
|
||||
}`,
|
||||
};
|
||||
export const HierarchyInstanceTopology = {
|
||||
variable: "$instanceId: ID!, $layer: String!",
|
||||
query: `
|
||||
hierarchyInstanceTopology: getInstanceHierarchy(instanceId: $instanceId, layer: $layer) {
|
||||
relations {
|
||||
upperInstance {
|
||||
id
|
||||
name
|
||||
layer
|
||||
normal
|
||||
serviceName
|
||||
serviceId
|
||||
}
|
||||
lowerInstance {
|
||||
id
|
||||
name
|
||||
layer
|
||||
normal
|
||||
serviceName
|
||||
serviceId
|
||||
}
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const ListLayerLevels = {
|
||||
query: `
|
||||
levels: listLayerLevels {
|
||||
layer
|
||||
level
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
@ -14,9 +14,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import type { AxiosPromise, AxiosResponse } from "axios";
|
||||
import axios from "axios";
|
||||
import { cancelToken } from "@/utils/cancelToken";
|
||||
import { httpQuery } from "./base";
|
||||
import * as app from "./query/app";
|
||||
import * as selector from "./query/selector";
|
||||
import * as dashboard from "./query/dashboard";
|
||||
@ -28,6 +26,7 @@ import * as alarm from "./query/alarm";
|
||||
import * as event from "./query/event";
|
||||
import * as ebpf from "./query/ebpf";
|
||||
import * as demandLog from "./query/demand-log";
|
||||
import * as asyncProfile from "./query/async-profile";
|
||||
|
||||
const query: { [key: string]: string } = {
|
||||
...app,
|
||||
@ -41,32 +40,27 @@ const query: { [key: string]: string } = {
|
||||
...event,
|
||||
...ebpf,
|
||||
...demandLog,
|
||||
...asyncProfile,
|
||||
};
|
||||
class Graphql {
|
||||
private queryData = "";
|
||||
public query(queryData: string) {
|
||||
this.queryData = queryData;
|
||||
queryData = "";
|
||||
query(data: string) {
|
||||
this.queryData = data;
|
||||
return this;
|
||||
}
|
||||
public params(variablesData: unknown): AxiosPromise<void> {
|
||||
return axios
|
||||
.post(
|
||||
"/graphql",
|
||||
{
|
||||
async params(variables: unknown) {
|
||||
const response = await httpQuery({
|
||||
method: "post",
|
||||
headers: {},
|
||||
json: {
|
||||
query: query[this.queryData],
|
||||
variables: variablesData,
|
||||
variables,
|
||||
},
|
||||
{ cancelToken: cancelToken() },
|
||||
)
|
||||
.then((res: AxiosResponse) => {
|
||||
if (res.data.errors) {
|
||||
res.data.errors = res.data.errors.map((e: { message: string }) => e.message).join(" ");
|
||||
}
|
||||
return res;
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
throw err;
|
||||
});
|
||||
if (response.errors) {
|
||||
response.errors = response.errors.map((e: { message: string }) => e.message).join(" ");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Alarm } from "../fragments/alarm";
|
||||
import { Alarm, AlarmTagKeys, AlarmTagValues } from "../fragments/alarm";
|
||||
|
||||
export const queryAlarms = `query queryAlarms(${Alarm.variable}) {${Alarm.query}}`;
|
||||
export const queryAlarmTagValues = `query queryTagValues(${AlarmTagValues.variable}) {${AlarmTagValues.query}}`;
|
||||
export const queryAlarmTagKeys = `query queryTagKeys(${AlarmTagKeys.variable}) {${AlarmTagKeys.query}}`;
|
||||
|
31
src/graphql/query/async-profile.ts
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
GetAsyncTaskList,
|
||||
GetAsyncProfileTaskProcess,
|
||||
CreateAsyncProfileTask,
|
||||
GetAsyncProfileAnalyze,
|
||||
} from "../fragments/async-profile";
|
||||
|
||||
export const getAsyncTaskList = `query getAsyncTaskList(${GetAsyncTaskList.variable}) {${GetAsyncTaskList.query}}`;
|
||||
|
||||
export const getAsyncProfileTaskProcess = `query getAsyncProfileTaskProcess(${GetAsyncProfileTaskProcess.variable}) {${GetAsyncProfileTaskProcess.query}}`;
|
||||
|
||||
export const saveAsyncProfileTask = `mutation createAsyncProfileTask(${CreateAsyncProfileTask.variable}) {${CreateAsyncProfileTask.query}}`;
|
||||
|
||||
export const getAsyncProfileAnalyze = `query getAsyncProfileAnalyze(${GetAsyncProfileAnalyze.variable}) {${GetAsyncProfileAnalyze.query}}`;
|
@ -14,18 +14,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
TypeOfMetrics,
|
||||
listMetrics,
|
||||
getAllTemplates,
|
||||
addTemplate,
|
||||
changeTemplate,
|
||||
deleteTemplate,
|
||||
} from "../fragments/dashboard";
|
||||
|
||||
export const queryTypeOfMetrics = `query typeOfMetrics(${TypeOfMetrics.variable}) {${TypeOfMetrics.query}}`;
|
||||
|
||||
export const queryMetrics = `query queryData(${listMetrics.variable}) {${listMetrics.query}}`;
|
||||
import { getAllTemplates, addTemplate, changeTemplate, deleteTemplate } from "../fragments/dashboard";
|
||||
|
||||
export const addNewTemplate = `mutation template(${addTemplate.variable}) {${addTemplate.query}}`;
|
||||
|
||||
|
@ -14,9 +14,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { InstanceTopology, EndpointTopology, ServicesTopology, ProcessTopology } from "../fragments/topology";
|
||||
import {
|
||||
InstanceTopology,
|
||||
EndpointTopology,
|
||||
ServicesTopology,
|
||||
ProcessTopology,
|
||||
HierarchyServiceTopology,
|
||||
HierarchyInstanceTopology,
|
||||
ListLayerLevels,
|
||||
} from "../fragments/topology";
|
||||
|
||||
export const getInstanceTopology = `query queryData(${InstanceTopology.variable}) {${InstanceTopology.query}}`;
|
||||
export const getEndpointTopology = `query queryData(${EndpointTopology.variable}) {${EndpointTopology.query}}`;
|
||||
export const getServicesTopology = `query queryData(${ServicesTopology.variable}) {${ServicesTopology.query}}`;
|
||||
export const getProcessTopology = `query queryData(${ProcessTopology.variable}) {${ProcessTopology.query}}`;
|
||||
export const getHierarchyInstanceTopology = `query queryData(${HierarchyInstanceTopology.variable}) {${HierarchyInstanceTopology.query}}`;
|
||||
export const getHierarchyServiceTopology = `query queryData(${HierarchyServiceTopology.variable}) {${HierarchyServiceTopology.query}}`;
|
||||
export const queryListLayerLevels = `query queryLayerLevels {${ListLayerLevels.query}}`;
|
||||
|
@ -14,32 +14,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export enum MetricQueryTypes {
|
||||
ReadMetricsValue = "readMetricsValue",
|
||||
ReadMetricsValues = "readMetricsValues",
|
||||
SortMetrics = "sortMetrics",
|
||||
ReadLabeledMetricsValues = "readLabeledMetricsValues",
|
||||
READHEATMAP = "readHeatMap",
|
||||
ReadSampledRecords = "readSampledRecords",
|
||||
ReadRecords = "readRecords",
|
||||
ReadNullableMetricsValue = "readNullableMetricsValue",
|
||||
}
|
||||
export const MaximumEntities = 20;
|
||||
|
||||
export enum Calculations {
|
||||
Percentage = "percentage",
|
||||
ByteToKB = "byteToKB",
|
||||
ByteToMB = "byteToMB",
|
||||
ByteToGB = "byteToGB",
|
||||
Apdex = "apdex",
|
||||
ConvertSeconds = "convertSeconds",
|
||||
ConvertMilliseconds = "convertMilliseconds",
|
||||
MsToS = "msTos",
|
||||
Average = "average",
|
||||
PercentageAvg = "percentageAvg",
|
||||
ApdexAvg = "apdexAvg",
|
||||
SecondToDay = "secondToDay",
|
||||
NanosecondToMillisecond = "nanosecondToMillisecond",
|
||||
}
|
||||
export enum sizeEnum {
|
||||
XS = "XS",
|
||||
SM = "SM",
|
||||
@ -68,50 +44,6 @@ screenMap.set(sizeEnum.XL, screenEnum.XL);
|
||||
screenMap.set(sizeEnum.XXL, screenEnum.XXL);
|
||||
|
||||
export const RespFields: Indexable = {
|
||||
readMetricsValues: `{
|
||||
label
|
||||
values {
|
||||
values {value isEmptyValue}
|
||||
}
|
||||
}`,
|
||||
readMetricsValue: ``,
|
||||
readNullableMetricsValue: `{
|
||||
value
|
||||
isEmptyValue
|
||||
}`,
|
||||
sortMetrics: `{
|
||||
name
|
||||
id
|
||||
value
|
||||
refId
|
||||
}`,
|
||||
readLabeledMetricsValues: `{
|
||||
label
|
||||
values {
|
||||
values {value isEmptyValue}
|
||||
}
|
||||
}`,
|
||||
readHeatMap: `{
|
||||
values {
|
||||
id
|
||||
values
|
||||
}
|
||||
buckets {
|
||||
min
|
||||
max
|
||||
}
|
||||
}`,
|
||||
readSampledRecords: `{
|
||||
name
|
||||
value
|
||||
refId
|
||||
}`,
|
||||
readRecords: `{
|
||||
id
|
||||
name
|
||||
value
|
||||
refId
|
||||
}`,
|
||||
execExpression: `{
|
||||
type
|
||||
results {
|
||||
@ -125,8 +57,60 @@ export const RespFields: Indexable = {
|
||||
name: id
|
||||
value
|
||||
refId: traceID
|
||||
owner {
|
||||
scope
|
||||
serviceID
|
||||
serviceName
|
||||
normal
|
||||
serviceInstanceID
|
||||
serviceInstanceName
|
||||
endpointID
|
||||
endpointName
|
||||
}
|
||||
}
|
||||
}
|
||||
error
|
||||
}`,
|
||||
};
|
||||
|
||||
export const DarkChartColors = [
|
||||
"#79bbff",
|
||||
"#a0a7e6",
|
||||
"#30A4EB",
|
||||
"#45BFC0",
|
||||
"#ebbf93",
|
||||
"#884dde",
|
||||
"#1bbf93",
|
||||
"#7289ab",
|
||||
"#f56c6c",
|
||||
"#81feb7",
|
||||
"#4094fa",
|
||||
"#ff894d",
|
||||
"#884dde",
|
||||
"#ebbf93",
|
||||
"#fedc6d",
|
||||
"#da7cfa",
|
||||
"#b88230",
|
||||
"#a0cfff",
|
||||
];
|
||||
|
||||
export const LightChartColors = [
|
||||
"#3f96e3",
|
||||
"#a0a7e6",
|
||||
"#45BFC0",
|
||||
"#FFCC55",
|
||||
"#FF6A84",
|
||||
"#c23531",
|
||||
"#2f4554",
|
||||
"#61a0a8",
|
||||
"#d48265",
|
||||
"#91c7ae",
|
||||
"#749f83",
|
||||
"#ca8622",
|
||||
"#bda29a",
|
||||
"#6e7074",
|
||||
"#546570",
|
||||
"#c4ccd3",
|
||||
];
|
||||
|
||||
export const MaxQueryLength = 120;
|
||||
|
@ -47,11 +47,11 @@ export function createBreakpointListen(fn?: (opt: CreateCallbackParams) => void)
|
||||
|
||||
function getWindowWidth() {
|
||||
const width = document.body.clientWidth;
|
||||
const xs = screenMap.get(sizeEnum.XS) || "";
|
||||
const sm = screenMap.get(sizeEnum.SM) || "";
|
||||
const md = screenMap.get(sizeEnum.MD) || "";
|
||||
const lg = screenMap.get(sizeEnum.LG) || "";
|
||||
const xl = screenMap.get(sizeEnum.XL) || "";
|
||||
const xs = screenMap.get(sizeEnum.XS) || 0;
|
||||
const sm = screenMap.get(sizeEnum.SM) || 0;
|
||||
const md = screenMap.get(sizeEnum.MD) || 0;
|
||||
const lg = screenMap.get(sizeEnum.LG) || 0;
|
||||
const xl = screenMap.get(sizeEnum.XL) || 0;
|
||||
if (width < xs) {
|
||||
screenRef.value = sizeEnum.XS;
|
||||
} else if (width < sm) {
|
||||
|
@ -17,15 +17,25 @@
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import type { LayoutConfig } from "@/types/dashboard";
|
||||
import { ConfigFieldTypes } from "@/views/dashboard/data";
|
||||
|
||||
export default function getDashboard(param?: { name: string; layer: string; entity: string }) {
|
||||
export default function getDashboard(param?: { name?: string; layer: string; entity: string }, t?: string) {
|
||||
const type = t || ConfigFieldTypes.NAME; // "NAME" or "ISDEFAULT"
|
||||
const dashboardStore = useDashboardStore();
|
||||
const opt = param || dashboardStore.currentDashboard;
|
||||
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
|
||||
const dashboard = list.find(
|
||||
let dashboard: Recordable;
|
||||
if (type === ConfigFieldTypes.NAME) {
|
||||
dashboard = list.find(
|
||||
(d: { name: string; layer: string; entity: string }) =>
|
||||
d.name === opt.name && d.entity === opt.entity && d.layer === opt.layer,
|
||||
);
|
||||
} else {
|
||||
dashboard = list.find(
|
||||
(d: { name: string; layer: string; entity: string; isDefault: boolean }) =>
|
||||
d.isDefault && d.entity === opt.entity && d.layer === opt.layer,
|
||||
);
|
||||
}
|
||||
const all = dashboardStore.layout;
|
||||
const widgets: LayoutConfig[] = [];
|
||||
for (const item of all) {
|
||||
@ -52,6 +62,9 @@ export default function getDashboard(param?: { name: string; layer: string; enti
|
||||
filters,
|
||||
};
|
||||
dashboardStore.setWidget(item);
|
||||
if (widget.id === sourceId) {
|
||||
return;
|
||||
}
|
||||
const targetTabIndex = (widget.id || "").split("-");
|
||||
const sourceTabindex = (sourceId || "").split("-") || [];
|
||||
let container: Nullable<Element>;
|
||||
|
@ -30,6 +30,8 @@ import { useDebounceFn } from "@vueuse/core";
|
||||
import { useEventListener } from "./useEventListener";
|
||||
import { useBreakpoint } from "./useBreakpoint";
|
||||
import echarts from "@/utils/echarts";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { Themes } from "@/constants/data";
|
||||
|
||||
export type ECOption = echarts.ComposeOption<
|
||||
| BarSeriesOption
|
||||
@ -44,8 +46,9 @@ export type ECOption = echarts.ComposeOption<
|
||||
>;
|
||||
|
||||
export function useECharts(elRef: Ref<HTMLDivElement>, theme: "light" | "dark" | "default" = "default"): Indexable {
|
||||
const appStore = useAppStoreWithOut();
|
||||
const getDarkMode = computed(() => {
|
||||
return theme === "default" ? "light" : theme;
|
||||
return appStore.theme === "default" ? Themes.Light : theme;
|
||||
});
|
||||
let chartInstance: Nullable<echarts.ECharts> = null;
|
||||
let resizeFn: Fn = resize;
|
||||
@ -55,7 +58,7 @@ export function useECharts(elRef: Ref<HTMLDivElement>, theme: "light" | "dark" |
|
||||
resizeFn = useDebounceFn(resize, 200);
|
||||
|
||||
const getOptions = computed(() => {
|
||||
if (getDarkMode.value !== "dark") {
|
||||
if (getDarkMode.value !== Themes.Dark) {
|
||||
return cacheOptions.value as ECOption;
|
||||
}
|
||||
return {
|
||||
|
@ -14,9 +14,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { RespFields } from "./data";
|
||||
import { RespFields, MaximumEntities, MaxQueryLength } from "./data";
|
||||
import { EntityType, ExpressionResultType } from "@/views/dashboard/data";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useTopologyStore } from "@/store/modules/topology";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
@ -24,31 +25,35 @@ import type { MetricConfigOpt } from "@/types/dashboard";
|
||||
import type { Instance, Endpoint, Service } from "@/types/selector";
|
||||
import type { Node, Call } from "@/types/topology";
|
||||
|
||||
export async function useExpressionsQueryProcessor(config: Indexable) {
|
||||
function expressionsGraphqlPods() {
|
||||
function chunkArray(array: any[], chunkSize: number) {
|
||||
const result = [];
|
||||
for (let i = 0; i < array.length; i += chunkSize) {
|
||||
result.push(array.slice(i, i + chunkSize));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function useDashboardQueryProcessor(configList: Indexable[]) {
|
||||
function expressionsGraphql(config: Indexable, idx: number) {
|
||||
if (!(config.metrics && config.metrics[0])) {
|
||||
return;
|
||||
}
|
||||
const appStore = useAppStoreWithOut();
|
||||
const dashboardStore = useDashboardStore();
|
||||
const selectorStore = useSelectorStore();
|
||||
|
||||
if (!selectorStore.currentService && dashboardStore.entity !== "All") {
|
||||
return;
|
||||
}
|
||||
const conditions: Recordable = {
|
||||
duration: appStore.durationTime,
|
||||
};
|
||||
const variables: string[] = [`$duration: Duration!`];
|
||||
const conditions: Recordable = {};
|
||||
const variables: string[] = [];
|
||||
const isRelation = ["ServiceRelation", "ServiceInstanceRelation", "EndpointRelation", "ProcessRelation"].includes(
|
||||
dashboardStore.entity,
|
||||
);
|
||||
if (isRelation && !selectorStore.currentDestService) {
|
||||
return;
|
||||
}
|
||||
const fragment = config.metrics.map((name: string, index: number) => {
|
||||
variables.push(`$expression${index}: String!`, `$entity${index}: Entity!`);
|
||||
conditions[`expression${index}`] = name;
|
||||
if (idx === 0) {
|
||||
variables.push(`$entity: Entity!`);
|
||||
const entity = {
|
||||
serviceName: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.value,
|
||||
normal: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.normal,
|
||||
@ -76,19 +81,21 @@ export async function useExpressionsQueryProcessor(config: Indexable) {
|
||||
? selectorStore.currentDestProcess && selectorStore.currentDestProcess.value
|
||||
: undefined,
|
||||
};
|
||||
conditions[`entity${index}`] = entity;
|
||||
conditions[`entity`] = entity;
|
||||
}
|
||||
const fragment = config.metrics.map((name: string, index: number) => {
|
||||
variables.push(`$expression${idx}${index}: String!`);
|
||||
conditions[`expression${idx}${index}`] = name;
|
||||
|
||||
return `expression${index}: execExpression(expression: $expression${index}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`;
|
||||
return `expression${idx}${index}: execExpression(expression: $expression${idx}${index}, entity: $entity, duration: $duration)${RespFields.execExpression}`;
|
||||
});
|
||||
const queryStr = `query queryData(${variables}) {${fragment}}`;
|
||||
|
||||
return {
|
||||
queryStr,
|
||||
variables,
|
||||
fragment,
|
||||
conditions,
|
||||
};
|
||||
}
|
||||
|
||||
function expressionsSource(resp: { errors: string; data: Indexable }) {
|
||||
function expressionsSource(config: Indexable, resp: { errors: string; data: Indexable | any }) {
|
||||
if (resp.errors) {
|
||||
ElMessage.error(resp.errors);
|
||||
return { source: {}, tips: [], typesOfMQE: [] };
|
||||
@ -97,13 +104,17 @@ export async function useExpressionsQueryProcessor(config: Indexable) {
|
||||
ElMessage.error("The query is wrong");
|
||||
return { source: {}, tips: [], typesOfMQE: [] };
|
||||
}
|
||||
if (resp.data.error) {
|
||||
ElMessage.error(resp.data.error);
|
||||
return { source: {}, tips: [], typesOfMQE: [] };
|
||||
}
|
||||
const tips: string[] = [];
|
||||
const source: { [key: string]: unknown } = {};
|
||||
const source: Indexable<unknown> = {};
|
||||
const keys = Object.keys(resp.data);
|
||||
const typesOfMQE: string[] = [];
|
||||
|
||||
for (let i = 0; i < config.metrics.length; i++) {
|
||||
const c: MetricConfigOpt = (config.metricConfig && config.metricConfig[i]) || {};
|
||||
const metricConfig: MetricConfigOpt = (config.metricConfig && config.metricConfig[i]) || {};
|
||||
const obj = resp.data[keys[i]] || {};
|
||||
const results = obj.results || [];
|
||||
const name = config.metrics[i];
|
||||
@ -112,27 +123,19 @@ export async function useExpressionsQueryProcessor(config: Indexable) {
|
||||
tips.push(obj.error);
|
||||
typesOfMQE.push(type);
|
||||
if (!obj.error) {
|
||||
if (type === ExpressionResultType.TIME_SERIES_VALUES) {
|
||||
if (results.length === 1) {
|
||||
const label = results[0].metric && results[0].metric.labels[0] && results[0].metric.labels[0].value;
|
||||
source[c.label || label || name] = results[0].values.map((d: { value: unknown }) => d.value) || [];
|
||||
} else {
|
||||
const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
|
||||
if ([ExpressionResultType.SINGLE_VALUE, ExpressionResultType.TIME_SERIES_VALUES].includes(type)) {
|
||||
for (const item of results) {
|
||||
let label =
|
||||
item.metric &&
|
||||
item.metric.labels.map((d: { key: string; value: string }) => `${d.key}=${d.value}`).join(",");
|
||||
const values = item.values.map((d: { value: unknown }) => d.value) || [];
|
||||
const index = item.metric.labels[0].value;
|
||||
const indexNum = labels.findIndex((_, i: number) => i === Number(index));
|
||||
if (labels[indexNum] && indexNum > -1) {
|
||||
source[labels[indexNum]] = values;
|
||||
} else {
|
||||
source[index] = values;
|
||||
if (results.length === 1) {
|
||||
// If the metrics label does not exist, use the configuration label or expression
|
||||
label = label ? `${metricConfig.label || name}, ${label}` : metricConfig.label || name;
|
||||
}
|
||||
source[label] = values;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type === ExpressionResultType.SINGLE_VALUE) {
|
||||
source[c.label || name] = (results[0].values[0] || {}).value;
|
||||
}
|
||||
if (([ExpressionResultType.RECORD_LIST, ExpressionResultType.SORTED_LIST] as string[]).includes(type)) {
|
||||
source[name] = results[0].values;
|
||||
}
|
||||
@ -141,24 +144,69 @@ export async function useExpressionsQueryProcessor(config: Indexable) {
|
||||
|
||||
return { source, tips, typesOfMQE };
|
||||
}
|
||||
const params = await expressionsGraphqlPods();
|
||||
if (!params) {
|
||||
return { source: {}, tips: [], typesOfMQE: [] };
|
||||
async function fetchMetrics(configArr: any) {
|
||||
const appStore = useAppStoreWithOut();
|
||||
const variables: string[] = [`$duration: Duration!`];
|
||||
let fragments = "";
|
||||
let conditions: Recordable<unknown> = {
|
||||
duration: appStore.durationTime,
|
||||
};
|
||||
for (let i = 0; i < configArr.length; i++) {
|
||||
const params = await expressionsGraphql(configArr[i], i);
|
||||
if (params) {
|
||||
fragments += params?.fragment;
|
||||
conditions = { ...conditions, ...params.conditions };
|
||||
variables.push(...params.variables);
|
||||
}
|
||||
|
||||
}
|
||||
if (!fragments) {
|
||||
return { 0: { source: {}, tips: [], typesOfMQE: [] } };
|
||||
}
|
||||
const queryStr = `query queryData(${variables}) {${fragments}}`;
|
||||
const dashboardStore = useDashboardStore();
|
||||
const json = await dashboardStore.fetchMetricValue(params);
|
||||
const json = await dashboardStore.fetchMetricValue({
|
||||
queryStr,
|
||||
conditions,
|
||||
});
|
||||
if (json.errors) {
|
||||
ElMessage.error(json.errors);
|
||||
return { source: {}, tips: [], typesOfMQE: [] };
|
||||
return { 0: { source: {}, tips: [], typesOfMQE: [] } };
|
||||
}
|
||||
const data = expressionsSource(json);
|
||||
try {
|
||||
const pageData: Recordable = {};
|
||||
|
||||
return data;
|
||||
for (let i = 0; i < configArr.length; i++) {
|
||||
const resp: any = {};
|
||||
for (let m = 0; m < configArr[i].metrics.length; m++) {
|
||||
resp[`expression${i}${m}`] = json.data[`expression${i}${m}`];
|
||||
}
|
||||
const data = expressionsSource(configArr[i], { ...json, data: resp });
|
||||
const id = configArr[i].id;
|
||||
pageData[id] = data;
|
||||
}
|
||||
return pageData;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return { 0: { source: {}, tips: [], typesOfMQE: [] } };
|
||||
}
|
||||
}
|
||||
|
||||
const partArr = chunkArray(configList, 6);
|
||||
const promiseArr = partArr.map((d: Array<Indexable>) => fetchMetrics(d));
|
||||
const responseList = await Promise.all(promiseArr);
|
||||
let resp = {};
|
||||
for (const item of responseList) {
|
||||
resp = {
|
||||
...resp,
|
||||
...item,
|
||||
};
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
export async function useExpressionsQueryPodsMetrics(
|
||||
pods: Array<(Instance | Endpoint | Service) & Indexable>,
|
||||
allPods: Array<(Instance | Endpoint | Service) & Indexable>,
|
||||
config: {
|
||||
expressions: string[];
|
||||
subExpressions: string[];
|
||||
@ -166,7 +214,7 @@ export async function useExpressionsQueryPodsMetrics(
|
||||
},
|
||||
scope: string,
|
||||
) {
|
||||
function expressionsGraphqlPods() {
|
||||
function expressionsGraphqlPods(pods: Array<(Instance | Endpoint | Service) & Indexable>) {
|
||||
const metrics: string[] = [];
|
||||
const subMetrics: string[] = [];
|
||||
config.expressions = config.expressions || [];
|
||||
@ -198,18 +246,22 @@ export async function useExpressionsQueryPodsMetrics(
|
||||
variables.push(`$entity${index}: Entity!`);
|
||||
conditions[`entity${index}`] = entity;
|
||||
const f = metrics.map((name: string, idx: number) => {
|
||||
variables.push(`$expression${index}${idx}: String!`);
|
||||
conditions[`expression${index}${idx}`] = name;
|
||||
if (index === 0) {
|
||||
variables.push(`$expression${idx}: String!`);
|
||||
conditions[`expression${idx}`] = name;
|
||||
}
|
||||
let str = "";
|
||||
if (config.subExpressions[idx]) {
|
||||
variables.push(`$subExpression${index}${idx}: String!`);
|
||||
conditions[`subExpression${index}${idx}`] = config.subExpressions[idx];
|
||||
str = `subexpression${index}${idx}: execExpression(expression: $subExpression${index}${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`;
|
||||
if (index === 0) {
|
||||
variables.push(`$subExpression${idx}: String!`);
|
||||
conditions[`subExpression${idx}`] = config.subExpressions[idx];
|
||||
}
|
||||
str = `subexpression${index}${idx}: execExpression(expression: $subExpression${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`;
|
||||
}
|
||||
|
||||
return (
|
||||
str +
|
||||
`expression${index}${idx}: execExpression(expression: $expression${index}${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`
|
||||
`expression${index}${idx}: execExpression(expression: $expression${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`
|
||||
);
|
||||
});
|
||||
return f;
|
||||
@ -220,7 +272,10 @@ export async function useExpressionsQueryPodsMetrics(
|
||||
return { queryStr, conditions };
|
||||
}
|
||||
|
||||
function expressionsPodsSource(resp: { errors: string; data: Indexable }): Indexable {
|
||||
function expressionsPodsSource(
|
||||
resp: { errors: string; data: Indexable },
|
||||
pods: Array<(Instance | Endpoint | Service) & Indexable>,
|
||||
): Indexable {
|
||||
if (resp.errors) {
|
||||
ElMessage.error(resp.errors);
|
||||
return {};
|
||||
@ -301,24 +356,47 @@ export async function useExpressionsQueryPodsMetrics(
|
||||
|
||||
return { data, names, subNames, metricConfigArr, metricTypesArr, expressionsTips, subExpressionsTips };
|
||||
}
|
||||
|
||||
async function fetchPodsExpressionValues(pods: Array<(Instance | Endpoint | Service) & Indexable>) {
|
||||
const dashboardStore = useDashboardStore();
|
||||
const params = await expressionsGraphqlPods();
|
||||
const params = await expressionsGraphqlPods(pods);
|
||||
|
||||
const json = await dashboardStore.fetchMetricValue(params);
|
||||
|
||||
if (json.errors) {
|
||||
ElMessage.error(json.errors);
|
||||
return {};
|
||||
}
|
||||
const expressionParams = expressionsPodsSource(json);
|
||||
const expressionParams = expressionsPodsSource(json, pods);
|
||||
|
||||
return expressionParams;
|
||||
}
|
||||
|
||||
const result = [];
|
||||
for (let i = 0; i < allPods.length; i += MaximumEntities) {
|
||||
result.push(allPods.slice(i, i + MaximumEntities));
|
||||
}
|
||||
const promiseArr = result.map((d: Array<(Instance | Endpoint | Service) & Indexable>) =>
|
||||
fetchPodsExpressionValues(d),
|
||||
);
|
||||
const responseList = await Promise.all(promiseArr);
|
||||
let resp: Indexable = { data: [], expressionsTips: [], subExpressionsTips: [] };
|
||||
for (const item of responseList) {
|
||||
resp = {
|
||||
...item,
|
||||
data: [...resp.data, ...item.data],
|
||||
expressionsTips: [...resp.expressionsTips, ...item.expressionsTips],
|
||||
subExpressionsTips: [...resp.subExpressionsTips, ...item.subExpressionsTips],
|
||||
};
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
||||
export function useQueryTopologyExpressionsProcessor(metrics: string[], instances: (Call | Node)[]) {
|
||||
const appStore = useAppStoreWithOut();
|
||||
const dashboardStore = useDashboardStore();
|
||||
|
||||
function getExpressionQuery() {
|
||||
function getExpressionQuery(partMetrics?: string[]) {
|
||||
const conditions: { [key: string]: unknown } = {
|
||||
duration: appStore.durationTime,
|
||||
};
|
||||
@ -330,10 +408,14 @@ export function useQueryTopologyExpressionsProcessor(metrics: string[], instance
|
||||
let serviceInstanceName;
|
||||
let destServiceInstanceName;
|
||||
let destEndpointName;
|
||||
let normal = false;
|
||||
let destNormal;
|
||||
if (d.sourceObj && d.targetObj) {
|
||||
// instances = Calls
|
||||
serviceName = d.sourceObj.serviceName || d.sourceObj.name;
|
||||
destServiceName = d.targetObj.serviceName || d.targetObj.name;
|
||||
normal = d.sourceObj.normal || d.sourceObj.isReal || false;
|
||||
destNormal = d.targetObj.normal || d.targetObj.isReal || false;
|
||||
if (EntityType[4].value === dashboardStore.entity) {
|
||||
serviceInstanceName = d.sourceObj.name;
|
||||
destServiceInstanceName = d.targetObj.name;
|
||||
@ -345,6 +427,10 @@ export function useQueryTopologyExpressionsProcessor(metrics: string[], instance
|
||||
} else {
|
||||
// instances = Nodes
|
||||
serviceName = d.serviceName || d.name;
|
||||
normal = d.normal || d.isReal || false;
|
||||
if (EntityType[3].value === dashboardStore.entity) {
|
||||
serviceInstanceName = d.name;
|
||||
}
|
||||
if (EntityType[4].value === dashboardStore.entity) {
|
||||
serviceInstanceName = d.name;
|
||||
}
|
||||
@ -354,17 +440,17 @@ export function useQueryTopologyExpressionsProcessor(metrics: string[], instance
|
||||
}
|
||||
const entity = {
|
||||
serviceName,
|
||||
normal: true,
|
||||
normal,
|
||||
serviceInstanceName,
|
||||
endpointName,
|
||||
destServiceName,
|
||||
destNormal: destServiceName ? true : undefined,
|
||||
destNormal: destServiceName ? destNormal : undefined,
|
||||
destServiceInstanceName,
|
||||
destEndpointName,
|
||||
};
|
||||
variables.push(`$entity${index}: Entity!`);
|
||||
conditions[`entity${index}`] = entity;
|
||||
const f = metrics.map((name: string, idx: number) => {
|
||||
const f = (partMetrics || metrics).map((name: string, idx: number) => {
|
||||
if (index === 0) {
|
||||
variables.push(`$expression${idx}: String!`);
|
||||
conditions[`expression${idx}`] = name;
|
||||
@ -378,23 +464,51 @@ export function useQueryTopologyExpressionsProcessor(metrics: string[], instance
|
||||
|
||||
return { queryStr, conditions };
|
||||
}
|
||||
function handleExpressionValues(resp: { [key: string]: any }) {
|
||||
const obj: any = {};
|
||||
function handleExpressionValues(partMetrics: string[], resp: { [key: string]: any }) {
|
||||
const obj: Indexable = {};
|
||||
for (let idx = 0; idx < instances.length; idx++) {
|
||||
for (let index = 0; index < metrics.length; index++) {
|
||||
for (let index = 0; index < partMetrics.length; index++) {
|
||||
const k = "expression" + idx + index;
|
||||
if (metrics[index]) {
|
||||
if (!obj[metrics[index]]) {
|
||||
obj[metrics[index]] = {
|
||||
if (partMetrics[index]) {
|
||||
if (!obj[partMetrics[index]]) {
|
||||
obj[partMetrics[index]] = {
|
||||
values: [],
|
||||
};
|
||||
}
|
||||
obj[metrics[index]].values.push({ value: resp[k].results[0].values[0].value, id: instances[idx].id });
|
||||
obj[partMetrics[index]].values.push({
|
||||
value: resp[k] && resp[k].results[0] && resp[k].results[0].values[0].value,
|
||||
id: instances[idx].id,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
return { getExpressionQuery, handleExpressionValues };
|
||||
async function fetchMetrics(partMetrics: string[]) {
|
||||
const topologyStore = useTopologyStore();
|
||||
const param = getExpressionQuery(partMetrics);
|
||||
const res = await topologyStore.getTopologyExpressionValue(param);
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
return;
|
||||
}
|
||||
return handleExpressionValues(partMetrics, res.data);
|
||||
}
|
||||
|
||||
async function getMetrics() {
|
||||
const count = Math.floor(MaxQueryLength / instances.length);
|
||||
const metricsArr = chunkArray(metrics, count);
|
||||
const promiseArr = metricsArr.map((d: string[]) => fetchMetrics(d));
|
||||
const responseList = await Promise.all(promiseArr);
|
||||
let resp = {};
|
||||
for (const item of responseList) {
|
||||
resp = {
|
||||
...resp,
|
||||
...item,
|
||||
};
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
||||
return { getMetrics, getExpressionQuery };
|
||||
}
|
||||
|
@ -16,6 +16,9 @@
|
||||
*/
|
||||
import type { LegendOptions } from "@/types/dashboard";
|
||||
import { isDef } from "@/utils/is";
|
||||
import { DarkChartColors, LightChartColors } from "./data";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { Themes } from "@/constants/data";
|
||||
|
||||
export default function useLegendProcess(legend?: LegendOptions) {
|
||||
let isRight = false;
|
||||
@ -32,7 +35,7 @@ export default function useLegendProcess(legend?: LegendOptions) {
|
||||
if (keys.length === 1) {
|
||||
return false;
|
||||
}
|
||||
if (legend && legend.asTable) {
|
||||
if (legend && (legend.asTable || legend.asSelector)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -96,37 +99,11 @@ export default function useLegendProcess(legend?: LegendOptions) {
|
||||
|
||||
return { source, headers };
|
||||
}
|
||||
function chartColors(keys: string[]) {
|
||||
let color: string[] = [];
|
||||
switch (keys.length) {
|
||||
case 2:
|
||||
color = ["#FF6A84", "#a0b1e6"];
|
||||
break;
|
||||
case 1:
|
||||
color = ["#3f96e3"];
|
||||
break;
|
||||
default:
|
||||
color = [
|
||||
"#30A4EB",
|
||||
"#45BFC0",
|
||||
"#FFCC55",
|
||||
"#FF6A84",
|
||||
"#a0a7e6",
|
||||
"#c23531",
|
||||
"#2f4554",
|
||||
"#61a0a8",
|
||||
"#d48265",
|
||||
"#91c7ae",
|
||||
"#749f83",
|
||||
"#ca8622",
|
||||
"#bda29a",
|
||||
"#6e7074",
|
||||
"#546570",
|
||||
"#c4ccd3",
|
||||
];
|
||||
break;
|
||||
}
|
||||
return color;
|
||||
function chartColors() {
|
||||
const appStore = useAppStoreWithOut();
|
||||
const list = appStore.theme === Themes.Dark ? DarkChartColors : LightChartColors;
|
||||
|
||||
return list;
|
||||
}
|
||||
return { showEchartsLegend, isRight, aggregations, chartColors };
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { MetricQueryTypes, Calculations } from "./data";
|
||||
import { MetricModes } from "@/views/dashboard/data";
|
||||
|
||||
export function useListConfig(config: Indexable, index: number) {
|
||||
if (config.metricModes === MetricModes.Expression) {
|
||||
return {
|
||||
isLinear: false,
|
||||
isAvg: true,
|
||||
};
|
||||
}
|
||||
const i = Number(index);
|
||||
const types = [Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg];
|
||||
const calculation = config.metricConfig && config.metricConfig[i] && config.metricConfig[i].calculation;
|
||||
const isLinear =
|
||||
[MetricQueryTypes.ReadMetricsValues, MetricQueryTypes.ReadLabeledMetricsValues].includes(config.metricTypes[i]) &&
|
||||
!types.includes(calculation);
|
||||
const isAvg =
|
||||
[MetricQueryTypes.ReadMetricsValues, MetricQueryTypes.ReadLabeledMetricsValues].includes(config.metricTypes[i]) &&
|
||||
types.includes(calculation);
|
||||
|
||||
return {
|
||||
isLinear,
|
||||
isAvg,
|
||||
};
|
||||
}
|
@ -1,437 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import dayjs from "dayjs";
|
||||
import { RespFields, MetricQueryTypes, Calculations } from "./data";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import type { Instance, Endpoint, Service } from "@/types/selector";
|
||||
import type { MetricConfigOpt } from "@/types/dashboard";
|
||||
|
||||
export function useQueryProcessor(config: Indexable) {
|
||||
if (!(config.metrics && config.metrics[0])) {
|
||||
return;
|
||||
}
|
||||
if (!(config.metricTypes && config.metricTypes[0])) {
|
||||
return;
|
||||
}
|
||||
const appStore = useAppStoreWithOut();
|
||||
const dashboardStore = useDashboardStore();
|
||||
const selectorStore = useSelectorStore();
|
||||
|
||||
if (!selectorStore.currentService && dashboardStore.entity !== "All") {
|
||||
return;
|
||||
}
|
||||
const conditions: Recordable = {
|
||||
duration: appStore.durationTime,
|
||||
};
|
||||
const variables: string[] = [`$duration: Duration!`];
|
||||
const isRelation = ["ServiceRelation", "ServiceInstanceRelation", "EndpointRelation", "ProcessRelation"].includes(
|
||||
dashboardStore.entity,
|
||||
);
|
||||
if (isRelation && !selectorStore.currentDestService) {
|
||||
return;
|
||||
}
|
||||
const fragment = config.metrics.map((name: string, index: number) => {
|
||||
const metricType = config.metricTypes[index] || "";
|
||||
const c = (config.metricConfig && config.metricConfig[index]) || {};
|
||||
if ([MetricQueryTypes.ReadSampledRecords, MetricQueryTypes.SortMetrics].includes(metricType)) {
|
||||
variables.push(`$condition${index}: TopNCondition!`);
|
||||
conditions[`condition${index}`] = {
|
||||
name,
|
||||
parentService: ["All"].includes(dashboardStore.entity) ? null : selectorStore.currentService.value,
|
||||
normal: selectorStore.currentService ? selectorStore.currentService.normal : true,
|
||||
topN: Number(c.topN) || 10,
|
||||
order: c.sortOrder || "DES",
|
||||
};
|
||||
} else {
|
||||
const entity = {
|
||||
serviceName: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.value,
|
||||
normal: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.normal,
|
||||
serviceInstanceName: ["ServiceInstance", "ServiceInstanceRelation", "ProcessRelation"].includes(
|
||||
dashboardStore.entity,
|
||||
)
|
||||
? selectorStore.currentPod && selectorStore.currentPod.value
|
||||
: undefined,
|
||||
endpointName: dashboardStore.entity.includes("Endpoint")
|
||||
? selectorStore.currentPod && selectorStore.currentPod.value
|
||||
: undefined,
|
||||
processName: dashboardStore.entity.includes("Process")
|
||||
? selectorStore.currentProcess && selectorStore.currentProcess.value
|
||||
: undefined,
|
||||
destNormal: isRelation ? selectorStore.currentDestService.normal : undefined,
|
||||
destServiceName: isRelation ? selectorStore.currentDestService.value : undefined,
|
||||
destServiceInstanceName: ["ServiceInstanceRelation", "ProcessRelation"].includes(dashboardStore.entity)
|
||||
? selectorStore.currentDestPod && selectorStore.currentDestPod.value
|
||||
: undefined,
|
||||
destEndpointName:
|
||||
dashboardStore.entity === "EndpointRelation"
|
||||
? selectorStore.currentDestPod && selectorStore.currentDestPod.value
|
||||
: undefined,
|
||||
destProcessName: dashboardStore.entity.includes("ProcessRelation")
|
||||
? selectorStore.currentDestProcess && selectorStore.currentDestProcess.value
|
||||
: undefined,
|
||||
};
|
||||
if ([MetricQueryTypes.ReadRecords].includes(metricType)) {
|
||||
variables.push(`$condition${index}: RecordCondition!`);
|
||||
conditions[`condition${index}`] = {
|
||||
name,
|
||||
parentEntity: entity,
|
||||
topN: Number(c.topN) || 10,
|
||||
order: c.sortOrder || "DES",
|
||||
};
|
||||
} else {
|
||||
if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) {
|
||||
const labels = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
|
||||
variables.push(`$labels${index}: [String!]!`);
|
||||
conditions[`labels${index}`] = labels;
|
||||
}
|
||||
variables.push(`$condition${index}: MetricsCondition!`);
|
||||
conditions[`condition${index}`] = {
|
||||
name,
|
||||
entity,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) {
|
||||
return `${name}${index}: ${metricType}(condition: $condition${index}, labels: $labels${index}, duration: $duration)${RespFields[metricType]}`;
|
||||
}
|
||||
const t = metricType === MetricQueryTypes.ReadMetricsValue ? MetricQueryTypes.ReadNullableMetricsValue : metricType;
|
||||
|
||||
return `${name}${index}: ${t}(condition: $condition${index}, duration: $duration)${RespFields[t]}`;
|
||||
});
|
||||
const queryStr = `query queryData(${variables}) {${fragment}}`;
|
||||
|
||||
return {
|
||||
queryStr,
|
||||
conditions,
|
||||
};
|
||||
}
|
||||
export function useSourceProcessor(
|
||||
resp: { errors: string; data: Indexable },
|
||||
config: {
|
||||
metrics: string[];
|
||||
metricTypes: string[];
|
||||
metricConfig: MetricConfigOpt[];
|
||||
},
|
||||
) {
|
||||
if (resp.errors) {
|
||||
ElMessage.error(resp.errors);
|
||||
return {};
|
||||
}
|
||||
if (!resp.data) {
|
||||
ElMessage.error("The query is wrong");
|
||||
return {};
|
||||
}
|
||||
const source: { [key: string]: unknown } = {};
|
||||
const keys = Object.keys(resp.data);
|
||||
|
||||
config.metricTypes.forEach((type: string, index) => {
|
||||
const m = config.metrics[index];
|
||||
const c = (config.metricConfig && config.metricConfig[index]) || {};
|
||||
|
||||
if (type === MetricQueryTypes.ReadMetricsValues) {
|
||||
source[c.label || m] = (resp.data[keys[index]] && calculateExp(resp.data[keys[index]].values.values, c)) || [];
|
||||
}
|
||||
if (type === MetricQueryTypes.ReadLabeledMetricsValues) {
|
||||
const resVal = Object.values(resp.data)[0] || [];
|
||||
const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
|
||||
const labelsIdx = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
|
||||
for (const item of resVal) {
|
||||
const values = item.values.values.map((d: { value: number; isEmptyValue: boolean }) =>
|
||||
d.isEmptyValue ? NaN : aggregation(Number(d.value), c),
|
||||
);
|
||||
const indexNum = labelsIdx.findIndex((d: string) => d === item.label);
|
||||
if (labels[indexNum] && indexNum > -1) {
|
||||
source[labels[indexNum]] = values;
|
||||
} else {
|
||||
source[item.label] = values;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type === MetricQueryTypes.ReadMetricsValue) {
|
||||
const v = Object.values(resp.data)[0] || {};
|
||||
source[m] = v.isEmptyValue ? NaN : aggregation(Number(v.value), c);
|
||||
}
|
||||
if (
|
||||
(
|
||||
[MetricQueryTypes.ReadRecords, MetricQueryTypes.ReadSampledRecords, MetricQueryTypes.SortMetrics] as string[]
|
||||
).includes(type)
|
||||
) {
|
||||
source[m] = (Object.values(resp.data)[0] || []).map((d: { value: unknown; name: string }) => {
|
||||
d.value = aggregation(Number(d.value), c);
|
||||
|
||||
return d;
|
||||
});
|
||||
}
|
||||
if (type === MetricQueryTypes.READHEATMAP) {
|
||||
const resVal = Object.values(resp.data)[0] || {};
|
||||
const nodes = [] as Indexable[];
|
||||
if (!(resVal && resVal.values)) {
|
||||
source[m] = { nodes: [] };
|
||||
return;
|
||||
}
|
||||
resVal.values.forEach((items: { values: number[] }, x: number) => {
|
||||
const grids = items.values.map((val: number, y: number) => [x, y, val]);
|
||||
|
||||
nodes.push(...grids);
|
||||
});
|
||||
let buckets = [] as Indexable[];
|
||||
if (resVal.buckets.length) {
|
||||
buckets = [resVal.buckets[0].min, ...resVal.buckets.map((item: { min: string; max: string }) => item.max)];
|
||||
}
|
||||
|
||||
source[m] = { nodes, buckets }; // nodes: number[][]
|
||||
}
|
||||
});
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
export function useQueryPodsMetrics(
|
||||
pods: Array<(Instance | Endpoint | Service) & Indexable>,
|
||||
config: {
|
||||
metrics: string[];
|
||||
metricTypes: string[];
|
||||
metricConfig: MetricConfigOpt[];
|
||||
},
|
||||
scope: string,
|
||||
) {
|
||||
const metricTypes = (config.metricTypes || []).filter((m: string) => m);
|
||||
if (!metricTypes.length) {
|
||||
return;
|
||||
}
|
||||
const metrics = (config.metrics || []).filter((m: string) => m);
|
||||
if (!metrics.length) {
|
||||
return;
|
||||
}
|
||||
const appStore = useAppStoreWithOut();
|
||||
const selectorStore = useSelectorStore();
|
||||
const conditions: { [key: string]: unknown } = {
|
||||
duration: appStore.durationTime,
|
||||
};
|
||||
const variables: string[] = [`$duration: Duration!`];
|
||||
const currentService = selectorStore.currentService || {};
|
||||
const fragmentList = pods.map((d: (Instance | Endpoint | Service) & Indexable, index: number) => {
|
||||
const param = {
|
||||
serviceName: scope === "Service" ? d.label : currentService.label,
|
||||
serviceInstanceName: scope === "ServiceInstance" ? d.label : undefined,
|
||||
endpointName: scope === "Endpoint" ? d.label : undefined,
|
||||
normal: scope === "Service" ? d.normal : currentService.normal,
|
||||
};
|
||||
const f = metrics.map((name: string, idx: number) => {
|
||||
const metricType = metricTypes[idx] || "";
|
||||
variables.push(`$condition${index}${idx}: MetricsCondition!`);
|
||||
conditions[`condition${index}${idx}`] = {
|
||||
name,
|
||||
entity: param,
|
||||
};
|
||||
let labelStr = "";
|
||||
if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) {
|
||||
const c = config.metricConfig[idx] || {};
|
||||
variables.push(`$labels${index}${idx}: [String!]!`);
|
||||
labelStr = `labels: $labels${index}${idx}, `;
|
||||
const labels = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
|
||||
conditions[`labels${index}${idx}`] = labels;
|
||||
}
|
||||
const t =
|
||||
metricType === MetricQueryTypes.ReadMetricsValue ? MetricQueryTypes.ReadNullableMetricsValue : metricType;
|
||||
return `${name}${index}${idx}: ${t}(condition: $condition${index}${idx}, ${labelStr}duration: $duration)${RespFields[t]}`;
|
||||
});
|
||||
return f;
|
||||
});
|
||||
const fragment = fragmentList.flat(1).join(" ");
|
||||
const queryStr = `query queryData(${variables}) {${fragment}}`;
|
||||
|
||||
return { queryStr, conditions };
|
||||
}
|
||||
|
||||
export function usePodsSource(
|
||||
pods: Array<Instance | Endpoint>,
|
||||
resp: { errors: string; data: Indexable },
|
||||
config: {
|
||||
metrics: string[];
|
||||
metricTypes: string[];
|
||||
metricConfig: MetricConfigOpt[];
|
||||
},
|
||||
): Indexable {
|
||||
if (resp.errors) {
|
||||
ElMessage.error(resp.errors);
|
||||
return {};
|
||||
}
|
||||
const names: string[] = [];
|
||||
const metricConfigArr: MetricConfigOpt[] = [];
|
||||
const metricTypesArr: string[] = [];
|
||||
const data = pods.map((d: any, idx: number) => {
|
||||
config.metrics.map((name: string, index: number) => {
|
||||
const c: any = (config.metricConfig && config.metricConfig[index]) || {};
|
||||
const key = name + idx + index;
|
||||
if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValue) {
|
||||
const v = resp.data[key];
|
||||
d[name] = v.isEmptyValue ? NaN : aggregation(v.value, c);
|
||||
if (idx === 0) {
|
||||
names.push(name);
|
||||
metricConfigArr.push(c);
|
||||
metricTypesArr.push(config.metricTypes[index]);
|
||||
}
|
||||
}
|
||||
if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValues) {
|
||||
d[name] = {};
|
||||
if ([Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg].includes(c.calculation)) {
|
||||
d[name]["avg"] = calculateExp(resp.data[key].values.values, c);
|
||||
}
|
||||
d[name]["values"] = resp.data[key].values.values.map((val: { value: number; isEmptyValue: boolean }) =>
|
||||
val.isEmptyValue ? NaN : aggregation(val.value, c),
|
||||
);
|
||||
if (idx === 0) {
|
||||
names.push(name);
|
||||
metricConfigArr.push(c);
|
||||
metricTypesArr.push(config.metricTypes[index]);
|
||||
}
|
||||
}
|
||||
if (config.metricTypes[index] === MetricQueryTypes.ReadLabeledMetricsValues) {
|
||||
const resVal = resp.data[key] || [];
|
||||
const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
|
||||
const labelsIdx = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
|
||||
for (let i = 0; i < resVal.length; i++) {
|
||||
const item = resVal[i];
|
||||
const values = item.values.values.map((d: { value: number; isEmptyValue: boolean }) =>
|
||||
d.isEmptyValue ? NaN : aggregation(Number(d.value), c),
|
||||
);
|
||||
const indexNum = labelsIdx.findIndex((d: string) => d === item.label);
|
||||
let key = item.label;
|
||||
if (labels[indexNum] && indexNum > -1) {
|
||||
key = labels[indexNum];
|
||||
}
|
||||
if (!d[key]) {
|
||||
d[key] = {};
|
||||
}
|
||||
if ([Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg].includes(c.calculation)) {
|
||||
d[key]["avg"] = calculateExp(item.values.values, c);
|
||||
}
|
||||
d[key]["values"] = values;
|
||||
if (idx === 0) {
|
||||
names.push(key);
|
||||
metricConfigArr.push({ ...c, index: i });
|
||||
metricTypesArr.push(config.metricTypes[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return d;
|
||||
});
|
||||
return { data, names, metricConfigArr, metricTypesArr };
|
||||
}
|
||||
export function useQueryTopologyMetrics(metrics: string[], ids: string[]) {
|
||||
const appStore = useAppStoreWithOut();
|
||||
const conditions: { [key: string]: unknown } = {
|
||||
duration: appStore.durationTime,
|
||||
ids,
|
||||
};
|
||||
const variables: string[] = [`$duration: Duration!`, `$ids: [ID!]!`];
|
||||
const fragmentList = metrics.map((d: string, index: number) => {
|
||||
conditions[`m${index}`] = d;
|
||||
variables.push(`$m${index}: String!`);
|
||||
|
||||
return `${d}: getValues(metric: {
|
||||
name: $m${index}
|
||||
ids: $ids
|
||||
}, duration: $duration) {
|
||||
values {
|
||||
id
|
||||
value
|
||||
}
|
||||
}`;
|
||||
});
|
||||
const queryStr = `query queryData(${variables}) {${fragmentList.join(" ")}}`;
|
||||
|
||||
return { queryStr, conditions };
|
||||
}
|
||||
export function calculateExp(
|
||||
list: { value: number; isEmptyValue: boolean }[],
|
||||
config: { calculation?: string },
|
||||
): (number | string)[] {
|
||||
const arr = list.filter((d: { value: number; isEmptyValue: boolean }) => !d.isEmptyValue);
|
||||
const sum = arr.length ? arr.map((d: { value: number }) => Number(d.value)).reduce((a, b) => a + b) : 0;
|
||||
let data: (number | string)[] = [];
|
||||
switch (config.calculation) {
|
||||
case Calculations.Average:
|
||||
data = [(sum / arr.length).toFixed(2)];
|
||||
break;
|
||||
case Calculations.PercentageAvg:
|
||||
data = [(sum / arr.length / 100).toFixed(2)];
|
||||
break;
|
||||
case Calculations.ApdexAvg:
|
||||
data = [(sum / arr.length / 10000).toFixed(2)];
|
||||
break;
|
||||
default:
|
||||
data = list.map((d: { value: number; isEmptyValue: boolean }) =>
|
||||
d.isEmptyValue ? NaN : aggregation(d.value, config),
|
||||
);
|
||||
break;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
export function aggregation(val: number, config: { calculation?: string }): number | string {
|
||||
let data: number | string = Number(val);
|
||||
|
||||
switch (config.calculation) {
|
||||
case Calculations.Percentage:
|
||||
data = (val / 100).toFixed(2);
|
||||
break;
|
||||
case Calculations.PercentageAvg:
|
||||
data = (val / 100).toFixed(2);
|
||||
break;
|
||||
case Calculations.ByteToKB:
|
||||
data = (val / 1024).toFixed(2);
|
||||
break;
|
||||
case Calculations.ByteToMB:
|
||||
data = (val / 1024 / 1024).toFixed(2);
|
||||
break;
|
||||
case Calculations.ByteToGB:
|
||||
data = (val / 1024 / 1024 / 1024).toFixed(2);
|
||||
break;
|
||||
case Calculations.Apdex:
|
||||
data = (val / 10000).toFixed(2);
|
||||
break;
|
||||
case Calculations.ConvertSeconds:
|
||||
data = dayjs(val * 1000).format("YYYY-MM-DD HH:mm:ss");
|
||||
break;
|
||||
case Calculations.ConvertMilliseconds:
|
||||
data = dayjs(val).format("YYYY-MM-DD HH:mm:ss");
|
||||
break;
|
||||
case Calculations.MsToS:
|
||||
data = (val / 1000).toFixed(2);
|
||||
break;
|
||||
case Calculations.SecondToDay:
|
||||
data = (val / 86400).toFixed(2);
|
||||
break;
|
||||
case Calculations.NanosecondToMillisecond:
|
||||
data = (val / 1000 / 1000).toFixed(2);
|
||||
break;
|
||||
case Calculations.ApdexAvg:
|
||||
data = (val / 10000).toFixed(2);
|
||||
break;
|
||||
default:
|
||||
data;
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
47
src/hooks/useSnapshot.ts
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import type { MetricsResults } from "@/types/dashboard";
|
||||
|
||||
export function useSnapshot(metrics: { name: string; results: MetricsResults[] }[]) {
|
||||
function processResults() {
|
||||
const sources = metrics.map((metric: { name: string; results: MetricsResults[] }) => {
|
||||
const values = metric.results.map(
|
||||
(r: { values: { value: string }[]; metric: { labels: { key: string; value: string }[] } }) => {
|
||||
const arr = r.values.map((v: { value: string }) => Number(v.value));
|
||||
if (!r.metric.labels.length) {
|
||||
return { values: arr };
|
||||
}
|
||||
const name = r.metric.labels
|
||||
.map(
|
||||
(label: { key: string; value: string }) =>
|
||||
`${metric.name}${label ? "{" : ""}${label.key}=${label.value}${label ? "}" : ""}`,
|
||||
)
|
||||
.join(",");
|
||||
return { name, values: arr };
|
||||
},
|
||||
);
|
||||
|
||||
return { name: metric.name, values };
|
||||
});
|
||||
|
||||
return sources;
|
||||
}
|
||||
|
||||
return {
|
||||
processResults,
|
||||
};
|
||||
}
|
@ -24,7 +24,7 @@ limitations under the License. -->
|
||||
<style lang="scss" scoped>
|
||||
.app-main {
|
||||
height: calc(100% - 40px);
|
||||
background: #f7f9fa;
|
||||
background: $layout-background;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
@ -48,11 +48,20 @@ limitations under the License. -->
|
||||
@input="changeTimeRange"
|
||||
/>
|
||||
<span> UTC{{ appStore.utcHour >= 0 ? "+" : "" }}{{ `${appStore.utcHour}:${appStore.utcMin}` }} </span>
|
||||
<span class="ml-5" ref="themeSwitchRef">
|
||||
<el-switch
|
||||
v-model="theme"
|
||||
:active-icon="Moon"
|
||||
:inactive-icon="Sunny"
|
||||
inline-prompt
|
||||
@change="handleChangeTheme"
|
||||
/>
|
||||
</span>
|
||||
<span title="refresh" class="ghost ml-5 cp" @click="handleReload">
|
||||
<Icon iconName="retry" :loading="appStore.autoRefresh" class="middle" />
|
||||
</span>
|
||||
<span class="version ml-5 cp">
|
||||
<el-popover trigger="hover" width="250" placement="bottom" effect="light" :content="appStore.version">
|
||||
<el-popover trigger="hover" :width="250" placement="bottom" :content="appStore.version">
|
||||
<template #reference>
|
||||
<span>
|
||||
<Icon iconName="info_outline" size="middle" />
|
||||
@ -64,17 +73,18 @@ limitations under the License. -->
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import timeFormat from "@/utils/timeFormat";
|
||||
import { Themes } from "@/constants/data";
|
||||
import router from "@/router";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { MetricCatalog } from "@/views/dashboard/data";
|
||||
import type { DashboardItem } from "@/types/dashboard";
|
||||
import router from "@/router";
|
||||
import { ArrowRight } from "@element-plus/icons-vue";
|
||||
import timeFormat from "@/utils/timeFormat";
|
||||
import { MetricCatalog } from "@/views/dashboard/data";
|
||||
import { ArrowRight, Moon, Sunny } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
/*global Indexable */
|
||||
const { t, te } = useI18n();
|
||||
@ -84,11 +94,67 @@ limitations under the License. -->
|
||||
const pathNames = ref<{ path?: string; name: string; selected: boolean }[][]>([]);
|
||||
const timeRange = ref<number>(0);
|
||||
const pageTitle = ref<string>("");
|
||||
const theme = ref<boolean>(true);
|
||||
const themeSwitchRef = ref<HTMLElement>();
|
||||
|
||||
const savedTheme = window.localStorage.getItem("theme-is-dark");
|
||||
if (savedTheme === "false") {
|
||||
theme.value = false;
|
||||
}
|
||||
if (savedTheme === "") {
|
||||
// read the theme preference from system setting if there is no user setting
|
||||
theme.value = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
}
|
||||
|
||||
changeTheme();
|
||||
resetDuration();
|
||||
getVersion();
|
||||
getNavPaths();
|
||||
|
||||
function changeTheme() {
|
||||
const root = document.documentElement;
|
||||
|
||||
if (theme.value) {
|
||||
root.classList.add(Themes.Dark);
|
||||
root.classList.remove(Themes.Light);
|
||||
appStore.setTheme(Themes.Dark);
|
||||
} else {
|
||||
root.classList.add(Themes.Light);
|
||||
root.classList.remove(Themes.Dark);
|
||||
appStore.setTheme(Themes.Light);
|
||||
}
|
||||
window.localStorage.setItem("theme-is-dark", String(theme.value));
|
||||
}
|
||||
|
||||
function handleChangeTheme() {
|
||||
const x = themeSwitchRef.value?.offsetLeft ?? 0;
|
||||
const y = themeSwitchRef.value?.offsetTop ?? 0;
|
||||
const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
|
||||
// compatibility handling
|
||||
if (!document.startViewTransition) {
|
||||
changeTheme();
|
||||
return;
|
||||
}
|
||||
// api: https://developer.chrome.com/docs/web-platform/view-transitions
|
||||
const transition = document.startViewTransition(() => {
|
||||
changeTheme();
|
||||
});
|
||||
|
||||
transition.ready.then(() => {
|
||||
const clipPath = [`circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`];
|
||||
document.documentElement.animate(
|
||||
{
|
||||
clipPath: !theme.value ? clipPath.reverse() : clipPath,
|
||||
},
|
||||
{
|
||||
duration: 500,
|
||||
easing: "ease-in",
|
||||
pseudoElement: !theme.value ? "::view-transition-old(root)" : "::view-transition-new(root)",
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function getName(list: any[]) {
|
||||
return list.find((d: any) => d.selected) || {};
|
||||
}
|
||||
@ -287,21 +353,16 @@ limitations under the License. -->
|
||||
padding: 5px;
|
||||
text-align: left;
|
||||
justify-content: space-between;
|
||||
background-color: #fafbfc;
|
||||
border-bottom: 1px solid #dfe4e8;
|
||||
color: #222;
|
||||
background-color: $theme-background;
|
||||
border-bottom: 1px solid $border-color;
|
||||
color: $font-color;
|
||||
font-size: $font-size-smaller;
|
||||
}
|
||||
|
||||
.nav-bar.dark {
|
||||
background-color: #333840;
|
||||
border-bottom: 1px solid #252a2f;
|
||||
color: #fafbfc;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: $font-size-normal;
|
||||
font-weight: 500;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
|
@ -50,7 +50,7 @@ limitations under the License. -->
|
||||
</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
</el-sub-menu>
|
||||
<el-menu-item :index="String(menu.name)" @click="changePage(menu)" v-else>
|
||||
<el-menu-item :index="String(menu.name)" v-else>
|
||||
<el-icon class="menu-icons" :style="{ marginRight: '12px' }" @mouseover="setCollapse">
|
||||
<router-link class="items menu-title" :to="menu.children[0].path">
|
||||
<Icon size="lg" :iconName="menu.meta.icon" />
|
||||
@ -83,7 +83,6 @@ limitations under the License. -->
|
||||
const appStore = useAppStoreWithOut();
|
||||
const router = useRouter();
|
||||
const name = ref<string>(String(router.currentRoute.value.name));
|
||||
const theme = ["VirtualMachine", "Kubernetes"].includes(name.value || "") ? ref("light") : ref("black");
|
||||
const routes = ref<RouteRecordRaw[] | any>(
|
||||
(router.options.routes || []).filter((d: any) => d.meta && d.meta.activate),
|
||||
);
|
||||
@ -100,9 +99,7 @@ limitations under the License. -->
|
||||
if (route.name === "ViewWidget") {
|
||||
showMenu.value = false;
|
||||
}
|
||||
const changePage = (menu: RouteRecordRaw) => {
|
||||
theme.value = ["VirtualMachine", "Kubernetes"].includes(String(menu.name)) ? "light" : "black";
|
||||
};
|
||||
|
||||
const filterMenus = (menus: Recordable[]) => {
|
||||
return menus.filter((d) => d.meta && !d.meta.notShow && d.meta.activate);
|
||||
};
|
||||
|
@ -94,14 +94,13 @@ const msg = {
|
||||
editTab: "Enable editing tab names",
|
||||
label: "Service Name",
|
||||
id: "Service ID",
|
||||
setRoot: "Set this to root",
|
||||
setNormal: "Set this to normal",
|
||||
setRoot: "Set Normal to Root",
|
||||
setNormal: "Set Root to Normal",
|
||||
export: "Export Dashboard Templates",
|
||||
import: "Import Dashboard Templates",
|
||||
yes: "Yes",
|
||||
no: "No",
|
||||
tableHeaderCol1: "Name of the first column of the table",
|
||||
tableHeaderCol2: "Name of the second column of the table",
|
||||
tableHeaderCol2: "Name of the last column of the table",
|
||||
showXAxis: "Show X Axis",
|
||||
showYAxis: "Show Y Axis",
|
||||
nameError: "The dashboard name cannot be duplicate",
|
||||
@ -140,7 +139,6 @@ const msg = {
|
||||
enableAssociate: "Enable association",
|
||||
text: "Text",
|
||||
query: "Query",
|
||||
endpointTips: "The table shows up to 20 pieces of endpoints.",
|
||||
viewTrace: "View Related Traces",
|
||||
relatedTraceOptions: "Related Trace Options",
|
||||
setLatencyDuration: "Latency Related Metrics",
|
||||
@ -155,6 +153,7 @@ const msg = {
|
||||
legendOptions: "Legend Options",
|
||||
showLegend: "Show Legend",
|
||||
asTable: "As Table",
|
||||
asSelector: "As Selector",
|
||||
toTheRight: "To The Right",
|
||||
legendValues: "Legend Values",
|
||||
minDuration: "Minimal Request Duration",
|
||||
@ -165,7 +164,6 @@ const msg = {
|
||||
iframeSrc: "Iframe Link",
|
||||
generateLink: "Generate Link",
|
||||
setDuration: "Lock Query Duration",
|
||||
openFunction: "OpenFunction",
|
||||
period: "Period",
|
||||
windows: "Windows",
|
||||
seconds: "Seconds",
|
||||
@ -286,7 +284,8 @@ const msg = {
|
||||
errorInfo: "Error Info",
|
||||
stack: "Stack",
|
||||
serviceVersion: "Service Version",
|
||||
errorPage: "Error Page",
|
||||
pagePath: "Page Path",
|
||||
errorUrl: "Error Url",
|
||||
category: "Category",
|
||||
grade: "Grade",
|
||||
relatedTraceLogs: "Related Logs",
|
||||
@ -297,11 +296,12 @@ const msg = {
|
||||
return: "Return",
|
||||
isError: "Error",
|
||||
contentType: "Content Type",
|
||||
content: "Content",
|
||||
content: "Timestamp - Content",
|
||||
level: "Level",
|
||||
viewLogs: "View Logs",
|
||||
logsTagsTip: `Only tags defined in the core/default/searchableLogsTags are searchable.
|
||||
Check more details on the Configuration Vocabulary page`,
|
||||
keywordsOfContentLogTips: "Current storage of SkyWalking OAP server does not support this.",
|
||||
keywordsOfContentLogTips: "Current storage of SkyWalking OAP server does not support this",
|
||||
setEvent: "Set Event",
|
||||
viewAttributes: "View",
|
||||
attributes: "Attributes",
|
||||
@ -356,7 +356,7 @@ const msg = {
|
||||
addKeywordsOfContent: "Please input a keyword of content",
|
||||
addExcludingKeywordsOfContent: "Please input a keyword of excluding content",
|
||||
noticeTag: "Please press Enter after inputting a tag(key=value).",
|
||||
conditionNotice: "Notice: Please press Enter after inputting a key of content, exclude key of content(key=value).",
|
||||
conditionNotice: "Notice: Please press Enter after inputting a key of content, exclude key of content(key=value)",
|
||||
language: "Language",
|
||||
save: "Save",
|
||||
editStrategy: "Edit Policies",
|
||||
@ -378,9 +378,24 @@ const msg = {
|
||||
menus: "Menus",
|
||||
saveReload: "Save and reload the page",
|
||||
document: "Documentation",
|
||||
metricMode: "Metric Mode",
|
||||
addExpressions: "Add Expressions",
|
||||
expressions: "Expression",
|
||||
unhealthyExpression: "Unhealthy Expression",
|
||||
traceDesc:
|
||||
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
|
||||
tabExpressions: "Tab Expressions",
|
||||
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
|
||||
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
|
||||
valueMappings: "Value Mappings",
|
||||
mappingTip: "Notice: The mapping key is a Regex string, e.g. ^([0-9])$",
|
||||
valueDashboard: "Data Value Related Dashboard",
|
||||
viewValueDashboard: "View Dashboard",
|
||||
errorInstances: "Error Instances",
|
||||
successInstances: "Success Instances",
|
||||
profilingEvents: "Async Profiling Events",
|
||||
execArgs: "Exec Args",
|
||||
instances: "Instances",
|
||||
snapshot: "Snapshot",
|
||||
expression: "Expression",
|
||||
};
|
||||
export default msg;
|
||||
|
@ -101,8 +101,7 @@ const msg = {
|
||||
import: "Importar Plantilla Panel",
|
||||
yes: "Sí",
|
||||
no: "No",
|
||||
tableHeaderCol1: "Nombre de la primera columna de la tabla",
|
||||
tableHeaderCol2: "Nombre de la segunda columna de la tabla",
|
||||
tableHeaderCol2: "Nombre de la Último columna de la tabla",
|
||||
showXAxis: "Mostrar Eje X",
|
||||
showYAxis: "Mostrar Eje Y",
|
||||
nameError: "El nombre del panel no puede ser duplicado",
|
||||
@ -139,7 +138,6 @@ const msg = {
|
||||
"El nombre sólo admite chino e inglés, líneas horizontales y subrayado, y la longitud del nombre no excederá de 300 caracteres",
|
||||
enableAssociate: "Activar asociación",
|
||||
query: "Consulta",
|
||||
endpointTips: "Aquí, la tabla muestra hasta 20 punto final.",
|
||||
queryOrder: "Consulta por duración",
|
||||
setOrder: "Orden de consulta",
|
||||
latency: "Retraso",
|
||||
@ -149,7 +147,6 @@ const msg = {
|
||||
iframeSrc: "Enlace Iframe",
|
||||
generateLink: "Generar enlaces",
|
||||
setDuration: "Duración de la consulta de bloqueo",
|
||||
openFunction: "OpenFunction",
|
||||
seconds: "Segundos",
|
||||
hourTip: "Seleccione Hora",
|
||||
minuteTip: "Seleccione Minuto",
|
||||
@ -285,7 +282,8 @@ const msg = {
|
||||
errorInfo: "Info Error",
|
||||
stack: "Pila",
|
||||
serviceVersion: "Versión Servicio",
|
||||
errorPage: "Página de Error",
|
||||
pagePath: "Página de Error",
|
||||
errorUrl: "Ruta de Error",
|
||||
category: "Categoría",
|
||||
grade: "Grado",
|
||||
relatedTraceLogs: "Registro de Datos Relacionados",
|
||||
@ -297,10 +295,11 @@ const msg = {
|
||||
isError: "Error",
|
||||
contentType: "Tipo de Contenido",
|
||||
content: "Contenido",
|
||||
level: "Level",
|
||||
viewLogs: "Ver Registro de Datos",
|
||||
logsTagsTip: `Solamente etiquetas definidas en core/default/searchableLogsTags pueden ser buscadas.
|
||||
Más información en la página de Vocabulario de Configuración`,
|
||||
keywordsOfContentLogTips: "El almacenamiento actual del servidor SkyWalking OAP no lo soporta.",
|
||||
keywordsOfContentLogTips: "El almacenamiento actual del servidor SkyWalking OAP no lo soporta",
|
||||
setEvent: "Establecer Evento",
|
||||
viewAttributes: "Ver",
|
||||
serviceEvents: "Eventos Servico",
|
||||
@ -378,9 +377,25 @@ const msg = {
|
||||
menus: "Menus",
|
||||
saveReload: "Save and reload the page",
|
||||
document: "Documentation",
|
||||
metricMode: "Metric Mode",
|
||||
addExpressions: "Add Expressions",
|
||||
expressions: "Expression",
|
||||
unhealthyExpression: "Unhealthy Expression",
|
||||
traceDesc:
|
||||
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
|
||||
tabExpressions: "Tab Expressions",
|
||||
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
|
||||
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
|
||||
valueMappings: "Value Mappings",
|
||||
mappingTip: "Aviso: La clave de mapeo es una cadena Regex, p. ej. ^([0-9])$",
|
||||
valueDashboard: "Data Value Related Dashboard",
|
||||
viewValueDashboard: "View Dashboard",
|
||||
errorInstances: "Error Instances",
|
||||
successInstances: "Success Instances",
|
||||
profilingEvents: "Async Profiling Events",
|
||||
execArgs: "Exec Args",
|
||||
instances: "Instances",
|
||||
snapshot: "Snapshot",
|
||||
expression: "Expression",
|
||||
asSelector: "As Selector",
|
||||
};
|
||||
export default msg;
|
||||
|
@ -30,6 +30,11 @@ const titles = {
|
||||
general_service_virtual_mq: "Virtual MQ",
|
||||
general_service_virtual_mq_desc:
|
||||
"Observe the virtual message queue servers which are conjectured by language agents through various plugins.",
|
||||
// Workflow Scheduler
|
||||
workflow_scheduler: "Workflow Scheduler",
|
||||
workflow_scheduler_desc: "Provide monitoring for workflow scheduling systems.",
|
||||
workflow_scheduler_airflow: "Airflow",
|
||||
workflow_scheduler_airflow_desc: "Observe tasks through telemetry data collected from Apache Airflow.",
|
||||
// Service Mesh
|
||||
service_mesh: "Service Mesh",
|
||||
service_mesh_desc:
|
||||
@ -41,13 +46,6 @@ const titles = {
|
||||
service_mesh_control_plane_desc: "Provide monitoring of the behavior of Istio through its self-monitoring metrics.",
|
||||
service_mesh_data_plane: "Data Plane",
|
||||
service_mesh_data_plane_desc: "Observe Envoy Proxy through Envoy Metrics Service.",
|
||||
// Functions
|
||||
functions: "Functions",
|
||||
functions_desc:
|
||||
"FaaS (Function-as-a-Service) is a type of cloud-computing service that allows you to execute code in response to events without the complex infrastructure typically associated with building and launching microservices applications.",
|
||||
functions_openfunction: "OpenFunction",
|
||||
functions_openfunction_desc:
|
||||
"OpenFunction as a FaaS platform, provides out-of-box observability with SkyWalking integration.",
|
||||
// Kubernetes
|
||||
kubernetes: "Kubernetes",
|
||||
kubernetes_desc:
|
||||
@ -82,6 +80,8 @@ const titles = {
|
||||
gateway: "Gateway",
|
||||
gateway_desc:
|
||||
"API gateway is an API management tool that sits between a client and a collection of backend services.",
|
||||
gateway_nginx: "Nginx",
|
||||
gateway_nginx_desc: "Provide Nginx monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
gateway_apisix: "APISIX",
|
||||
gateway_apisix_desc: "Provide APISIX monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
gateway_aws_api_gateway: "AWS API Gateway",
|
||||
@ -109,6 +109,12 @@ const titles = {
|
||||
"A message queue is a form of asynchronous service-to-service communication used in serverless and microservices architectures.",
|
||||
mq_rabbitmq: "RabbitMQ",
|
||||
mq_rabbitmq_desc: "Provide RabbitMQ monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
mq_kafka: "Kafka",
|
||||
mq_kafka_desc: "Provide Kafka monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
mq_pulsar: "Pulsar",
|
||||
mq_pulsar_desc: "Provide Pulsar monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
mq_rocketmq: "RocketMQ",
|
||||
mq_rocketmq_desc: "Provide RocketMQ monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
// self observability
|
||||
self_observability: "Self Observability",
|
||||
self_observability_desc:
|
||||
@ -119,6 +125,23 @@ const titles = {
|
||||
self_observability_satellite: "Satellite",
|
||||
self_observability_satellite_desc:
|
||||
"Satellite: an open-source agent designed for the cloud-native infrastructures, which provides a low-cost, high-efficient, and more secure way to collect telemetry data. It is the recommended load balancer for telemetry collecting.",
|
||||
self_observability_java_agent: "SkyWalking Java Agent",
|
||||
self_observability_java_agent_desc:
|
||||
"The self observability of SkyWalking Java Agent, which provides the abilities to measure the tracing performance and error statistics of plugins.",
|
||||
self_observability_go_agent: "SkyWalking Go Agent",
|
||||
self_observability_go_agent_desc:
|
||||
"The self observability of SkyWalking Go Agent, which provides the abilities to measure the tracing performance and error statistics of plugins.",
|
||||
cilium: "Cilium",
|
||||
cilium_desc:
|
||||
"Cilium is a CNI plugin for Kubernetes that provides eBPF-based networking, security, and load balancing.",
|
||||
cilium_service: "Cilium Service",
|
||||
cilium_service_desc: "Observe Service status and resources from Cilium Hubble.",
|
||||
data_processing_engine: "Data Processing Engine",
|
||||
data_processing_engine_desc:
|
||||
"A data processing engine is a system designed to efficiently process, transform, and analyze large-scale data in real time or batch mode.",
|
||||
data_processing_engine_flink: "Flink",
|
||||
data_processing_engine_flink_desc:
|
||||
"Apache Flink is a framework and distributed processing engine for stateful computations over unbounded and bounded data streams. Flink has been designed to run in all common cluster environments, perform computations at in-memory speed and at any scale.",
|
||||
};
|
||||
|
||||
export default titles;
|
||||
|
@ -30,6 +30,12 @@ const titles = {
|
||||
general_service_virtual_mq: "MQ virtual",
|
||||
general_service_virtual_mq_desc:
|
||||
"Observe the virtual message queue servers which are conjectured by language agents through various plugins.",
|
||||
// Workflow Scheduler
|
||||
workflow_scheduler: "Flujo de trabajo",
|
||||
workflow_scheduler_desc: "Proporcionar monitoreo para sistemas de programación de flujos de trabajo.",
|
||||
workflow_scheduler_airflow: "Airflow",
|
||||
workflow_scheduler_airflow_desc:
|
||||
"Observando tareas a través de los datos de telemetría recopilados desde Apache Airflow.",
|
||||
// Service Mesh
|
||||
service_mesh: "Malla de Servicios",
|
||||
service_mesh_desc:
|
||||
@ -41,13 +47,6 @@ const titles = {
|
||||
service_mesh_control_plane_desc: "Provide monitoring of the behavior of Istio through its self-monitoring metrics.",
|
||||
service_mesh_data_plane: "Plano de Datos",
|
||||
service_mesh_data_plane_desc: "Observe Envoy Proxy through Envoy Metrics Service.",
|
||||
// Functions
|
||||
functions: "Funciones",
|
||||
functions_desc:
|
||||
"FaaS (Function-as-a-Service) is a type of cloud-computing service that allows you to execute code in response to events without the complex infrastructure typically associated with building and launching microservices applications.",
|
||||
functions_openfunction: "OpenFunction",
|
||||
functions_openfunction_desc:
|
||||
"OpenFunction as a FaaS platform, provides out-of-box observability with SkyWalking integration.",
|
||||
// Kubernetes
|
||||
kubernetes: "Kubernetes",
|
||||
kubernetes_desc:
|
||||
@ -82,6 +81,8 @@ const titles = {
|
||||
gateway: "Puerta",
|
||||
gateway_desc:
|
||||
"API gateway is an API management tool that sits between a client and a collection of backend services.",
|
||||
gateway_nginx: "Nginx",
|
||||
gateway_nginx_desc: "Provide Nginx monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
gateway_apisix: "APISIX",
|
||||
gateway_apisix_desc: "Provide APISIX monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
gateway_aws_api_gateway: "AWS API Gateway",
|
||||
@ -109,6 +110,12 @@ const titles = {
|
||||
"A message queue is a form of asynchronous service-to-service communication used in serverless and microservices architectures.",
|
||||
mq_rabbitmq: "RabbitMQ",
|
||||
mq_rabbitmq_desc: "Provide RabbitMQ monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
mq_kafka: "Kafka",
|
||||
mq_kafka_desc: "Provide Kafka monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
mq_pulsar: "Pulsar",
|
||||
mq_pulsar_desc: "Provide Pulsar monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
mq_rocketmq: "RocketMQ",
|
||||
mq_rocketmq_desc: "Provide RocketMQ monitoring through OpenTelemetry's Prometheus Receiver.",
|
||||
// self observability
|
||||
self_observability: "Self Observability",
|
||||
self_observability_desc:
|
||||
@ -119,6 +126,23 @@ const titles = {
|
||||
self_observability_satellite: "Satellite",
|
||||
self_observability_satellite_desc:
|
||||
"Satellite: an open-source agent designed for the cloud-native infrastructures, which provides a low-cost, high-efficient, and more secure way to collect telemetry data. It is the recommended load balancer for telemetry collecting.",
|
||||
self_observability_java_agent: "SkyWalking Java Agent",
|
||||
self_observability_java_agent_desc:
|
||||
"La auto-observabilidad de SkyWalking Java Agent, que proporciona la capacidad de medir el rendimiento del trazado y las estadísticas de errores de los plugins.",
|
||||
self_observability_go_agent: "SkyWalking Go Agent",
|
||||
self_observability_go_agent_desc:
|
||||
"La auto-observabilidad de SkyWalking Go Agent, que proporciona la capacidad de medir el rendimiento del trazado y las estadísticas de errores de los plugins.",
|
||||
cilium: "Cilium",
|
||||
cilium_desc:
|
||||
"Cilium es un complemento CNI para Kubernetes que proporciona redes, seguridad y equilibrio de carga basados en eBPF.",
|
||||
cilium_service: "Cilium Service",
|
||||
cilium_service_desc: "Observe el estado del servicio y los recursos de Cilium Hubble.",
|
||||
data_processing_engine: "Data Processing Engine",
|
||||
data_processing_engine_desc:
|
||||
"A data processing engine is a system designed to efficiently process, transform, and analyze large-scale data in real time or batch mode.",
|
||||
data_processing_engine_flink: "Flink",
|
||||
data_processing_engine_flink_desc:
|
||||
"Apache Flink is a framework and distributed processing engine for stateful computations over unbounded and bounded data streams. Flink has been designed to run in all common cluster environments, perform computations at in-memory speed and at any scale.",
|
||||
};
|
||||
|
||||
export default titles;
|
||||
|
@ -26,6 +26,11 @@ const titles = {
|
||||
general_service_virtual_cache_desc: "观察语言代理通过各种插件推测的虚拟缓存服务器。",
|
||||
general_service_virtual_mq: "虚拟消息队列",
|
||||
general_service_virtual_mq_desc: "观察语言代理通过各种插件推测的虚拟消息队列服务器。",
|
||||
// Workflow Scheduler
|
||||
workflow_scheduler: "工作流调度",
|
||||
workflow_scheduler_desc: "提供工作流调度系统监控。",
|
||||
workflow_scheduler_airflow: "Airflow",
|
||||
workflow_scheduler_airflow_desc: "通过从Apache Airflow收集的遥测数据观察任务。",
|
||||
// Service Mesh
|
||||
service_mesh: "服务网格",
|
||||
service_mesh_desc: "服务网格(Istio)通过分布式或微服务架构解决了开发人员和运营商面临的挑战。",
|
||||
@ -35,12 +40,6 @@ const titles = {
|
||||
service_mesh_control_plane_desc: "通过Istio的自我监控指标提供对其行为的监控。",
|
||||
service_mesh_data_plane: "数据平面",
|
||||
service_mesh_data_plane_desc: "通过Envoy Metrics Service观察Envoy Proxy。",
|
||||
// Functions
|
||||
functions: "Functions",
|
||||
functions_desc:
|
||||
"FaaS(功能即服务)是一种云计算服务,允许您在没有通常与构建和启动微服务应用程序相关的复杂基础设施的情况下执行代码以响应事件。",
|
||||
functions_openfunction: "OpenFunction",
|
||||
functions_openfunction_desc: "OpenFunction作为一个FaaS平台,通过SkyWalking集成提供开箱即用的可观察性。",
|
||||
// Kubernetes
|
||||
kubernetes: "Kubernetes",
|
||||
kubernetes_desc: "Kubernetes是一个开源的容器编排系统,用于自动化软件部署、扩展和管理。",
|
||||
@ -72,6 +71,8 @@ const titles = {
|
||||
// Gateway
|
||||
gateway: "网关",
|
||||
gateway_desc: "API网关是位于客户端和后端服务集合之间的API管理工具。",
|
||||
gateway_nginx: "Nginx",
|
||||
gateway_nginx_desc: "通过OpenTelemetry的Prometheus接收器提供Nginx监控。",
|
||||
gateway_apisix: "APISIX",
|
||||
gateway_apisix_desc: "通过OpenTelemetry的Prometheus接收器提供APISIX监控。",
|
||||
gateway_aws_api_gateway: "AWS API Gateway",
|
||||
@ -96,6 +97,12 @@ const titles = {
|
||||
mq_desc: "消息队列是无服务器和微服务架构中使用的异步服务对服务通信的一种形式。",
|
||||
mq_rabbitmq: "RabbitMQ",
|
||||
mq_rabbitmq_desc: "通过OpenTelemetry的Prometheus接收器提供RabbitMQ监控。",
|
||||
mq_kafka: "Kafka",
|
||||
mq_Kafka_desc: "通过OpenTelemetry的Prometheus接收器提供Kafka监控。",
|
||||
mq_pulsar: "Pulsar",
|
||||
mq_Pulsar_desc: "通过OpenTelemetry的Prometheus接收器提供Pulsar监控。",
|
||||
mq_rocketmq: "RocketMQ",
|
||||
mq_rocketmq_desc: "通过OpenTelemetry的Prometheus接收器提供RocketMQ监控。",
|
||||
// self observability
|
||||
self_observability: "自监控",
|
||||
self_observability_desc: "自观察性为运行SkyWalking生态系统中的组件和服务器提供了可观察性。",
|
||||
@ -104,6 +111,19 @@ const titles = {
|
||||
self_observability_satellite: "Satellite",
|
||||
self_observability_satellite_desc:
|
||||
"Satellite:为云原生基础设施设计的开源代理,提供了一种低成本、高效、更安全的遥测数据收集方式。它是遥测采集的推荐负载均衡器。",
|
||||
self_observability_java_agent: "SkyWalking Java Agent",
|
||||
self_observability_java_agent_desc: "SkyWalking Java Agent 自监控提供了对 agent 插件的性能追踪和错误统计。",
|
||||
self_observability_go_agent: "SkyWalking Go Agent",
|
||||
self_observability_go_agent_desc: "SkyWalking Go Agent 自监控提供了对 agent 插件的性能追踪和错误统计。",
|
||||
cilium: "Cilium",
|
||||
cilium_desc: "Cilium是Kubernetes上的CNI插件,提供基于eBPF的网络、安全和负载均衡。",
|
||||
cilium_service: "Cilium服务",
|
||||
cilium_service_desc: "通过Cilium Hubble收集的遥测数据观察服务。",
|
||||
data_processing_engine: "数据处理引擎",
|
||||
data_processing_engine_desc: "数据处理引擎是一个用于高效地在实时或批处理模式下处理、转换和分析大规模数据的系统。",
|
||||
data_processing_engine_flink: "Flink",
|
||||
data_processing_engine_flink_desc:
|
||||
"Apache Flink 是一个框架和分布式处理引擎,用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算。",
|
||||
};
|
||||
|
||||
export default titles;
|
||||
|
@ -99,8 +99,7 @@ const msg = {
|
||||
import: "导入仪表板模板",
|
||||
yes: "是",
|
||||
no: "否",
|
||||
tableHeaderCol1: "表格的第一列的名称",
|
||||
tableHeaderCol2: "表格的第二列的名称",
|
||||
tableHeaderCol2: "表格的最后一列的名称",
|
||||
showXAxis: "显示X轴",
|
||||
showYAxis: "显示Y轴",
|
||||
nameError: "仪表板名称不能重复",
|
||||
@ -138,7 +137,6 @@ const msg = {
|
||||
duplicateName: "重复的名称",
|
||||
text: "文本",
|
||||
query: "查询",
|
||||
endpointTips: "这里最多展示20条endpoints。",
|
||||
viewTrace: "查看相关Trace",
|
||||
relatedTraceOptions: "相关的Trace选项",
|
||||
setLatencyDuration: "延迟相关指标",
|
||||
@ -153,6 +151,7 @@ const msg = {
|
||||
legendOptions: "图例选项",
|
||||
showLegend: "显示图例",
|
||||
asTable: "作为表格",
|
||||
asSelector: "作为选择器",
|
||||
toTheRight: "在右边",
|
||||
legendValues: "图例值",
|
||||
minDuration: "最小请求持续时间",
|
||||
@ -163,7 +162,6 @@ const msg = {
|
||||
iframeSrc: "Iframe链接",
|
||||
generateLink: "生成链接",
|
||||
setDuration: "锁定查询持续时间",
|
||||
openFunction: "OpenFunction",
|
||||
period: "周期",
|
||||
windows: "Windows",
|
||||
seconds: "秒",
|
||||
@ -283,7 +281,8 @@ const msg = {
|
||||
errorInfo: "错误信息",
|
||||
stack: "堆栈",
|
||||
serviceVersion: "服务版本",
|
||||
errorPage: "错误页面",
|
||||
pagePath: "错误页面",
|
||||
errorUrl: "错误路径",
|
||||
category: "类别",
|
||||
grade: "等级",
|
||||
relatedTraceLogs: "相关的日志",
|
||||
@ -294,7 +293,8 @@ const msg = {
|
||||
return: "返回",
|
||||
isError: "错误",
|
||||
contentType: "内容类型",
|
||||
content: "内容",
|
||||
content: "时间戳 - 内容",
|
||||
level: "Level",
|
||||
viewLogs: "查看日志",
|
||||
logsTagsTip: "只有core/default/searchableLogsTags中定义的标记才可搜索。查看配置词汇表页面上的更多详细信息。",
|
||||
keywordsOfContentLogTips: "SkyWalking OAP服务器的当前存储不支持此操作",
|
||||
@ -376,9 +376,24 @@ const msg = {
|
||||
menusManagement: "菜单",
|
||||
saveReload: "保存并重新加载页面",
|
||||
document: "文档",
|
||||
metricMode: "指标模式",
|
||||
addExpressions: "添加表达式",
|
||||
expressions: "表达式",
|
||||
unhealthyExpression: "非健康表达式",
|
||||
traceDesc:
|
||||
"Trace Segment代表在单一操作系统进程(例如JVM)中执行的追踪部分。它包含了一组跨度(spans),这些跨度通常与单一请求或执行上下文关联。",
|
||||
tabExpressions: "Tab表达式",
|
||||
hierarchyNodeMetrics: "层次图节点的指标",
|
||||
hierarchyNodeDashboard: "作为层次图节点的dashboard",
|
||||
valueMappings: "值映射",
|
||||
mappingTip: "注意: 映射键是一个正则表达式字符串,比如 ^([0-9])$",
|
||||
valueDashboard: "数据值相关的仪表板",
|
||||
viewValueDashboard: "查看仪表板",
|
||||
errorInstances: "错误的实例",
|
||||
successInstances: "成功的实例",
|
||||
profilingEvents: "异步分析事件",
|
||||
execArgs: "String任务扩展",
|
||||
instances: "实例",
|
||||
snapshot: "快照",
|
||||
expression: "表达式",
|
||||
};
|
||||
export default msg;
|
||||
|
@ -15,6 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { createApp } from "vue";
|
||||
import { ElLoading } from "element-plus";
|
||||
import App from "./App.vue";
|
||||
import { store } from "./store";
|
||||
import components from "@/components";
|
||||
@ -23,6 +24,11 @@ import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import "./styles/index.ts";
|
||||
import "virtual:svg-icons-register";
|
||||
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: "Loading...",
|
||||
background: "rgba(0, 0, 0, 0.8)",
|
||||
});
|
||||
const app = createApp(App);
|
||||
const appStore = useAppStoreWithOut();
|
||||
|
||||
@ -34,7 +40,7 @@ mountApp();
|
||||
async function mountApp() {
|
||||
await appStore.getActivateMenus();
|
||||
await appStore.queryOAPTimeInfo();
|
||||
|
||||
const router = await import("./router");
|
||||
app.use(router.default).mount("#app");
|
||||
loading.close();
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
import type { RouteRecordRaw } from "vue-router";
|
||||
import Layout from "@/layout/Index.vue";
|
||||
import Alarm from "@/views/Alarm.vue";
|
||||
|
||||
export const routesAlarm: Array<RouteRecordRaw> = [
|
||||
{
|
||||
@ -32,8 +33,8 @@ export const routesAlarm: Array<RouteRecordRaw> = [
|
||||
children: [
|
||||
{
|
||||
path: "/alerting",
|
||||
name: "Alarm",
|
||||
component: () => import("@/views/Alarm.vue"),
|
||||
name: "ViewAlarm",
|
||||
component: Alarm,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -16,6 +16,10 @@
|
||||
*/
|
||||
import type { RouteRecordRaw } from "vue-router";
|
||||
import Layout from "@/layout/Index.vue";
|
||||
import List from "@/views/dashboard/List.vue";
|
||||
import New from "@/views/dashboard/New.vue";
|
||||
import Edit from "@/views/dashboard/Edit.vue";
|
||||
import Widget from "@/views/dashboard/Widget.vue";
|
||||
|
||||
export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
{
|
||||
@ -32,7 +36,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard/list",
|
||||
component: () => import("@/views/dashboard/List.vue"),
|
||||
component: List,
|
||||
name: "List",
|
||||
meta: {
|
||||
i18nKey: "dashboardList",
|
||||
@ -42,7 +46,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
},
|
||||
{
|
||||
path: "/dashboard/new",
|
||||
component: () => import("@/views/dashboard/New.vue"),
|
||||
component: New,
|
||||
name: "New",
|
||||
meta: {
|
||||
i18nKey: "dashboardNew",
|
||||
@ -54,26 +58,26 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
path: "",
|
||||
redirect: "/dashboard/:layerId/:entity/:name",
|
||||
name: "Create",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
meta: {
|
||||
notShow: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "CreateChild",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:name/tab/:activeTabIndex",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "CreateActiveTabIndex",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "View",
|
||||
redirect: "/dashboard/:layerId/:entity/:serviceId/:name",
|
||||
meta: {
|
||||
@ -82,12 +86,12 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewChild",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:name/tab/:activeTabIndex",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewActiveTabIndex",
|
||||
},
|
||||
],
|
||||
@ -95,20 +99,20 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "",
|
||||
redirect: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
name: "ViewServiceRelation",
|
||||
component: Edit,
|
||||
name: "ServiceRelations",
|
||||
meta: {
|
||||
notShow: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewServiceRelation",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name/tab/:activeTabIndex",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewServiceRelationActiveTabIndex",
|
||||
},
|
||||
],
|
||||
@ -116,20 +120,20 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "",
|
||||
redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
name: "ViewPod",
|
||||
component: Edit,
|
||||
name: "Pods",
|
||||
meta: {
|
||||
notShow: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewPod",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name/tab/:activeTabIndex",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewPodActiveTabIndex",
|
||||
},
|
||||
],
|
||||
@ -137,20 +141,20 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "",
|
||||
redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
name: "ViewProcess",
|
||||
component: Edit,
|
||||
name: "Processes",
|
||||
meta: {
|
||||
notShow: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewProcess",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name/tab/:activeTabIndex",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewProcessActiveTabIndex",
|
||||
},
|
||||
],
|
||||
@ -158,20 +162,20 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "",
|
||||
redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
name: "PodRelation",
|
||||
component: Edit,
|
||||
name: "PodRelations",
|
||||
meta: {
|
||||
notShow: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewPodRelation",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name/tab/:activeTabIndex",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewPodRelationActiveTabIndex",
|
||||
},
|
||||
],
|
||||
@ -180,25 +184,25 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
path: "",
|
||||
redirect:
|
||||
"/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
name: "ProcessRelation",
|
||||
component: Edit,
|
||||
name: "ProcessRelations",
|
||||
meta: {
|
||||
notShow: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewProcessRelation",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name/tab/:activeTabIndex",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewProcessRelationActiveTabIndex",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name/duration/:duration",
|
||||
component: () => import("@/views/dashboard/Edit.vue"),
|
||||
component: Edit,
|
||||
name: "ViewProcessRelationDuration",
|
||||
},
|
||||
],
|
||||
@ -206,14 +210,14 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "",
|
||||
name: "Widget",
|
||||
component: () => import("@/views/dashboard/Widget.vue"),
|
||||
component: Widget,
|
||||
meta: {
|
||||
notShow: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/page/:layer/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:config/:duration?",
|
||||
component: () => import("@/views/dashboard/Widget.vue"),
|
||||
component: Widget,
|
||||
name: "ViewWidget",
|
||||
},
|
||||
],
|
||||
|
@ -21,6 +21,7 @@ import { routesMarketplace } from "./marketplace";
|
||||
import { routesAlarm } from "./alarm";
|
||||
import routesLayers from "./layer";
|
||||
import { routesSettings } from "./settings";
|
||||
import { routesNotFound } from "./notFound";
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
...routesMarketplace,
|
||||
@ -28,6 +29,7 @@ const routes: RouteRecordRaw[] = [
|
||||
...routesAlarm,
|
||||
...routesDashboard,
|
||||
...routesSettings,
|
||||
...routesNotFound,
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
@ -35,19 +37,27 @@ const router = createRouter({
|
||||
routes,
|
||||
});
|
||||
|
||||
(window as any).axiosCancel = [];
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
router.beforeEach((to, _, next) => {
|
||||
// const token = window.localStorage.getItem("skywalking-authority");
|
||||
if ((window as any).axiosCancel.length !== 0) {
|
||||
for (const func of (window as any).axiosCancel) {
|
||||
setTimeout(func(), 0);
|
||||
}
|
||||
(window as any).axiosCancel = [];
|
||||
}
|
||||
|
||||
if (to.path === "/") {
|
||||
const defaultPath = (routesLayers[0] && routesLayers[0].children[0].path) || "";
|
||||
let defaultPath = "";
|
||||
for (const route of routesLayers) {
|
||||
for (const child of route.children) {
|
||||
if (child.meta.activate) {
|
||||
defaultPath = child.path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (defaultPath) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!defaultPath) {
|
||||
defaultPath = "/marketplace";
|
||||
}
|
||||
|
||||
next({ path: defaultPath });
|
||||
} else {
|
||||
next();
|
||||
|
@ -17,6 +17,7 @@
|
||||
import Layout from "@/layout/Index.vue";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import type { MenuOptions } from "@/types/app";
|
||||
import Layer from "@/views/Layer.vue";
|
||||
|
||||
function layerDashboards() {
|
||||
const appStore = useAppStoreWithOut();
|
||||
@ -47,13 +48,13 @@ function layerDashboards() {
|
||||
descKey: child.descKey,
|
||||
i18nKey: child.i18nKey,
|
||||
},
|
||||
component: () => import("@/views/Layer.vue"),
|
||||
component: Layer,
|
||||
};
|
||||
route.children.push(d);
|
||||
const tab = {
|
||||
name: `${child.name}ActiveTabIndex`,
|
||||
path: `/${child.name}/tab/:activeTabIndex`,
|
||||
component: () => import("@/views/Layer.vue"),
|
||||
path: `/${child.path}/tab/:activeTabIndex`,
|
||||
component: Layer,
|
||||
meta: {
|
||||
notShow: true,
|
||||
layer: child.layer,
|
||||
@ -74,7 +75,7 @@ function layerDashboards() {
|
||||
descKey: item.descKey,
|
||||
i18nKey: item.i18nKey,
|
||||
},
|
||||
component: () => import("@/views/Layer.vue"),
|
||||
component: Layer,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
import type { RouteRecordRaw } from "vue-router";
|
||||
import Layout from "@/layout/Index.vue";
|
||||
import Marketplace from "@/views/Marketplace.vue";
|
||||
|
||||
export const routesMarketplace: Array<RouteRecordRaw> = [
|
||||
{
|
||||
@ -33,7 +34,7 @@ export const routesMarketplace: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "/marketplace",
|
||||
name: "MenusManagement",
|
||||
component: () => import("@/views/Marketplace.vue"),
|
||||
component: Marketplace,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
26
src/router/notFound.ts
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import type { RouteRecordRaw } from "vue-router";
|
||||
import NotFound from "@/views/NotFound.vue";
|
||||
|
||||
export const routesNotFound: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "/:pathMatch(.*)*",
|
||||
name: "NotFound",
|
||||
component: NotFound,
|
||||
},
|
||||
];
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
import type { RouteRecordRaw } from "vue-router";
|
||||
import Layout from "@/layout/Index.vue";
|
||||
import Settings from "@/views/Settings.vue";
|
||||
|
||||
export const routesSettings: Array<RouteRecordRaw> = [
|
||||
{
|
||||
@ -32,8 +33,8 @@ export const routesSettings: Array<RouteRecordRaw> = [
|
||||
children: [
|
||||
{
|
||||
path: "/settings",
|
||||
name: "Settings",
|
||||
component: () => import("@/views/Settings.vue"),
|
||||
name: "ViewSettings",
|
||||
component: Settings,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -14,13 +14,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { WidgetType } from "@/views/dashboard/data";
|
||||
|
||||
export const NewControl = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 24,
|
||||
h: 12,
|
||||
i: "0",
|
||||
type: "Widget",
|
||||
type: WidgetType.Widget,
|
||||
};
|
||||
export const TextConfig = {
|
||||
fontColor: "white",
|
||||
@ -39,17 +41,20 @@ export const TimeRangeConfig = {
|
||||
};
|
||||
|
||||
export const ControlsTypes = [
|
||||
"Trace",
|
||||
"Profile",
|
||||
"Log",
|
||||
"DemandLog",
|
||||
"Ebpf",
|
||||
"NetworkProfiling",
|
||||
"ThirdPartyApp",
|
||||
"ContinuousProfiling",
|
||||
"TaskTimeline",
|
||||
WidgetType.Trace,
|
||||
WidgetType.Profile,
|
||||
WidgetType.Log,
|
||||
WidgetType.DemandLog,
|
||||
WidgetType.Ebpf,
|
||||
WidgetType.NetworkProfiling,
|
||||
WidgetType.AsyncProfiling,
|
||||
WidgetType.ThirdPartyApp,
|
||||
WidgetType.ContinuousProfiling,
|
||||
WidgetType.TaskTimeline,
|
||||
];
|
||||
export enum EBPFProfilingTriggerType {
|
||||
FIXED_TIME = "FIXED_TIME",
|
||||
CONTINUOUS_PROFILING = "CONTINUOUS_PROFILING",
|
||||
}
|
||||
|
||||
export const EndpointsTopNDefault = 20;
|
||||
|
@ -17,8 +17,8 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import type { Alarm } from "@/types/alarm";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
|
||||
interface AlarmState {
|
||||
loading: boolean;
|
||||
@ -35,16 +35,24 @@ export const alarmStore = defineStore({
|
||||
}),
|
||||
actions: {
|
||||
async getAlarms(params: Recordable) {
|
||||
const res: AxiosResponse = await graphql.query("queryAlarms").params(params);
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
this.loading = true;
|
||||
const res = await graphql.query("queryAlarms").params(params);
|
||||
this.loading = false;
|
||||
if (res.errors) {
|
||||
return res;
|
||||
}
|
||||
if (res.data.data.getAlarm.items) {
|
||||
this.alarms = res.data.data.getAlarm.items;
|
||||
this.total = res.data.data.getAlarm.total;
|
||||
if (res.data.getAlarm.items) {
|
||||
this.alarms = res.data.getAlarm.items;
|
||||
this.total = res.data.getAlarm.total;
|
||||
}
|
||||
return res.data;
|
||||
},
|
||||
async getAlarmTagKeys() {
|
||||
return await graphql.query("queryAlarmTagKeys").params({ duration: useAppStoreWithOut().durationTime });
|
||||
},
|
||||
async getAlarmTagValues(tagKey: string) {
|
||||
return await graphql.query("queryAlarmTagValues").params({ tagKey, duration: useAppStoreWithOut().durationTime });
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -19,10 +19,10 @@ import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import type { Duration, DurationTime } from "@/types/app";
|
||||
import getLocalTime from "@/utils/localtime";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import dateFormatStep, { dateFormatTime } from "@/utils/dateFormat";
|
||||
import { TimeType } from "@/constants/data";
|
||||
import type { MenuOptions, SubItem } from "@/types/app";
|
||||
import { Themes } from "@/constants/data";
|
||||
/*global Nullable*/
|
||||
interface AppState {
|
||||
durationRow: Recordable;
|
||||
@ -36,6 +36,7 @@ interface AppState {
|
||||
isMobile: boolean;
|
||||
reloadTimer: Nullable<IntervalHandle>;
|
||||
allMenus: MenuOptions[];
|
||||
theme: string;
|
||||
}
|
||||
|
||||
export const appStore = defineStore({
|
||||
@ -56,6 +57,7 @@ export const appStore = defineStore({
|
||||
isMobile: false,
|
||||
reloadTimer: null,
|
||||
allMenus: [],
|
||||
theme: Themes.Dark,
|
||||
}),
|
||||
getters: {
|
||||
duration(): Duration {
|
||||
@ -115,17 +117,14 @@ export const appStore = defineStore({
|
||||
actions: {
|
||||
setDuration(data: Duration): void {
|
||||
this.durationRow = data;
|
||||
if ((window as any).axiosCancel.length !== 0) {
|
||||
for (const event of (window as any).axiosCancel) {
|
||||
setTimeout(event(), 0);
|
||||
}
|
||||
(window as any).axiosCancel = [];
|
||||
}
|
||||
this.runEventStack();
|
||||
},
|
||||
updateDurationRow(data: Duration) {
|
||||
this.durationRow = data;
|
||||
},
|
||||
setTheme(data: string) {
|
||||
this.theme = data;
|
||||
},
|
||||
setUTC(utcHour: number, utcMin: number): void {
|
||||
this.runEventStack();
|
||||
this.utcMin = utcMin;
|
||||
@ -179,11 +178,11 @@ export const appStore = defineStore({
|
||||
});
|
||||
},
|
||||
async queryOAPTimeInfo() {
|
||||
const res: AxiosResponse = await graphql.query("queryOAPTimeInfo").params({});
|
||||
if (res.data.errors) {
|
||||
const res = await graphql.query("queryOAPTimeInfo").params({});
|
||||
if (res.errors) {
|
||||
this.utc = -(new Date().getTimezoneOffset() / 60) + ":0";
|
||||
} else {
|
||||
this.utc = res.data.data.getTimeInfo.timezone / 100 + ":0";
|
||||
this.utc = res.data.getTimeInfo.timezone / 100 + ":0";
|
||||
}
|
||||
const utcArr = this.utc.split(":");
|
||||
this.utcHour = isNaN(Number(utcArr[0])) ? 0 : Number(utcArr[0]);
|
||||
@ -191,21 +190,21 @@ export const appStore = defineStore({
|
||||
|
||||
return res.data;
|
||||
},
|
||||
async fetchVersion(): Promise<void> {
|
||||
const res: AxiosResponse = await graphql.query("queryOAPVersion").params({});
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
async fetchVersion() {
|
||||
const res = await graphql.query("queryOAPVersion").params({});
|
||||
if (res.errors) {
|
||||
return res;
|
||||
}
|
||||
this.version = res.data.data.version;
|
||||
this.version = res.data.version;
|
||||
return res.data;
|
||||
},
|
||||
async queryMenuItems() {
|
||||
const res: AxiosResponse = await graphql.query("queryMenuItems").params({});
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
const res = await graphql.query("queryMenuItems").params({});
|
||||
if (res.errors) {
|
||||
return res;
|
||||
}
|
||||
|
||||
return res.data.data;
|
||||
return res.data;
|
||||
},
|
||||
setReloadTimer(timer: IntervalHandle) {
|
||||
this.reloadTimer = timer;
|
||||
|
138
src/store/modules/async-profiling.ts
Normal file
@ -0,0 +1,138 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { defineStore } from "pinia";
|
||||
import type {
|
||||
AsyncProfilingTask,
|
||||
AsyncProfileTaskCreationRequest,
|
||||
AsyncProfilerStackElement,
|
||||
AsyncProfilerTaskProgress,
|
||||
} from "@/types/async-profiling";
|
||||
import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import type { Instance } from "@/types/selector";
|
||||
|
||||
interface AsyncProfilingState {
|
||||
taskList: Array<Recordable<AsyncProfilingTask>>;
|
||||
selectedTask: Recordable<AsyncProfilingTask>;
|
||||
taskProgress: Recordable<AsyncProfilerTaskProgress>;
|
||||
instances: Instance[];
|
||||
analyzeTrees: AsyncProfilerStackElement[];
|
||||
loadingTree: boolean;
|
||||
loadingTasks: boolean;
|
||||
}
|
||||
|
||||
export const asyncProfilingStore = defineStore({
|
||||
id: "asyncProfiling",
|
||||
state: (): AsyncProfilingState => ({
|
||||
taskList: [],
|
||||
selectedTask: {},
|
||||
taskProgress: {},
|
||||
instances: [],
|
||||
analyzeTrees: [],
|
||||
loadingTree: false,
|
||||
loadingTasks: false,
|
||||
}),
|
||||
actions: {
|
||||
setSelectedTask(task: Recordable<AsyncProfilingTask>) {
|
||||
this.selectedTask = task || {};
|
||||
},
|
||||
setAnalyzeTrees(tree: AsyncProfilerStackElement[]) {
|
||||
this.analyzeTrees = tree;
|
||||
},
|
||||
async getTaskList() {
|
||||
const selectorStore = useSelectorStore();
|
||||
this.loadingTasks = true;
|
||||
const response = await graphql.query("getAsyncTaskList").params({
|
||||
request: {
|
||||
serviceId: selectorStore.currentService.id,
|
||||
limit: 10000,
|
||||
},
|
||||
});
|
||||
this.loadingTasks = false;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.taskList = response.data.asyncTaskList.tasks || [];
|
||||
this.selectedTask = this.taskList[0] || {};
|
||||
this.setAnalyzeTrees([]);
|
||||
this.setSelectedTask(this.selectedTask);
|
||||
if (!this.taskList.length) {
|
||||
return response;
|
||||
}
|
||||
return response;
|
||||
},
|
||||
async getTaskLogs(param: { taskID: string }) {
|
||||
const response = await graphql.query("getAsyncProfileTaskProcess").params(param);
|
||||
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.taskProgress = response.data.taskProgress;
|
||||
return response;
|
||||
},
|
||||
async getServiceInstances(param: { serviceId: string; isRelation: boolean }) {
|
||||
if (!param.serviceId) {
|
||||
return null;
|
||||
}
|
||||
const response = await graphql.query("queryInstances").params({
|
||||
serviceId: param.serviceId,
|
||||
duration: useAppStoreWithOut().durationTime,
|
||||
});
|
||||
if (!response.errors) {
|
||||
this.instances = (response.data.pods || []).map((d: Instance) => {
|
||||
d.value = d.id || "";
|
||||
return d;
|
||||
});
|
||||
}
|
||||
return response;
|
||||
},
|
||||
async createTask(param: AsyncProfileTaskCreationRequest) {
|
||||
const response = await graphql.query("saveAsyncProfileTask").params({ asyncProfilerTaskCreationRequest: param });
|
||||
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.getTaskList();
|
||||
return response;
|
||||
},
|
||||
async getAsyncProfilingAnalyze(params: { taskId: string; instanceIds: Array<string>; eventType: string }) {
|
||||
if (!params.instanceIds.length) {
|
||||
return new Promise((resolve) => resolve({}));
|
||||
}
|
||||
this.loadingTree = true;
|
||||
const response = await graphql.query("getAsyncProfileAnalyze").params({ request: params });
|
||||
this.loadingTree = false;
|
||||
if (response.errors) {
|
||||
this.analyzeTrees = [];
|
||||
return response;
|
||||
}
|
||||
const { analysisResult } = response.data;
|
||||
if (!analysisResult) {
|
||||
this.analyzeTrees = [];
|
||||
return response;
|
||||
}
|
||||
this.analyzeTrees = [analysisResult.tree];
|
||||
return response;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export function useAsyncProfilingStore(): Recordable {
|
||||
return asyncProfilingStore(store);
|
||||
}
|
@ -21,7 +21,6 @@ import type { Instance } from "@/types/selector";
|
||||
import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import type { MonitorInstance, MonitorProcess } from "@/types/continous-profiling";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import { dateFormat } from "@/utils/dateFormat";
|
||||
|
||||
interface ContinousProfilingState {
|
||||
@ -84,37 +83,37 @@ export const continousProfilingStore = defineStore({
|
||||
checkItems: CheckItems[];
|
||||
}[],
|
||||
) {
|
||||
const res: AxiosResponse = await graphql.query("editStrategy").params({
|
||||
const response = await graphql.query("editStrategy").params({
|
||||
request: {
|
||||
serviceId,
|
||||
targets,
|
||||
},
|
||||
});
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getStrategyList(params: { serviceId: string }) {
|
||||
if (!params.serviceId) {
|
||||
return new Promise((resolve) => resolve({}));
|
||||
}
|
||||
this.policyLoading = true;
|
||||
const res: AxiosResponse = await graphql.query("getStrategyList").params(params);
|
||||
const response = await graphql.query("getStrategyList").params(params);
|
||||
|
||||
this.policyLoading = false;
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
const list = res.data.data.strategyList || [];
|
||||
const list = response.data.strategyList || [];
|
||||
if (!list.length) {
|
||||
this.taskList = [];
|
||||
this.instances = [];
|
||||
this.instance = null;
|
||||
}
|
||||
const arr = list.length ? res.data.data.strategyList : [{ type: "", checkItems: [{ type: "" }] }];
|
||||
const arr = list.length ? response.data.strategyList : [{ type: "", checkItems: [{ type: "" }] }];
|
||||
this.strategyList = arr.map((d: StrategyItem, index: number) => {
|
||||
return {
|
||||
...d,
|
||||
@ -123,25 +122,25 @@ export const continousProfilingStore = defineStore({
|
||||
});
|
||||
this.setSelectedStrategy(this.strategyList[0]);
|
||||
if (!this.selectedStrategy.type) {
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
this.getMonitoringInstances(params.serviceId);
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getMonitoringInstances(serviceId: string): Promise<Nullable<AxiosResponse>> {
|
||||
async getMonitoringInstances(serviceId: string) {
|
||||
this.instancesLoading = true;
|
||||
if (!serviceId) {
|
||||
return null;
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("getMonitoringInstances").params({
|
||||
const response = await graphql.query("getMonitoringInstances").params({
|
||||
serviceId,
|
||||
target: this.selectedStrategy.type,
|
||||
});
|
||||
this.instancesLoading = false;
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.instances = (res.data.data.instances || [])
|
||||
this.instances = (response.data.instances || [])
|
||||
.map((d: MonitorInstance) => {
|
||||
const processes = (d.processes || [])
|
||||
.sort((c: MonitorProcess, d: MonitorProcess) => d.lastTriggerTimestamp - c.lastTriggerTimestamp)
|
||||
@ -161,7 +160,7 @@ export const continousProfilingStore = defineStore({
|
||||
})
|
||||
.sort((a: MonitorInstance, b: MonitorInstance) => b.lastTriggerTimestamp - a.lastTriggerTimestamp);
|
||||
this.instance = this.instances[0] || null;
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -18,14 +18,12 @@ import { defineStore } from "pinia";
|
||||
import { store } from "@/store";
|
||||
import type { LayoutConfig } from "@/types/dashboard";
|
||||
import graphql from "@/graphql";
|
||||
import query from "@/graphql/fetch";
|
||||
import fetchQuery from "@/graphql/fetch";
|
||||
import type { DashboardItem } from "@/types/dashboard";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { NewControl, TextConfig, TimeRangeConfig, ControlsTypes } from "../data";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { EntityType, MetricModes } from "@/views/dashboard/data";
|
||||
import { EntityType, WidgetType } from "@/views/dashboard/data";
|
||||
interface DashboardState {
|
||||
showConfig: boolean;
|
||||
layout: LayoutConfig[];
|
||||
@ -78,7 +76,7 @@ export const dashboardStore = defineStore({
|
||||
setCurrentDashboard(item: DashboardItem) {
|
||||
this.currentDashboard = item;
|
||||
},
|
||||
addControl(type: string) {
|
||||
addControl(type: WidgetType) {
|
||||
const arr = this.layout.map((d: Recordable) => Number(d.i));
|
||||
let index = String(Math.max(...arr) + 1);
|
||||
if (!this.layout.length) {
|
||||
@ -89,14 +87,8 @@ export const dashboardStore = defineStore({
|
||||
i: index,
|
||||
id: index,
|
||||
type,
|
||||
metricTypes: [""],
|
||||
metrics: [""],
|
||||
};
|
||||
|
||||
if (type === "Widget") {
|
||||
newItem.metricMode = MetricModes.Expression;
|
||||
}
|
||||
if (type === "Tab") {
|
||||
if (type === WidgetType.Tab) {
|
||||
newItem.h = 36;
|
||||
newItem.activedTabIndex = 0;
|
||||
newItem.children = [
|
||||
@ -110,7 +102,7 @@ export const dashboardStore = defineStore({
|
||||
},
|
||||
];
|
||||
}
|
||||
if (type === "Topology") {
|
||||
if (type === WidgetType.Topology) {
|
||||
newItem.h = 36;
|
||||
newItem.graph = {
|
||||
showDepth: true,
|
||||
@ -120,11 +112,11 @@ export const dashboardStore = defineStore({
|
||||
if (ControlsTypes.includes(type)) {
|
||||
newItem.h = 36;
|
||||
}
|
||||
if (type === "Text") {
|
||||
if (type === WidgetType.Text) {
|
||||
newItem.h = 6;
|
||||
newItem.graph = TextConfig;
|
||||
}
|
||||
if (type === "TimeRange") {
|
||||
if (type === WidgetType.TimeRange) {
|
||||
newItem.w = 8;
|
||||
newItem.h = 6;
|
||||
newItem.graph = TimeRangeConfig;
|
||||
@ -149,7 +141,7 @@ export const dashboardStore = defineStore({
|
||||
};
|
||||
this.layout[idx].children?.push(i);
|
||||
},
|
||||
addTabControls(type: string) {
|
||||
addTabControls(type: WidgetType) {
|
||||
const activedGridItem = this.activedGridItem.split("-")[0];
|
||||
const idx = this.layout.findIndex((d: LayoutConfig) => d.i === activedGridItem);
|
||||
if (idx < 0) {
|
||||
@ -168,13 +160,8 @@ export const dashboardStore = defineStore({
|
||||
i: index,
|
||||
id,
|
||||
type,
|
||||
metricTypes: [""],
|
||||
metrics: [""],
|
||||
};
|
||||
if (type === "Widget") {
|
||||
newItem.metricMode = MetricModes.Expression;
|
||||
}
|
||||
if (type === "Topology") {
|
||||
if (type === WidgetType.Topology) {
|
||||
newItem.h = 32;
|
||||
newItem.graph = {
|
||||
showDepth: true,
|
||||
@ -183,11 +170,11 @@ export const dashboardStore = defineStore({
|
||||
if (ControlsTypes.includes(type)) {
|
||||
newItem.h = 32;
|
||||
}
|
||||
if (type === "Text") {
|
||||
if (type === WidgetType.Text) {
|
||||
newItem.h = 6;
|
||||
newItem.graph = TextConfig;
|
||||
}
|
||||
if (type === "TimeRange") {
|
||||
if (type === WidgetType.TimeRange) {
|
||||
newItem.w = 8;
|
||||
newItem.h = 6;
|
||||
newItem.graph = TextConfig;
|
||||
@ -291,7 +278,7 @@ export const dashboardStore = defineStore({
|
||||
},
|
||||
setWidget(param: LayoutConfig) {
|
||||
for (let i = 0; i < this.layout.length; i++) {
|
||||
if (this.layout[i].type === "Tab") {
|
||||
if (this.layout[i].type === WidgetType.Tab) {
|
||||
if ((this.layout[i].children || []).length) {
|
||||
for (const child of this.layout[i].children || []) {
|
||||
if (child.children && child.children.length) {
|
||||
@ -311,43 +298,24 @@ export const dashboardStore = defineStore({
|
||||
}
|
||||
}
|
||||
},
|
||||
async fetchMetricType(item: string) {
|
||||
const res: AxiosResponse = await graphql.query("queryTypeOfMetrics").params({ name: item });
|
||||
|
||||
return res.data;
|
||||
},
|
||||
async getTypeOfMQE(expression: string) {
|
||||
const res: AxiosResponse = await graphql.query("getTypeOfMQE").params({ expression });
|
||||
|
||||
return res.data;
|
||||
},
|
||||
async fetchMetricList(regex: string) {
|
||||
const res: AxiosResponse = await graphql.query("queryMetrics").params({ regex });
|
||||
|
||||
return res.data;
|
||||
},
|
||||
async fetchMetricValue(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
|
||||
const res: AxiosResponse = await query(param);
|
||||
return res.data;
|
||||
return await fetchQuery(param);
|
||||
},
|
||||
async fetchTemplates() {
|
||||
const res: AxiosResponse = await graphql.query("getTemplates").params({});
|
||||
const res = await graphql.query("getTemplates").params({});
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (res.errors) {
|
||||
return res;
|
||||
}
|
||||
const data = res.data.data.getAllTemplates;
|
||||
const data = res.data.getAllTemplates;
|
||||
let list = [];
|
||||
for (const t of data) {
|
||||
const c = JSON.parse(t.configuration);
|
||||
const key = [c.layer, c.entity, c.name].join("_");
|
||||
|
||||
list.push({
|
||||
...c,
|
||||
id: t.id,
|
||||
layer: c.layer,
|
||||
entity: c.entity,
|
||||
name: c.name,
|
||||
isRoot: c.isRoot,
|
||||
children: undefined,
|
||||
});
|
||||
sessionStorage.setItem(key, JSON.stringify({ id: t.id, configuration: c }));
|
||||
}
|
||||
@ -386,20 +354,20 @@ export const dashboardStore = defineStore({
|
||||
this.dashboards = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
|
||||
},
|
||||
async updateDashboard(setting: { id: string; configuration: string }) {
|
||||
const res: AxiosResponse = await graphql.query("updateTemplate").params({
|
||||
const resp = await graphql.query("updateTemplate").params({
|
||||
setting,
|
||||
});
|
||||
if (res.data.errors) {
|
||||
ElMessage.error(res.data.errors);
|
||||
return res.data;
|
||||
if (resp.errors) {
|
||||
ElMessage.error(resp.errors);
|
||||
return resp;
|
||||
}
|
||||
const json = res.data.data.changeTemplate;
|
||||
const json = resp.data.changeTemplate;
|
||||
if (!json.status) {
|
||||
ElMessage.error(json.message);
|
||||
return res.data;
|
||||
return resp;
|
||||
}
|
||||
ElMessage.success("Saved successfully");
|
||||
return res.data;
|
||||
return resp;
|
||||
},
|
||||
async saveDashboard() {
|
||||
if (!this.currentDashboard?.name) {
|
||||
@ -428,20 +396,19 @@ export const dashboardStore = defineStore({
|
||||
d.layer === this.currentDashboard?.layer,
|
||||
);
|
||||
if (index > -1) {
|
||||
const { t } = useI18n();
|
||||
ElMessage.error(t("nameError"));
|
||||
ElMessage.error("The dashboard name cannot be duplicate");
|
||||
return;
|
||||
}
|
||||
res = await graphql.query("addNewTemplate").params({ setting: { configuration: JSON.stringify(c) } });
|
||||
|
||||
json = res.data.data.addTemplate;
|
||||
json = res.data.addTemplate;
|
||||
if (!json.status) {
|
||||
ElMessage.error(json.message);
|
||||
}
|
||||
}
|
||||
if (res.data.errors || res.errors) {
|
||||
ElMessage.error(res.data.errors);
|
||||
return res.data;
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
return res;
|
||||
}
|
||||
if (!json.status) {
|
||||
return json;
|
||||
@ -463,16 +430,16 @@ export const dashboardStore = defineStore({
|
||||
return json;
|
||||
},
|
||||
async deleteDashboard() {
|
||||
const res: AxiosResponse = await graphql.query("removeTemplate").params({ id: this.currentDashboard?.id });
|
||||
const res = await graphql.query("removeTemplate").params({ id: this.currentDashboard?.id });
|
||||
|
||||
if (res.data.errors) {
|
||||
ElMessage.error(res.data.errors);
|
||||
return res.data;
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
return res;
|
||||
}
|
||||
const json = res.data.data.disableTemplate;
|
||||
const json = res.data.disableTemplate;
|
||||
if (!json.status) {
|
||||
ElMessage.error(json.message);
|
||||
return res.data;
|
||||
return res;
|
||||
}
|
||||
this.dashboards = this.dashboards.filter((d: Recordable) => d.id !== this.currentDashboard?.id);
|
||||
const key = [this.currentDashboard?.layer, this.currentDashboard?.entity, this.currentDashboard?.name].join("_");
|
||||
|
@ -18,7 +18,6 @@ import { defineStore } from "pinia";
|
||||
import type { Instance } from "@/types/selector";
|
||||
import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import type { Conditions, Log } from "@/types/demand-log";
|
||||
@ -60,16 +59,16 @@ export const demandLogStore = defineStore({
|
||||
},
|
||||
async getInstances(id: string) {
|
||||
const serviceId = this.selectorStore.currentService ? this.selectorStore.currentService.id : id;
|
||||
const res: AxiosResponse = await graphql.query("queryInstances").params({
|
||||
const response = await graphql.query("queryInstances").params({
|
||||
serviceId,
|
||||
duration: useAppStoreWithOut().durationTime,
|
||||
});
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.instances = res.data.data.pods || [];
|
||||
return res.data;
|
||||
this.instances = response.data.pods || [];
|
||||
return response;
|
||||
},
|
||||
async getContainers(serviceInstanceId: string) {
|
||||
if (!serviceInstanceId) {
|
||||
@ -78,35 +77,35 @@ export const demandLogStore = defineStore({
|
||||
const condition = {
|
||||
serviceInstanceId,
|
||||
};
|
||||
const res: AxiosResponse = await graphql.query("fetchContainers").params({ condition });
|
||||
const response = await graphql.query("fetchContainers").params({ condition });
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
if (res.data.data.containers.errorReason) {
|
||||
if (response.data.containers.errorReason) {
|
||||
this.containers = [{ label: "", value: "" }];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
this.containers = res.data.data.containers.containers.map((d: string) => {
|
||||
this.containers = response.data.containers.containers.map((d: string) => {
|
||||
return { label: d, value: d };
|
||||
});
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getDemandLogs() {
|
||||
this.loadLogs = true;
|
||||
const res: AxiosResponse = await graphql.query("fetchDemandPodLogs").params({ condition: this.conditions });
|
||||
const response = await graphql.query("fetchDemandPodLogs").params({ condition: this.conditions });
|
||||
this.loadLogs = false;
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
if (res.data.data.logs.errorReason) {
|
||||
this.setLogs([], res.data.data.logs.errorReason);
|
||||
return res.data;
|
||||
if (response.data.logs.errorReason) {
|
||||
this.setLogs([], response.data.logs.errorReason);
|
||||
return response;
|
||||
}
|
||||
this.total = res.data.data.logs.logs.length;
|
||||
const logs = res.data.data.logs.logs.map((d: Log) => d.content).join("\n");
|
||||
this.total = response.data.logs.logs.length;
|
||||
const logs = response.data.logs.logs.map((d: Log) => d.content).join("\n");
|
||||
this.setLogs(logs);
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -19,7 +19,6 @@ import type { Option } from "@/types/app";
|
||||
import type { EBPFTaskCreationRequest, EBPFProfilingSchedule, EBPFTaskList, AnalyzationTrees } from "@/types/ebpf";
|
||||
import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import { EBPFProfilingTriggerType } from "../data";
|
||||
interface EbpfState {
|
||||
taskList: Array<Recordable<EBPFTaskList>>;
|
||||
@ -57,70 +56,70 @@ export const ebpfStore = defineStore({
|
||||
this.analyzeTrees = tree;
|
||||
},
|
||||
async getCreateTaskData(serviceId: string) {
|
||||
const res: AxiosResponse = await graphql.query("getCreateTaskData").params({ serviceId });
|
||||
const response = await graphql.query("getCreateTaskData").params({ serviceId });
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
const json = res.data.data.createTaskData;
|
||||
const json = response.data.createTaskData;
|
||||
this.couldProfiling = json.couldProfiling || false;
|
||||
this.labels = json.processLabels.map((d: string) => {
|
||||
return { label: d, value: d };
|
||||
});
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async createTask(param: EBPFTaskCreationRequest) {
|
||||
const res: AxiosResponse = await graphql.query("saveEBPFTask").params({ request: param });
|
||||
const response = await graphql.query("saveEBPFTask").params({ request: param });
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.getTaskList({
|
||||
serviceId: param.serviceId,
|
||||
targets: ["ON_CPU", "OFF_CPU"],
|
||||
triggerType: EBPFProfilingTriggerType.FIXED_TIME,
|
||||
});
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getTaskList(params: { serviceId: string; targets: string[] }) {
|
||||
if (!params.serviceId) {
|
||||
return new Promise((resolve) => resolve({}));
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("getEBPFTasks").params(params);
|
||||
const response = await graphql.query("getEBPFTasks").params(params);
|
||||
|
||||
this.ebpfTips = "";
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.taskList = res.data.data.queryEBPFTasks || [];
|
||||
this.taskList = response.data.queryEBPFTasks || [];
|
||||
this.selectedTask = this.taskList[0] || {};
|
||||
this.setSelectedTask(this.selectedTask);
|
||||
if (!this.taskList.length) {
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
this.getEBPFSchedules({ taskId: String(this.taskList[0].taskId) });
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getEBPFSchedules(params: { taskId: string }) {
|
||||
if (!params.taskId) {
|
||||
return new Promise((resolve) => resolve({}));
|
||||
}
|
||||
|
||||
const res: AxiosResponse = await graphql.query("getEBPFSchedules").params({ ...params });
|
||||
const response = await graphql.query("getEBPFSchedules").params({ ...params });
|
||||
|
||||
if (res.data.errors) {
|
||||
if (response.errors) {
|
||||
this.eBPFSchedules = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
this.ebpfTips = "";
|
||||
const { eBPFSchedules } = res.data.data;
|
||||
const { eBPFSchedules } = response.data;
|
||||
|
||||
this.eBPFSchedules = eBPFSchedules;
|
||||
if (!eBPFSchedules.length) {
|
||||
this.eBPFSchedules = [];
|
||||
this.analyzeTrees = [];
|
||||
}
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getEBPFAnalyze(params: {
|
||||
scheduleIdList: string[];
|
||||
@ -134,24 +133,24 @@ export const ebpfStore = defineStore({
|
||||
if (!params.timeRanges.length) {
|
||||
return new Promise((resolve) => resolve({}));
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("getEBPFResult").params(params);
|
||||
const response = await graphql.query("getEBPFResult").params(params);
|
||||
|
||||
if (res.data.errors) {
|
||||
if (response.errors) {
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
const { analysisEBPFResult } = res.data.data;
|
||||
const { analysisEBPFResult } = response.data;
|
||||
this.ebpfTips = analysisEBPFResult.tip;
|
||||
if (!analysisEBPFResult) {
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
if (analysisEBPFResult.tip) {
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
this.analyzeTrees = analysisEBPFResult.trees;
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -17,11 +17,11 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import type { Event, QueryEventCondition } from "@/types/events";
|
||||
import type { Instance, Endpoint } from "@/types/selector";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { EndpointsTopNDefault } from "../data";
|
||||
|
||||
interface eventState {
|
||||
loading: boolean;
|
||||
@ -46,47 +46,48 @@ export const eventStore = defineStore({
|
||||
},
|
||||
async getInstances() {
|
||||
const serviceId = useSelectorStore().currentService ? useSelectorStore().currentService.id : "";
|
||||
const res: AxiosResponse = await graphql.query("queryInstances").params({
|
||||
const response = await graphql.query("queryInstances").params({
|
||||
serviceId,
|
||||
duration: useAppStoreWithOut().durationTime,
|
||||
});
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.instances = [{ value: "", label: "All" }, ...res.data.data.pods] || [{ value: "", label: "All" }];
|
||||
return res.data;
|
||||
this.instances = [{ value: "", label: "All" }, ...response.data.pods];
|
||||
return response;
|
||||
},
|
||||
async getEndpoints(keyword: string) {
|
||||
const serviceId = useSelectorStore().currentService ? useSelectorStore().currentService.id : "";
|
||||
if (!serviceId) {
|
||||
return;
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("queryEndpoints").params({
|
||||
const response = await graphql.query("queryEndpoints").params({
|
||||
serviceId,
|
||||
duration: useAppStoreWithOut().durationTime,
|
||||
keyword: keyword || "",
|
||||
limit: EndpointsTopNDefault,
|
||||
});
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.endpoints = [{ value: "", label: "All" }, ...res.data.data.pods] || [{ value: "", label: "All" }];
|
||||
return res.data;
|
||||
this.endpoints = [{ value: "", label: "All" }, ...response.data.pods];
|
||||
return response;
|
||||
},
|
||||
async getEvents() {
|
||||
this.loading = true;
|
||||
const res: AxiosResponse = await graphql.query("queryEvents").params({
|
||||
const response = await graphql.query("queryEvents").params({
|
||||
condition: {
|
||||
...this.condition,
|
||||
time: useAppStoreWithOut().durationTime,
|
||||
},
|
||||
});
|
||||
this.loading = false;
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
if (res.data.data.fetchEvents) {
|
||||
this.events = (res.data.data.fetchEvents.events || []).map((item: Event) => {
|
||||
if (response.data.fetchEvents) {
|
||||
this.events = (response.data.fetchEvents.events || []).map((item: Event) => {
|
||||
let scope = "Service";
|
||||
if (item.source.serviceInstance) {
|
||||
scope = "ServiceInstance";
|
||||
@ -101,7 +102,7 @@ export const eventStore = defineStore({
|
||||
return item;
|
||||
});
|
||||
}
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -18,10 +18,10 @@ import { defineStore } from "pinia";
|
||||
import type { Instance, Endpoint, Service } from "@/types/selector";
|
||||
import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import { EndpointsTopNDefault } from "../data";
|
||||
|
||||
interface LogState {
|
||||
services: Service[];
|
||||
@ -61,50 +61,51 @@ export const logStore = defineStore({
|
||||
};
|
||||
},
|
||||
async getServices(layer: string) {
|
||||
const res: AxiosResponse = await graphql.query("queryServices").params({
|
||||
const response = await graphql.query("queryServices").params({
|
||||
layer,
|
||||
});
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.services = res.data.data.services;
|
||||
return res.data;
|
||||
this.services = response.data.services;
|
||||
return response;
|
||||
},
|
||||
async getInstances(id: string) {
|
||||
const serviceId = this.selectorStore.currentService ? this.selectorStore.currentService.id : id;
|
||||
const res: AxiosResponse = await graphql.query("queryInstances").params({
|
||||
const response = await graphql.query("queryInstances").params({
|
||||
serviceId,
|
||||
duration: useAppStoreWithOut().durationTime,
|
||||
});
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.instances = [{ value: "0", label: "All" }, ...res.data.data.pods] || [{ value: " 0", label: "All" }];
|
||||
return res.data;
|
||||
this.instances = [{ value: "0", label: "All" }, ...response.data.pods];
|
||||
return response;
|
||||
},
|
||||
async getEndpoints(id: string, keyword?: string) {
|
||||
const serviceId = this.selectorStore.currentService ? this.selectorStore.currentService.id : id;
|
||||
const res: AxiosResponse = await graphql.query("queryEndpoints").params({
|
||||
const response = await graphql.query("queryEndpoints").params({
|
||||
serviceId,
|
||||
duration: useAppStoreWithOut().durationTime,
|
||||
keyword: keyword || "",
|
||||
limit: EndpointsTopNDefault,
|
||||
});
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.endpoints = [{ value: "0", label: "All" }, ...res.data.data.pods] || [{ value: "0", label: "All" }];
|
||||
return res.data;
|
||||
this.endpoints = [{ value: "0", label: "All" }, ...response.data.pods];
|
||||
return response;
|
||||
},
|
||||
async getLogsByKeywords() {
|
||||
const res: AxiosResponse = await graphql.query("queryLogsByKeywords").params({});
|
||||
const response = await graphql.query("queryLogsByKeywords").params({});
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
|
||||
this.supportQueryLogsByKeywords = res.data.data.support;
|
||||
return res.data;
|
||||
this.supportQueryLogsByKeywords = response.data.support;
|
||||
return response;
|
||||
},
|
||||
async getLogs() {
|
||||
const dashboardStore = useDashboardStore();
|
||||
@ -115,39 +116,31 @@ export const logStore = defineStore({
|
||||
},
|
||||
async getServiceLogs() {
|
||||
this.loadLogs = true;
|
||||
const res: AxiosResponse = await graphql.query("queryServiceLogs").params({ condition: this.conditions });
|
||||
const response = await graphql.query("queryServiceLogs").params({ condition: this.conditions });
|
||||
this.loadLogs = false;
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
|
||||
this.logs = res.data.data.queryLogs.logs;
|
||||
return res.data;
|
||||
this.logs = response.data.queryLogs.logs;
|
||||
return response;
|
||||
},
|
||||
async getBrowserLogs() {
|
||||
this.loadLogs = true;
|
||||
const res: AxiosResponse = await graphql.query("queryBrowserErrorLogs").params({ condition: this.conditions });
|
||||
const response = await graphql.query("queryBrowserErrorLogs").params({ condition: this.conditions });
|
||||
|
||||
this.loadLogs = false;
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.logs = res.data.data.queryBrowserErrorLogs.logs;
|
||||
return res.data;
|
||||
this.logs = response.data.queryBrowserErrorLogs.logs;
|
||||
return response;
|
||||
},
|
||||
async getLogTagKeys() {
|
||||
const res: AxiosResponse = await graphql
|
||||
.query("queryLogTagKeys")
|
||||
.params({ duration: useAppStoreWithOut().durationTime });
|
||||
|
||||
return res.data;
|
||||
return await graphql.query("queryLogTagKeys").params({ duration: useAppStoreWithOut().durationTime });
|
||||
},
|
||||
async getLogTagValues(tagKey: string) {
|
||||
const res: AxiosResponse = await graphql
|
||||
.query("queryLogTagValues")
|
||||
.params({ tagKey, duration: useAppStoreWithOut().durationTime });
|
||||
|
||||
return res.data;
|
||||
return await graphql.query("queryLogTagValues").params({ tagKey, duration: useAppStoreWithOut().durationTime });
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -18,7 +18,6 @@ import { defineStore } from "pinia";
|
||||
import type { EBPFTaskList, ProcessNode } from "@/types/ebpf";
|
||||
import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import type { Call } from "@/types/topology";
|
||||
import type { LayoutConfig } from "@/types/dashboard";
|
||||
import { ElMessage } from "element-plus";
|
||||
@ -126,65 +125,65 @@ export const networkProfilingStore = defineStore({
|
||||
minDuration: number;
|
||||
}[],
|
||||
) {
|
||||
const res: AxiosResponse = await graphql.query("newNetworkProfiling").params({
|
||||
const response = await graphql.query("newNetworkProfiling").params({
|
||||
request: {
|
||||
instanceId,
|
||||
samplings: params,
|
||||
},
|
||||
});
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getTaskList(params: { serviceId: string; serviceInstanceId: string; targets: string[] }) {
|
||||
if (!params.serviceId) {
|
||||
return new Promise((resolve) => resolve({}));
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("getEBPFTasks").params(params);
|
||||
const response = await graphql.query("getEBPFTasks").params(params);
|
||||
|
||||
this.networkTip = "";
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.networkTasks = res.data.data.queryEBPFTasks || [];
|
||||
this.networkTasks = response.data.queryEBPFTasks || [];
|
||||
this.selectedNetworkTask = this.networkTasks[0] || {};
|
||||
this.setSelectedNetworkTask(this.selectedNetworkTask);
|
||||
if (!this.networkTasks.length) {
|
||||
this.nodes = [];
|
||||
this.calls = [];
|
||||
}
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async keepNetworkProfiling(taskId: string) {
|
||||
if (!taskId) {
|
||||
return new Promise((resolve) => resolve({}));
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("aliveNetworkProfiling").params({ taskId });
|
||||
const response = await graphql.query("aliveNetworkProfiling").params({ taskId });
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.aliveNetwork = res.data.data.keepEBPFNetworkProfiling.status;
|
||||
this.aliveNetwork = response.data.keepEBPFNetworkProfiling.status;
|
||||
if (!this.aliveNetwork) {
|
||||
ElMessage.warning(res.data.data.keepEBPFNetworkProfiling.errorReason);
|
||||
ElMessage.warning(response.data.keepEBPFNetworkProfiling.errorReason);
|
||||
}
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getProcessTopology(params: { duration: DurationTime; serviceInstanceId: string }) {
|
||||
this.loadNodes = true;
|
||||
const res: AxiosResponse = await graphql.query("getProcessTopology").params(params);
|
||||
const response = await graphql.query("getProcessTopology").params(params);
|
||||
this.loadNodes = false;
|
||||
if (res.data.errors) {
|
||||
if (response.errors) {
|
||||
this.nodes = [];
|
||||
this.calls = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
const { topology } = res.data.data;
|
||||
const { topology } = response.data;
|
||||
|
||||
this.setTopology(topology);
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -26,8 +26,8 @@ import type {
|
||||
import type { Trace } from "@/types/trace";
|
||||
import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { EndpointsTopNDefault } from "../data";
|
||||
|
||||
interface ProfileState {
|
||||
endpoints: Endpoint[];
|
||||
@ -80,7 +80,7 @@ export const profileStore = defineStore({
|
||||
this.analyzeTrees = [];
|
||||
},
|
||||
setCurrentSegment(segment: Trace) {
|
||||
this.currentSegment = segment;
|
||||
this.currentSegment = segment || {};
|
||||
this.segmentSpans = segment.spans || [];
|
||||
if (segment.spans) {
|
||||
this.currentSpan = segment.spans[0] || {};
|
||||
@ -93,36 +93,38 @@ export const profileStore = defineStore({
|
||||
this.highlightTop = !this.highlightTop;
|
||||
},
|
||||
async getEndpoints(serviceId: string, keyword?: string) {
|
||||
const res: AxiosResponse = await graphql.query("queryEndpoints").params({
|
||||
const response = await graphql.query("queryEndpoints").params({
|
||||
serviceId,
|
||||
duration: useAppStoreWithOut().durationTime,
|
||||
keyword: keyword || "",
|
||||
limit: EndpointsTopNDefault,
|
||||
});
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.endpoints = res.data.data.pods || [];
|
||||
return res.data;
|
||||
this.endpoints = response.data.pods || [];
|
||||
return response.data;
|
||||
},
|
||||
async getTaskEndpoints(serviceId: string, keyword?: string) {
|
||||
const res: AxiosResponse = await graphql.query("queryEndpoints").params({
|
||||
const response = await graphql.query("queryEndpoints").params({
|
||||
serviceId,
|
||||
duration: useAppStoreWithOut().durationTime,
|
||||
keyword: keyword || "",
|
||||
limit: EndpointsTopNDefault,
|
||||
});
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.taskEndpoints = [{ value: "", label: "All" }, ...res.data.data.pods];
|
||||
return res.data;
|
||||
this.taskEndpoints = [{ value: "", label: "All" }, ...response.data.pods];
|
||||
return response;
|
||||
},
|
||||
async getTaskList() {
|
||||
const res: AxiosResponse = await graphql.query("getProfileTaskList").params(this.condition);
|
||||
const response = await graphql.query("getProfileTaskList").params(this.condition);
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
const list = res.data.data.taskList || [];
|
||||
const list = response.data.taskList || [];
|
||||
this.taskList = list;
|
||||
this.currentTask = list[0] || {};
|
||||
if (!list.length) {
|
||||
@ -130,52 +132,52 @@ export const profileStore = defineStore({
|
||||
this.segmentSpans = [];
|
||||
this.analyzeTrees = [];
|
||||
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
this.getSegmentList({ taskID: list[0].id });
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getSegmentList(params: { taskID: string }) {
|
||||
if (!params.taskID) {
|
||||
return new Promise((resolve) => resolve({}));
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("getProfileTaskSegmentList").params(params);
|
||||
const response = await graphql.query("getProfileTaskSegmentList").params(params);
|
||||
|
||||
if (res.data.errors) {
|
||||
if (response.errors) {
|
||||
this.segmentList = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
const { segmentList } = res.data.data;
|
||||
const { segmentList } = response.data;
|
||||
|
||||
this.segmentList = segmentList || [];
|
||||
if (!segmentList.length) {
|
||||
this.segmentSpans = [];
|
||||
this.analyzeTrees = [];
|
||||
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
if (segmentList[0]) {
|
||||
this.currentSegment = segmentList[0];
|
||||
this.setCurrentSegment(segmentList[0]);
|
||||
this.getSegmentSpans(segmentList[0].segmentId);
|
||||
} else {
|
||||
this.currentSegment = {};
|
||||
this.setCurrentSegment({});
|
||||
}
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getSegmentSpans(params: { segmentId: string }) {
|
||||
if (!params.segmentId) {
|
||||
if (!(params && params.segmentId)) {
|
||||
return new Promise((resolve) => resolve({}));
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("queryProfileSegment").params(params);
|
||||
if (res.data.errors) {
|
||||
const response = await graphql.query("queryProfileSegment").params(params);
|
||||
if (response.errors) {
|
||||
this.segmentSpans = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
const { segment } = res.data.data;
|
||||
const { segment } = response.data;
|
||||
if (!segment) {
|
||||
this.segmentSpans = [];
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
this.segmentSpans = segment.spans.map((d: SegmentSpan) => {
|
||||
return {
|
||||
@ -186,52 +188,52 @@ export const profileStore = defineStore({
|
||||
});
|
||||
if (!(segment.spans && segment.spans.length)) {
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
const index = segment.spans.length - 1 || 0;
|
||||
this.currentSpan = segment.spans[index];
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getProfileAnalyze(params: Array<{ segmentId: string; timeRange: { start: number; end: number } }>) {
|
||||
if (!params.length) {
|
||||
return new Promise((resolve) => resolve({}));
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("getProfileAnalyze").params({ queries: params });
|
||||
const response = await graphql.query("getProfileAnalyze").params({ queries: params });
|
||||
|
||||
if (res.data.errors) {
|
||||
if (response.errors) {
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
const { analyze, tip } = res.data.data;
|
||||
const { analyze, tip } = response.data;
|
||||
if (tip) {
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
|
||||
if (!analyze) {
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
return response;
|
||||
}
|
||||
this.analyzeTrees = analyze.trees;
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async createTask(param: ProfileTaskCreationRequest) {
|
||||
const res: AxiosResponse = await graphql.query("saveProfileTask").params({ creationRequest: param });
|
||||
const response = await graphql.query("saveProfileTask").params({ creationRequest: param });
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.getTaskList();
|
||||
return res.data;
|
||||
return response;
|
||||
},
|
||||
async getTaskLogs(param: { taskID: string }) {
|
||||
const res: AxiosResponse = await graphql.query("getProfileTaskLogs").params(param);
|
||||
const response = await graphql.query("getProfileTaskLogs").params(param);
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (response.errors) {
|
||||
return response;
|
||||
}
|
||||
this.taskLogs = res.data.data.taskLogs;
|
||||
return res.data;
|
||||
this.taskLogs = response.data.taskLogs;
|
||||
return response;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -18,8 +18,8 @@ import { defineStore } from "pinia";
|
||||
import type { Service, Instance, Endpoint, Process } from "@/types/selector";
|
||||
import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { EndpointsTopNDefault } from "../data";
|
||||
interface SelectorState {
|
||||
services: Service[];
|
||||
destServices: Service[];
|
||||
@ -76,62 +76,55 @@ export const selectorStore = defineStore({
|
||||
setDestProcesses(processes: Array<Process>) {
|
||||
this.destProcesses = processes;
|
||||
},
|
||||
async fetchLayers(): Promise<AxiosResponse> {
|
||||
const res: AxiosResponse = await graphql.query("queryLayers").params({});
|
||||
|
||||
return res.data || {};
|
||||
async fetchLayers() {
|
||||
return await graphql.query("queryLayers").params({});
|
||||
},
|
||||
async fetchServices(layer: string): Promise<AxiosResponse> {
|
||||
const res: AxiosResponse = await graphql.query("queryServices").params({ layer });
|
||||
async fetchServices(layer: string) {
|
||||
const res = await graphql.query("queryServices").params({ layer });
|
||||
|
||||
if (!res.data.errors) {
|
||||
this.services = res.data.data.services || [];
|
||||
this.destServices = res.data.data.services || [];
|
||||
if (!res.errors) {
|
||||
this.services = res.data.services || [];
|
||||
this.destServices = res.data.services || [];
|
||||
}
|
||||
return res.data;
|
||||
},
|
||||
async getServiceInstances(param?: { serviceId: string; isRelation: boolean }): Promise<Nullable<AxiosResponse>> {
|
||||
async getServiceInstances(param?: { serviceId: string; isRelation: boolean }) {
|
||||
const serviceId = param ? param.serviceId : this.currentService?.id;
|
||||
if (!serviceId) {
|
||||
return null;
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("queryInstances").params({
|
||||
const resp = await graphql.query("queryInstances").params({
|
||||
serviceId,
|
||||
duration: useAppStoreWithOut().durationTime,
|
||||
});
|
||||
if (!res.data.errors) {
|
||||
if (!resp.errors) {
|
||||
if (param && param.isRelation) {
|
||||
this.destPods = res.data.data.pods || [];
|
||||
return res.data;
|
||||
this.destPods = resp.data.pods || [];
|
||||
return resp;
|
||||
}
|
||||
this.pods = res.data.data.pods || [];
|
||||
this.pods = resp.data.pods || [];
|
||||
}
|
||||
return res.data;
|
||||
return resp;
|
||||
},
|
||||
async getProcesses(param?: { instanceId: string; isRelation: boolean }): Promise<Nullable<AxiosResponse>> {
|
||||
async getProcesses(param?: { instanceId: string; isRelation: boolean }) {
|
||||
const instanceId = param ? param.instanceId : this.currentPod?.id;
|
||||
if (!instanceId) {
|
||||
return null;
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("queryProcesses").params({
|
||||
const res = await graphql.query("queryProcesses").params({
|
||||
instanceId,
|
||||
duration: useAppStoreWithOut().durationTime,
|
||||
});
|
||||
if (!res.data.errors) {
|
||||
if (!res.errors) {
|
||||
if (param && param.isRelation) {
|
||||
this.destProcesses = res.data.data.processes || [];
|
||||
return res.data;
|
||||
this.destProcesses = res.data.processes || [];
|
||||
return res;
|
||||
}
|
||||
this.processes = res.data.data.processes || [];
|
||||
this.processes = res.data.processes || [];
|
||||
}
|
||||
return res.data;
|
||||
return res;
|
||||
},
|
||||
async getEndpoints(params: {
|
||||
keyword?: string;
|
||||
serviceId?: string;
|
||||
isRelation?: boolean;
|
||||
limit?: number;
|
||||
}): Promise<Nullable<AxiosResponse>> {
|
||||
async getEndpoints(params: { keyword?: string; serviceId?: string; isRelation?: boolean; limit?: number }) {
|
||||
if (!params) {
|
||||
params = {};
|
||||
}
|
||||
@ -139,96 +132,96 @@ export const selectorStore = defineStore({
|
||||
if (!serviceId) {
|
||||
return null;
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("queryEndpoints").params({
|
||||
const res = await graphql.query("queryEndpoints").params({
|
||||
serviceId,
|
||||
duration: useAppStoreWithOut().durationTime,
|
||||
keyword: params.keyword || "",
|
||||
limit: params.limit,
|
||||
limit: params.limit || EndpointsTopNDefault,
|
||||
});
|
||||
if (!res.data.errors) {
|
||||
if (!res.errors) {
|
||||
if (params.isRelation) {
|
||||
this.destPods = res.data.data.pods || [];
|
||||
return res.data;
|
||||
this.destPods = res.data.pods || [];
|
||||
return res;
|
||||
}
|
||||
this.pods = res.data.data.pods || [];
|
||||
this.pods = res.data.pods || [];
|
||||
}
|
||||
return res.data;
|
||||
return res;
|
||||
},
|
||||
async getService(serviceId: string, isRelation: boolean) {
|
||||
if (!serviceId) {
|
||||
return;
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("queryService").params({
|
||||
const res = await graphql.query("queryService").params({
|
||||
serviceId,
|
||||
});
|
||||
if (!res.data.errors) {
|
||||
if (!res.errors) {
|
||||
if (isRelation) {
|
||||
this.setCurrentDestService(res.data.data.service);
|
||||
this.destServices = [res.data.data.service];
|
||||
return res.data;
|
||||
this.setCurrentDestService(res.data.service);
|
||||
this.destServices = [res.data.service];
|
||||
return res;
|
||||
}
|
||||
this.setCurrentService(res.data.data.service);
|
||||
this.services = [res.data.data.service];
|
||||
this.setCurrentService(res.data.service);
|
||||
this.services = [res.data.service];
|
||||
}
|
||||
|
||||
return res.data;
|
||||
return res;
|
||||
},
|
||||
async getInstance(instanceId: string, isRelation?: boolean) {
|
||||
if (!instanceId) {
|
||||
return;
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("queryInstance").params({
|
||||
const res = await graphql.query("queryInstance").params({
|
||||
instanceId,
|
||||
});
|
||||
if (!res.data.errors) {
|
||||
if (!res.errors) {
|
||||
if (isRelation) {
|
||||
this.currentDestPod = res.data.data.instance || null;
|
||||
this.destPods = [res.data.data.instance];
|
||||
return res.data;
|
||||
this.currentDestPod = res.data.instance || null;
|
||||
this.destPods = [res.data.instance];
|
||||
return res;
|
||||
}
|
||||
this.currentPod = res.data.data.instance || null;
|
||||
this.pods = [res.data.data.instance];
|
||||
this.currentPod = res.data.instance || null;
|
||||
this.pods = [res.data.instance];
|
||||
}
|
||||
|
||||
return res.data;
|
||||
return res;
|
||||
},
|
||||
async getEndpoint(endpointId: string, isRelation?: string) {
|
||||
if (!endpointId) {
|
||||
return;
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("queryEndpoint").params({
|
||||
const res = await graphql.query("queryEndpoint").params({
|
||||
endpointId,
|
||||
});
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
if (res.errors) {
|
||||
return res;
|
||||
}
|
||||
if (isRelation) {
|
||||
this.currentDestPod = res.data.data.endpoint || null;
|
||||
this.destPods = [res.data.data.endpoint];
|
||||
return res.data;
|
||||
this.currentDestPod = res.data.endpoint || null;
|
||||
this.destPods = [res.data.endpoint];
|
||||
return res;
|
||||
}
|
||||
this.currentPod = res.data.data.endpoint || null;
|
||||
this.pods = [res.data.data.endpoint];
|
||||
return res.data;
|
||||
this.currentPod = res.data.endpoint || null;
|
||||
this.pods = [res.data.endpoint];
|
||||
return res;
|
||||
},
|
||||
async getProcess(processId: string, isRelation?: boolean) {
|
||||
if (!processId) {
|
||||
return;
|
||||
}
|
||||
const res: AxiosResponse = await graphql.query("queryProcess").params({
|
||||
const res = await graphql.query("queryProcess").params({
|
||||
processId,
|
||||
});
|
||||
if (!res.data.errors) {
|
||||
if (!res.errors) {
|
||||
if (isRelation) {
|
||||
this.currentDestProcess = res.data.data.process || null;
|
||||
this.destProcesses = [res.data.data.process];
|
||||
this.currentDestProcess = res.data.process || null;
|
||||
this.destProcesses = [res.data.process];
|
||||
return res.data;
|
||||
}
|
||||
this.currentProcess = res.data.data.process || null;
|
||||
this.processes = [res.data.data.process];
|
||||
this.currentProcess = res.data.process || null;
|
||||
this.processes = [res.data.process];
|
||||
}
|
||||
|
||||
return res.data;
|
||||
return res;
|
||||
},
|
||||
},
|
||||
});
|
||||
|