mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-01 22:14:28 +00:00
feat: support the process dashboard and create the time range text widget (#138)
This commit is contained in:
parent
973b51e9ca
commit
9c0bb988e6
@ -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.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License. -->
|
limitations under the License. -->
|
||||||
<svg t="1648717513168" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15451" width="48" height="48"><path d="M810.666667 213.333333v597.333334H213.333333V213.333333h597.333334m85.333333-85.333333H128v768h768V128z m-512 170.666667h-85.333333v85.333333h85.333333z m170.666667 0h-85.333334v85.333333h85.333334z m-170.666667 170.666666h-85.333333v85.333334h85.333333z m170.666667 0h-85.333334v85.333334h85.333334z m-170.666667 170.666667h-85.333333v85.333333h85.333333z m170.666667 0h-85.333334v85.333333h85.333334z m170.666666-341.333333h-85.333333v85.333333h85.333333z m0 170.666666h-85.333333v85.333334h85.333333z m0 170.666667h-85.333333v85.333333h85.333333z" p-id="15452" fill="#515151"></path></svg>
|
<svg t="1648717513168" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15451" width="48" height="48"><path d="M810.666667 213.333333v597.333334H213.333333V213.333333h597.333334m85.333333-85.333333H128v768h768V128z m-512 170.666667h-85.333333v85.333333h85.333333z m170.666667 0h-85.333334v85.333333h85.333334z m-170.666667 170.666666h-85.333333v85.333334h85.333333z m170.666667 0h-85.333334v85.333334h85.333334z m-170.666667 170.666667h-85.333333v85.333333h85.333333z m170.666667 0h-85.333334v85.333333h85.333334z m170.666666-341.333333h-85.333333v85.333333h85.333333z m0 170.666666h-85.333333v85.333334h85.333333z m0 170.666667h-85.333333v85.333333h85.333333z" p-id="15452"></path></svg>
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
17
src/assets/icons/library_add.svg
Normal file
17
src/assets/icons/library_add.svg
Normal 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 version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M18.984 11.016v-2.016h-3.984v-3.984h-2.016v3.984h-3.984v2.016h3.984v3.984h2.016v-3.984h3.984zM20.016 2.016q0.797 0 1.383 0.586t0.586 1.383v12q0 0.797-0.586 1.406t-1.383 0.609h-12q-0.797 0-1.406-0.609t-0.609-1.406v-12q0-0.797 0.609-1.383t1.406-0.586h12zM3.984 6v14.016h14.016v1.969h-14.016q-0.797 0-1.383-0.586t-0.586-1.383v-14.016h1.969z"></path>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
15
src/assets/icons/time_range.svg
Normal file
15
src/assets/icons/time_range.svg
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<!-- 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="1660294515307" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1020" width="48" height="48"><path d="M240 512h64c9.6 0 16-6.4 16-16v-32c0-9.6-6.4-16-16-16h-64c-9.6 0-16 6.4-16 16v32c0 9.6 6.4 16 16 16z m160 0h384c9.6 0 16-6.4 16-16v-32c0-9.6-6.4-16-16-16H400c-9.6 0-16 6.4-16 16v32c0 9.6 6.4 16 16 16z m384 256h-64c-9.6 0-16 6.4-16 16v32c0 9.6 6.4 16 16 16h64c9.6 0 16-6.4 16-16v-32c0-9.6-6.4-16-16-16z" p-id="1021"></path><path d="M896 128H768V96c0-16-12.8-32-32-32s-32 12.8-32 32v32H320V96c0-16-12.8-32-32-32s-32 12.8-32 32v32H128c-35.2 0-64 28.8-64 64v704c0 35.2 28.8 64 64 64h768c35.2 0 64-28.8 64-64V192c0-35.2-28.8-64-64-64z m0 736c0 19.2-12.8 32-32 32H160c-19.2 0-32-12.8-32-32V384h768v480z m0-544H128v-96c0-19.2 12.8-32 32-32h96v32c0 16 12.8 32 32 32s32-12.8 32-32v-32h384v32c0 16 12.8 32 32 32s32-12.8 32-32v-32h96c19.2 0 32 12.8 32 32v96z" p-id="1022"></path><path d="M240 832h384c9.6 0 16-6.4 16-16v-32c0-9.6-6.4-16-16-16H240c-9.6 0-16 6.4-16 16v32c0 9.6 6.4 16 16 16z m0-160h544c9.6 0 16-6.4 16-16v-32c0-9.6-6.4-16-16-16H240c-9.6 0-16 6.4-16 16v32c0 9.6 6.4 16 16 16z" p-id="1023"></path></svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -33,12 +33,15 @@ export const createEBPFTask = {
|
|||||||
}`,
|
}`,
|
||||||
};
|
};
|
||||||
export const queryEBPFTasks = {
|
export const queryEBPFTasks = {
|
||||||
variable: "$serviceId: ID!",
|
variable:
|
||||||
|
"$serviceId: ID, $serviceInstanceId: ID, $targets: [EBPFProfilingTargetType!]",
|
||||||
query: `
|
query: `
|
||||||
queryEBPFTasks: queryEBPFProfilingTasks(serviceId: $serviceId) {
|
queryEBPFTasks: queryEBPFProfilingTasks(serviceId: $serviceId, serviceInstanceId: $serviceInstanceId, targets: $targets) {
|
||||||
taskId
|
taskId
|
||||||
serviceName
|
serviceName
|
||||||
serviceId
|
serviceId
|
||||||
|
serviceInstanceId
|
||||||
|
serviceInstanceName
|
||||||
processLabels
|
processLabels
|
||||||
taskStartTime
|
taskStartTime
|
||||||
triggerType
|
triggerType
|
||||||
@ -90,3 +93,22 @@ export const analysisEBPFResult = {
|
|||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const createNetworkProfiling = {
|
||||||
|
variable: "$request: EBPFProfilingNetworkTaskRequest!",
|
||||||
|
query: `
|
||||||
|
createEBPFNetworkProfiling(request: $request) {
|
||||||
|
status
|
||||||
|
errorReason
|
||||||
|
id
|
||||||
|
}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const keepNetworkProfiling = {
|
||||||
|
variable: "$taskId: ID!",
|
||||||
|
query: `
|
||||||
|
keepEBPFNetworkProfiling(taskId: $taskId) {
|
||||||
|
status
|
||||||
|
errorReason
|
||||||
|
}`,
|
||||||
|
};
|
||||||
|
@ -48,6 +48,29 @@ export const Instances = {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const Processes = {
|
||||||
|
variable: "$instanceId: ID!, $duration: Duration!",
|
||||||
|
query: `
|
||||||
|
processes: listProcesses(instanceId: $instanceId, duration: $duration) {
|
||||||
|
id
|
||||||
|
value: name
|
||||||
|
label: name
|
||||||
|
serviceId
|
||||||
|
serviceName
|
||||||
|
instanceId
|
||||||
|
instanceName
|
||||||
|
agentId
|
||||||
|
detectType
|
||||||
|
attributes {
|
||||||
|
name
|
||||||
|
value
|
||||||
|
}
|
||||||
|
labels
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
|
||||||
export const Endpoints = {
|
export const Endpoints = {
|
||||||
variable: "$serviceId: ID!, $keyword: String!",
|
variable: "$serviceId: ID!, $keyword: String!",
|
||||||
query: `
|
query: `
|
||||||
@ -102,3 +125,24 @@ export const getEndpoint = {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getProcess = {
|
||||||
|
variable: "$processId: ID!",
|
||||||
|
query: `
|
||||||
|
process: getProcess(processId: $processId) {
|
||||||
|
id
|
||||||
|
value: name
|
||||||
|
label: name
|
||||||
|
serviceId
|
||||||
|
serviceName
|
||||||
|
instanceId
|
||||||
|
instanceName
|
||||||
|
agentId
|
||||||
|
detectType
|
||||||
|
attributes {
|
||||||
|
name
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
@ -75,3 +75,26 @@ export const InstanceTopology = {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
|
export const ProcessTopology = {
|
||||||
|
variable: "$serviceInstanceId: ID!, $duration: Duration!",
|
||||||
|
query: `
|
||||||
|
topology: getProcessTopology(serviceInstanceId: $serviceInstanceId,
|
||||||
|
duration: $duration) {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
isReal
|
||||||
|
serviceName
|
||||||
|
serviceId
|
||||||
|
serviceInstanceId
|
||||||
|
serviceInstanceName
|
||||||
|
}
|
||||||
|
calls {
|
||||||
|
id
|
||||||
|
source
|
||||||
|
detectPoints
|
||||||
|
target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
@ -21,6 +21,8 @@ import {
|
|||||||
queryEBPFTasks,
|
queryEBPFTasks,
|
||||||
queryEBPFSchedules,
|
queryEBPFSchedules,
|
||||||
analysisEBPFResult,
|
analysisEBPFResult,
|
||||||
|
createNetworkProfiling,
|
||||||
|
keepNetworkProfiling,
|
||||||
} from "../fragments/ebpf";
|
} from "../fragments/ebpf";
|
||||||
|
|
||||||
export const getCreateTaskData = `query queryCreateTaskData(${queryCreateTaskData.variable}) {${queryCreateTaskData.query}}`;
|
export const getCreateTaskData = `query queryCreateTaskData(${queryCreateTaskData.variable}) {${queryCreateTaskData.query}}`;
|
||||||
@ -32,3 +34,7 @@ export const getEBPFTasks = `query queryEBPFTasks(${queryEBPFTasks.variable}) {$
|
|||||||
export const getEBPFSchedules = `query queryEBPFSchedules(${queryEBPFSchedules.variable}) {${queryEBPFSchedules.query}}`;
|
export const getEBPFSchedules = `query queryEBPFSchedules(${queryEBPFSchedules.variable}) {${queryEBPFSchedules.query}}`;
|
||||||
|
|
||||||
export const getEBPFResult = `query analysisEBPFResult(${analysisEBPFResult.variable}) {${analysisEBPFResult.query}}`;
|
export const getEBPFResult = `query analysisEBPFResult(${analysisEBPFResult.variable}) {${analysisEBPFResult.query}}`;
|
||||||
|
|
||||||
|
export const newNetworkProfiling = `mutation createNetworkProfiling(${createNetworkProfiling.variable}) {${createNetworkProfiling.query}}`;
|
||||||
|
|
||||||
|
export const aliveNetworkProfiling = `mutation keepNetworkProfiling(${keepNetworkProfiling.variable}) {${keepNetworkProfiling.query}}`;
|
||||||
|
@ -22,6 +22,8 @@ import {
|
|||||||
getService,
|
getService,
|
||||||
getInstance,
|
getInstance,
|
||||||
getEndpoint,
|
getEndpoint,
|
||||||
|
Processes,
|
||||||
|
getProcess,
|
||||||
} from "../fragments/selector";
|
} from "../fragments/selector";
|
||||||
|
|
||||||
export const queryServices = `query queryServices(${Services.variable}) {${Services.query}}`;
|
export const queryServices = `query queryServices(${Services.variable}) {${Services.query}}`;
|
||||||
@ -31,3 +33,5 @@ export const queryLayers = `query listLayer {${Layers.query}}`;
|
|||||||
export const queryService = `query queryService(${getService.variable}) {${getService.query}}`;
|
export const queryService = `query queryService(${getService.variable}) {${getService.query}}`;
|
||||||
export const queryInstance = `query queryInstance(${getInstance.variable}) {${getInstance.query}}`;
|
export const queryInstance = `query queryInstance(${getInstance.variable}) {${getInstance.query}}`;
|
||||||
export const queryEndpoint = `query queryInstance(${getEndpoint.variable}) {${getEndpoint.query}}`;
|
export const queryEndpoint = `query queryInstance(${getEndpoint.variable}) {${getEndpoint.query}}`;
|
||||||
|
export const queryProcesses = `query queryProcesses(${Processes.variable}) {${Processes.query}}`;
|
||||||
|
export const queryProcess = `query queryProcess(${getProcess.variable}) {${getProcess.query}}`;
|
||||||
|
@ -18,8 +18,10 @@ import {
|
|||||||
InstanceTopology,
|
InstanceTopology,
|
||||||
EndpointTopology,
|
EndpointTopology,
|
||||||
ServicesTopology,
|
ServicesTopology,
|
||||||
|
ProcessTopology,
|
||||||
} from "../fragments/topology";
|
} from "../fragments/topology";
|
||||||
|
|
||||||
export const getInstanceTopology = `query queryData(${InstanceTopology.variable}) {${InstanceTopology.query}}`;
|
export const getInstanceTopology = `query queryData(${InstanceTopology.variable}) {${InstanceTopology.query}}`;
|
||||||
export const getEndpointTopology = `query queryData(${EndpointTopology.variable}) {${EndpointTopology.query}}`;
|
export const getEndpointTopology = `query queryData(${EndpointTopology.variable}) {${EndpointTopology.query}}`;
|
||||||
export const getServicesTopology = `query queryData(${ServicesTopology.variable}) {${ServicesTopology.query}}`;
|
export const getServicesTopology = `query queryData(${ServicesTopology.variable}) {${ServicesTopology.query}}`;
|
||||||
|
export const getProcessTopology = `query queryData(${ProcessTopology.variable}) {${ProcessTopology.query}}`;
|
||||||
|
@ -32,7 +32,7 @@ export enum Calculations {
|
|||||||
Precision = "precision",
|
Precision = "precision",
|
||||||
ConvertSeconds = "convertSeconds",
|
ConvertSeconds = "convertSeconds",
|
||||||
ConvertMilliseconds = "convertMilliseconds",
|
ConvertMilliseconds = "convertMilliseconds",
|
||||||
MsTos = "msTos",
|
MsToS = "msTos",
|
||||||
Average = "average",
|
Average = "average",
|
||||||
PercentageAvg = "percentageAvg",
|
PercentageAvg = "percentageAvg",
|
||||||
ApdexAvg = "apdexAvg",
|
ApdexAvg = "apdexAvg",
|
||||||
|
@ -383,19 +383,16 @@ export function aggregation(
|
|||||||
case Calculations.Apdex:
|
case Calculations.Apdex:
|
||||||
data = val / 10000;
|
data = val / 10000;
|
||||||
break;
|
break;
|
||||||
case Calculations.ApdexAvg:
|
|
||||||
data = val / 10000;
|
|
||||||
break;
|
|
||||||
case Calculations.ConvertSeconds:
|
case Calculations.ConvertSeconds:
|
||||||
data = dayjs(val).format("YYYY-MM-DD HH:mm:ss");
|
data = dayjs(val * 1000).format("YYYY-MM-DD HH:mm:ss");
|
||||||
break;
|
break;
|
||||||
case Calculations.ConvertMilliseconds:
|
case Calculations.ConvertMilliseconds:
|
||||||
data = dayjs.unix(val).format("YYYY-MM-DD HH:mm:ss");
|
data = dayjs(val).format("YYYY-MM-DD HH:mm:ss");
|
||||||
break;
|
break;
|
||||||
case Calculations.Precision:
|
case Calculations.Precision:
|
||||||
data = data.toFixed(2);
|
data = data.toFixed(2);
|
||||||
break;
|
break;
|
||||||
case Calculations.MsTos:
|
case Calculations.MsToS:
|
||||||
data = (val / 1000).toFixed(2);
|
data = (val / 1000).toFixed(2);
|
||||||
break;
|
break;
|
||||||
case Calculations.SecondToDay:
|
case Calculations.SecondToDay:
|
||||||
|
@ -149,6 +149,7 @@ const msg = {
|
|||||||
"The name only supports Chinese and English, horizontal lines and underscores. The length of the name is limited to 300 characters",
|
"The name only supports Chinese and English, horizontal lines and underscores. The length of the name is limited to 300 characters",
|
||||||
duplicateName: "Duplicate name",
|
duplicateName: "Duplicate name",
|
||||||
enableAssociate: "Enable association",
|
enableAssociate: "Enable association",
|
||||||
|
text: "Text",
|
||||||
seconds: "Seconds",
|
seconds: "Seconds",
|
||||||
hourTip: "Select Hour",
|
hourTip: "Select Hour",
|
||||||
minuteTip: "Select Minute",
|
minuteTip: "Select Minute",
|
||||||
|
@ -145,6 +145,7 @@ const msg = {
|
|||||||
begin: "Inicio",
|
begin: "Inicio",
|
||||||
associateOptions: "Opciones de asociación",
|
associateOptions: "Opciones de asociación",
|
||||||
widget: "Dispositivo pequeño",
|
widget: "Dispositivo pequeño",
|
||||||
|
text: "Texto",
|
||||||
duplicateName: "Nombre duplicado",
|
duplicateName: "Nombre duplicado",
|
||||||
nameTip:
|
nameTip:
|
||||||
"El nombre sólo admite chino e inglés, líneas horizontales y subrayado, y la longitud del nombre no excederá de 300 caracteres",
|
"El nombre sólo admite chino e inglés, líneas horizontales y subrayado, y la longitud del nombre no excederá de 300 caracteres",
|
||||||
|
@ -146,6 +146,7 @@ const msg = {
|
|||||||
enableAssociate: "启用关联",
|
enableAssociate: "启用关联",
|
||||||
nameTip: "该名称仅支持中文和英文、横线和下划线, 并且限制长度为300个字符",
|
nameTip: "该名称仅支持中文和英文、横线和下划线, 并且限制长度为300个字符",
|
||||||
duplicateName: "重复的名称",
|
duplicateName: "重复的名称",
|
||||||
|
text: "文本",
|
||||||
seconds: "秒",
|
seconds: "秒",
|
||||||
hourTip: "选择小时",
|
hourTip: "选择小时",
|
||||||
minuteTip: "选择分钟",
|
minuteTip: "选择分钟",
|
||||||
|
@ -182,7 +182,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
|||||||
import(
|
import(
|
||||||
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
|
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
|
||||||
),
|
),
|
||||||
name: "ViewPodRelation",
|
name: "PodRelation",
|
||||||
meta: {
|
meta: {
|
||||||
notShow: true,
|
notShow: true,
|
||||||
},
|
},
|
||||||
@ -205,6 +205,37 @@ export const routesDashboard: Array<RouteRecordRaw> = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "",
|
||||||
|
redirect:
|
||||||
|
"/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name",
|
||||||
|
component: () =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
|
||||||
|
),
|
||||||
|
name: "ProcessRelation",
|
||||||
|
meta: {
|
||||||
|
notShow: true,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name",
|
||||||
|
component: () =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
|
||||||
|
),
|
||||||
|
name: "ViewProcessRelation",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name/tab/:activeTabIndex",
|
||||||
|
component: () =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
|
||||||
|
),
|
||||||
|
name: "ViewProcessRelationActiveTabIndex",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -29,3 +29,11 @@ export const TextConfig = {
|
|||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
textAlign: "left",
|
textAlign: "left",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const TimeRangeConfig = {
|
||||||
|
fontColor: "black",
|
||||||
|
backgroundColor: "white",
|
||||||
|
fontSize: 14,
|
||||||
|
textAlign: "center",
|
||||||
|
text: "text",
|
||||||
|
};
|
||||||
|
@ -21,7 +21,7 @@ import graphql from "@/graphql";
|
|||||||
import query from "@/graphql/fetch";
|
import query from "@/graphql/fetch";
|
||||||
import { DashboardItem } from "@/types/dashboard";
|
import { DashboardItem } from "@/types/dashboard";
|
||||||
import { useSelectorStore } from "@/store/modules/selectors";
|
import { useSelectorStore } from "@/store/modules/selectors";
|
||||||
import { NewControl, TextConfig } from "../data";
|
import { NewControl, TextConfig, TimeRangeConfig } from "../data";
|
||||||
import { AxiosResponse } from "axios";
|
import { AxiosResponse } from "axios";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
@ -113,13 +113,27 @@ export const dashboardStore = defineStore({
|
|||||||
: 3,
|
: 3,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (["Trace", "Profile", "Log", "DemandLog", "Ebpf"].includes(type)) {
|
if (
|
||||||
|
[
|
||||||
|
"Trace",
|
||||||
|
"Profile",
|
||||||
|
"Log",
|
||||||
|
"DemandLog",
|
||||||
|
"Ebpf",
|
||||||
|
"NetworkProfiling",
|
||||||
|
].includes(type)
|
||||||
|
) {
|
||||||
newItem.h = 36;
|
newItem.h = 36;
|
||||||
}
|
}
|
||||||
if (type === "Text") {
|
if (type === "Text") {
|
||||||
newItem.h = 6;
|
newItem.h = 6;
|
||||||
newItem.graph = TextConfig;
|
newItem.graph = TextConfig;
|
||||||
}
|
}
|
||||||
|
if (type === "TimeRange") {
|
||||||
|
newItem.w = 8;
|
||||||
|
newItem.h = 6;
|
||||||
|
newItem.graph = TimeRangeConfig;
|
||||||
|
}
|
||||||
this.activedGridItem = newItem.i;
|
this.activedGridItem = newItem.i;
|
||||||
this.selectedGrid = newItem;
|
this.selectedGrid = newItem;
|
||||||
this.layout = this.layout.map((d: LayoutConfig) => {
|
this.layout = this.layout.map((d: LayoutConfig) => {
|
||||||
@ -170,13 +184,27 @@ export const dashboardStore = defineStore({
|
|||||||
showDepth: true,
|
showDepth: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (["Trace", "Profile", "Log", "DemandLog", "Ebpf"].includes(type)) {
|
if (
|
||||||
|
[
|
||||||
|
"Trace",
|
||||||
|
"Profile",
|
||||||
|
"Log",
|
||||||
|
"DemandLog",
|
||||||
|
"Ebpf",
|
||||||
|
"NetworkProfiling",
|
||||||
|
].includes(type)
|
||||||
|
) {
|
||||||
newItem.h = 32;
|
newItem.h = 32;
|
||||||
}
|
}
|
||||||
if (type === "Text") {
|
if (type === "Text") {
|
||||||
newItem.h = 6;
|
newItem.h = 6;
|
||||||
newItem.graph = TextConfig;
|
newItem.graph = TextConfig;
|
||||||
}
|
}
|
||||||
|
if (type === "TimeRange") {
|
||||||
|
newItem.w = 8;
|
||||||
|
newItem.h = 6;
|
||||||
|
newItem.graph = TextConfig;
|
||||||
|
}
|
||||||
if (this.layout[idx].children) {
|
if (this.layout[idx].children) {
|
||||||
const items = children.map((d: LayoutConfig) => {
|
const items = children.map((d: LayoutConfig) => {
|
||||||
d.y = d.y + newItem.h;
|
d.y = d.y + newItem.h;
|
||||||
|
@ -25,8 +25,7 @@ import {
|
|||||||
import { store } from "@/store";
|
import { store } from "@/store";
|
||||||
import graphql from "@/graphql";
|
import graphql from "@/graphql";
|
||||||
import { AxiosResponse } from "axios";
|
import { AxiosResponse } from "axios";
|
||||||
|
interface EbpfState {
|
||||||
interface EbpfStore {
|
|
||||||
taskList: EBPFTaskList[];
|
taskList: EBPFTaskList[];
|
||||||
eBPFSchedules: EBPFProfilingSchedule[];
|
eBPFSchedules: EBPFProfilingSchedule[];
|
||||||
currentSchedule: EBPFProfilingSchedule | Record<string, never>;
|
currentSchedule: EBPFProfilingSchedule | Record<string, never>;
|
||||||
@ -40,7 +39,7 @@ interface EbpfStore {
|
|||||||
|
|
||||||
export const ebpfStore = defineStore({
|
export const ebpfStore = defineStore({
|
||||||
id: "eBPF",
|
id: "eBPF",
|
||||||
state: (): EbpfStore => ({
|
state: (): EbpfState => ({
|
||||||
taskList: [],
|
taskList: [],
|
||||||
eBPFSchedules: [],
|
eBPFSchedules: [],
|
||||||
currentSchedule: {},
|
currentSchedule: {},
|
||||||
@ -53,7 +52,7 @@ export const ebpfStore = defineStore({
|
|||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
setSelectedTask(task: EBPFTaskList) {
|
setSelectedTask(task: EBPFTaskList) {
|
||||||
this.selectedTask = task;
|
this.selectedTask = task || {};
|
||||||
},
|
},
|
||||||
setCurrentSchedule(s: EBPFProfilingSchedule) {
|
setCurrentSchedule(s: EBPFProfilingSchedule) {
|
||||||
this.currentSchedule = s;
|
this.currentSchedule = s;
|
||||||
@ -84,22 +83,31 @@ export const ebpfStore = defineStore({
|
|||||||
if (res.data.errors) {
|
if (res.data.errors) {
|
||||||
return res.data;
|
return res.data;
|
||||||
}
|
}
|
||||||
this.getTaskList(param.serviceId);
|
this.getTaskList({
|
||||||
|
serviceId: param.serviceId,
|
||||||
|
targets: ["ON_CPU", "OFF_CPU"],
|
||||||
|
});
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
async getTaskList(serviceId: string) {
|
async getTaskList(params: {
|
||||||
if (!serviceId) {
|
serviceId: string;
|
||||||
|
serviceInstanceId: string;
|
||||||
|
targets: string[];
|
||||||
|
}) {
|
||||||
|
if (!params.serviceId) {
|
||||||
return new Promise((resolve) => resolve({}));
|
return new Promise((resolve) => resolve({}));
|
||||||
}
|
}
|
||||||
const res: AxiosResponse = await graphql
|
const res: AxiosResponse = await graphql
|
||||||
.query("getEBPFTasks")
|
.query("getEBPFTasks")
|
||||||
.params({ serviceId });
|
.params(params);
|
||||||
|
|
||||||
this.tip = "";
|
this.tip = "";
|
||||||
if (res.data.errors) {
|
if (res.data.errors) {
|
||||||
return res.data;
|
return res.data;
|
||||||
}
|
}
|
||||||
this.taskList = res.data.data.queryEBPFTasks || [];
|
this.taskList = res.data.data.queryEBPFTasks || [];
|
||||||
|
this.selectedTask = this.taskList[0] || {};
|
||||||
|
this.setSelectedTask(this.selectedTask);
|
||||||
if (!this.taskList.length) {
|
if (!this.taskList.length) {
|
||||||
return res.data;
|
return res.data;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { Service, Instance, Endpoint } from "@/types/selector";
|
import { Service, Instance, Endpoint, Process } from "@/types/selector";
|
||||||
import { store } from "@/store";
|
import { store } from "@/store";
|
||||||
import graphql from "@/graphql";
|
import graphql from "@/graphql";
|
||||||
import { AxiosResponse } from "axios";
|
import { AxiosResponse } from "axios";
|
||||||
@ -24,11 +24,15 @@ interface SelectorState {
|
|||||||
services: Service[];
|
services: Service[];
|
||||||
destServices: Service[];
|
destServices: Service[];
|
||||||
pods: Array<Instance | Endpoint>;
|
pods: Array<Instance | Endpoint>;
|
||||||
|
processes: Process[];
|
||||||
|
destProcesses: Process[];
|
||||||
currentService: Nullable<Service>;
|
currentService: Nullable<Service>;
|
||||||
currentPod: Nullable<Instance | Endpoint>;
|
currentPod: Nullable<Instance | Endpoint>;
|
||||||
|
currentProcess: Nullable<Process>;
|
||||||
currentDestService: Nullable<Service>;
|
currentDestService: Nullable<Service>;
|
||||||
currentDestPod: Nullable<Instance | Endpoint>;
|
currentDestPod: Nullable<Instance | Endpoint>;
|
||||||
destPods: Array<Instance | Endpoint>;
|
destPods: Array<Instance | Endpoint>;
|
||||||
|
currentDestProcess: Nullable<Process>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const selectorStore = defineStore({
|
export const selectorStore = defineStore({
|
||||||
@ -38,10 +42,14 @@ export const selectorStore = defineStore({
|
|||||||
destServices: [],
|
destServices: [],
|
||||||
pods: [],
|
pods: [],
|
||||||
destPods: [],
|
destPods: [],
|
||||||
|
processes: [],
|
||||||
|
destProcesses: [],
|
||||||
currentService: null,
|
currentService: null,
|
||||||
currentPod: null,
|
currentPod: null,
|
||||||
|
currentProcess: null,
|
||||||
currentDestService: null,
|
currentDestService: null,
|
||||||
currentDestPod: null,
|
currentDestPod: null,
|
||||||
|
currentDestProcess: null,
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
setCurrentService(service: Nullable<Service>) {
|
setCurrentService(service: Nullable<Service>) {
|
||||||
@ -56,6 +64,18 @@ export const selectorStore = defineStore({
|
|||||||
setCurrentDestPod(pod: Nullable<Instance | Endpoint>) {
|
setCurrentDestPod(pod: Nullable<Instance | Endpoint>) {
|
||||||
this.currentDestPod = pod;
|
this.currentDestPod = pod;
|
||||||
},
|
},
|
||||||
|
setCurrentProcess(process: Nullable<Process>) {
|
||||||
|
this.currentProcess = process;
|
||||||
|
},
|
||||||
|
setCurrentDestProcess(process: Nullable<Process>) {
|
||||||
|
this.currentDestProcess = process;
|
||||||
|
},
|
||||||
|
setDestPods(pods: Array<Instance | Endpoint>) {
|
||||||
|
this.destPods = pods;
|
||||||
|
},
|
||||||
|
setDestProcesses(processes: Array<Process>) {
|
||||||
|
this.destProcesses = processes;
|
||||||
|
},
|
||||||
async fetchLayers(): Promise<AxiosResponse> {
|
async fetchLayers(): Promise<AxiosResponse> {
|
||||||
const res: AxiosResponse = await graphql.query("queryLayers").params({});
|
const res: AxiosResponse = await graphql.query("queryLayers").params({});
|
||||||
|
|
||||||
@ -93,6 +113,27 @@ export const selectorStore = defineStore({
|
|||||||
}
|
}
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
|
async getProcesses(param?: {
|
||||||
|
instanceId: string;
|
||||||
|
isRelation: boolean;
|
||||||
|
}): Promise<Nullable<AxiosResponse>> {
|
||||||
|
const instanceId = param ? param.instanceId : this.currentPod?.id;
|
||||||
|
if (!instanceId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const res: AxiosResponse = await graphql.query("queryProcesses").params({
|
||||||
|
instanceId,
|
||||||
|
duration: useAppStoreWithOut().durationTime,
|
||||||
|
});
|
||||||
|
if (!res.data.errors) {
|
||||||
|
if (param && param.isRelation) {
|
||||||
|
this.destProcesses = res.data.data.processes || [];
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
this.processes = res.data.data.processes || [];
|
||||||
|
}
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
async getEndpoints(params: {
|
async getEndpoints(params: {
|
||||||
keyword?: string;
|
keyword?: string;
|
||||||
serviceId?: string;
|
serviceId?: string;
|
||||||
@ -176,6 +217,25 @@ export const selectorStore = defineStore({
|
|||||||
this.pods = [res.data.data.endpoint];
|
this.pods = [res.data.data.endpoint];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
async getProcess(instanceId: string, isRelation?: boolean) {
|
||||||
|
if (!instanceId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const res: AxiosResponse = await graphql.query("queryProcess").params({
|
||||||
|
instanceId,
|
||||||
|
});
|
||||||
|
if (!res.data.errors) {
|
||||||
|
if (isRelation) {
|
||||||
|
this.currentDestProcess = res.data.data.process || null;
|
||||||
|
this.destProcesses = [res.data.data.process];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.currentProcess = res.data.data.process || null;
|
||||||
|
this.processes = [res.data.data.process];
|
||||||
|
}
|
||||||
|
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
24
src/types/ebpf.d.ts
vendored
24
src/types/ebpf.d.ts
vendored
@ -15,6 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Process } from "./selector";
|
||||||
export interface EBPFTaskCreationRequest {
|
export interface EBPFTaskCreationRequest {
|
||||||
serviceId: string;
|
serviceId: string;
|
||||||
processLabels: string[];
|
processLabels: string[];
|
||||||
@ -43,18 +44,7 @@ export interface EBPFProfilingSchedule {
|
|||||||
startTime: number;
|
startTime: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Process = {
|
export type Process = Process;
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
serviceId: string;
|
|
||||||
serviceName: string;
|
|
||||||
instanceId: string;
|
|
||||||
instanceName: string;
|
|
||||||
agentId: string;
|
|
||||||
detectType: string;
|
|
||||||
attributes: { name: string; value: string }[];
|
|
||||||
labels: string[];
|
|
||||||
};
|
|
||||||
export type StackElement = {
|
export type StackElement = {
|
||||||
id: string;
|
id: string;
|
||||||
originId: string;
|
originId: string;
|
||||||
@ -75,3 +65,13 @@ export type AnalyzationTrees = {
|
|||||||
dumpCount: number;
|
dumpCount: number;
|
||||||
stackType: string;
|
stackType: string;
|
||||||
};
|
};
|
||||||
|
export type ProcessNode = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
serviceId: string;
|
||||||
|
serviceName: string;
|
||||||
|
serviceInstanceId: string;
|
||||||
|
serviceInstanceName: string;
|
||||||
|
name: string;
|
||||||
|
isReal: boolean;
|
||||||
|
};
|
||||||
|
13
src/types/selector.d.ts
vendored
13
src/types/selector.d.ts
vendored
@ -46,3 +46,16 @@ export type Service = {
|
|||||||
layers: string[];
|
layers: string[];
|
||||||
shortName: string;
|
shortName: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type Process = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
serviceId: string;
|
||||||
|
serviceName: string;
|
||||||
|
instanceId: string;
|
||||||
|
instanceName: string;
|
||||||
|
agentId: string;
|
||||||
|
detectType: string;
|
||||||
|
attributes: { name: string; value: string }[];
|
||||||
|
labels: string[];
|
||||||
|
};
|
||||||
|
161
src/views/dashboard/configuration/TimeRange.vue
Normal file
161
src/views/dashboard/configuration/TimeRange.vue
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
<!-- 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>
|
||||||
|
<div class="item">
|
||||||
|
<span class="label">{{ t("text") }}</span>
|
||||||
|
<el-input
|
||||||
|
class="input"
|
||||||
|
v-model="text"
|
||||||
|
size="small"
|
||||||
|
@change="changeConfig({ text })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="label">{{ t("textAlign") }}</span>
|
||||||
|
<Selector
|
||||||
|
:value="textAlign"
|
||||||
|
:options="AlignStyle"
|
||||||
|
size="small"
|
||||||
|
placeholder="Select a color"
|
||||||
|
class="input"
|
||||||
|
@change="changeConfig({ textAlign: $event[0].value })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="label">{{ t("backgroundColors") }}</span>
|
||||||
|
<Selector
|
||||||
|
:value="backgroundColor"
|
||||||
|
:options="Colors"
|
||||||
|
size="small"
|
||||||
|
placeholder="Select a color"
|
||||||
|
class="input"
|
||||||
|
@change="changeConfig({ backgroundColor: $event[0].value })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="label">{{ t("fontSize") }}</span>
|
||||||
|
<el-slider
|
||||||
|
class="slider"
|
||||||
|
v-model="fontSize"
|
||||||
|
show-input
|
||||||
|
input-size="small"
|
||||||
|
:min="12"
|
||||||
|
:max="30"
|
||||||
|
:step="1"
|
||||||
|
@change="changeConfig({ fontSize })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="label">{{ t("fontColors") }}</span>
|
||||||
|
<Selector
|
||||||
|
:value="fontColor"
|
||||||
|
:options="Colors"
|
||||||
|
size="small"
|
||||||
|
placeholder="Select a color"
|
||||||
|
class="input"
|
||||||
|
@change="changeConfig({ fontColor: $event[0].value })"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<el-button size="small" @click="cancelConfig">
|
||||||
|
{{ t("cancel") }}
|
||||||
|
</el-button>
|
||||||
|
<el-button size="small" type="primary" @click="applyConfig">
|
||||||
|
{{ t("apply") }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const dashboardStore = useDashboardStore();
|
||||||
|
const originConfig = dashboardStore.selectedGrid;
|
||||||
|
const graph = originConfig.graph || {};
|
||||||
|
const backgroundColor = ref(graph.backgroundColor || "green");
|
||||||
|
const fontColor = ref(graph.fontColor || "white");
|
||||||
|
const fontSize = ref<number>(graph.fontSize || 12);
|
||||||
|
const textAlign = ref(graph.textAlign || "left");
|
||||||
|
const text = ref<string>(graph.text || "");
|
||||||
|
const Colors = [
|
||||||
|
{
|
||||||
|
label: "Green",
|
||||||
|
value: "green",
|
||||||
|
},
|
||||||
|
{ label: "Blue", value: "blue" },
|
||||||
|
{ label: "Red", value: "red" },
|
||||||
|
{ label: "Grey", value: "grey" },
|
||||||
|
{ label: "White", value: "white" },
|
||||||
|
{ label: "Black", value: "black" },
|
||||||
|
{ label: "Orange", value: "orange" },
|
||||||
|
];
|
||||||
|
const AlignStyle = [
|
||||||
|
{
|
||||||
|
label: "Left",
|
||||||
|
value: "left",
|
||||||
|
},
|
||||||
|
{ label: "Center", value: "center" },
|
||||||
|
{ label: "Right", value: "right" },
|
||||||
|
];
|
||||||
|
function changeConfig(param: { [key: string]: unknown }) {
|
||||||
|
const { selectedGrid } = dashboardStore;
|
||||||
|
const graph = {
|
||||||
|
...selectedGrid.graph,
|
||||||
|
...param,
|
||||||
|
};
|
||||||
|
dashboardStore.selectWidget({ ...selectedGrid, graph });
|
||||||
|
}
|
||||||
|
function applyConfig() {
|
||||||
|
dashboardStore.setConfigPanel(false);
|
||||||
|
dashboardStore.setConfigs(dashboardStore.selectedGrid);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelConfig() {
|
||||||
|
dashboardStore.selectWidget(originConfig);
|
||||||
|
dashboardStore.setConfigPanel(false);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.slider {
|
||||||
|
width: 500px;
|
||||||
|
margin-top: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: right;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
@ -19,10 +19,12 @@ import Text from "./Text.vue";
|
|||||||
import Widget from "./Widget.vue";
|
import Widget from "./Widget.vue";
|
||||||
import Topology from "./Topology.vue";
|
import Topology from "./Topology.vue";
|
||||||
import Event from "./Event.vue";
|
import Event from "./Event.vue";
|
||||||
|
import TimeRange from "./TimeRange.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Text,
|
Text,
|
||||||
Widget,
|
Widget,
|
||||||
Topology,
|
Topology,
|
||||||
Event,
|
Event,
|
||||||
|
TimeRange,
|
||||||
};
|
};
|
||||||
|
@ -179,12 +179,16 @@ const setVisTypes = computed(() => {
|
|||||||
|
|
||||||
async function setMetricType(chart?: any) {
|
async function setMetricType(chart?: any) {
|
||||||
const g = chart || dashboardStore.selectedGrid.graph || {};
|
const g = chart || dashboardStore.selectedGrid.graph || {};
|
||||||
|
let arr: any[] = states.metricList;
|
||||||
|
if (!chart) {
|
||||||
const json = await dashboardStore.fetchMetricList();
|
const json = await dashboardStore.fetchMetricList();
|
||||||
if (json.errors) {
|
if (json.errors) {
|
||||||
ElMessage.error(json.errors);
|
ElMessage.error(json.errors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
states.metricList = (json.data.metrics || []).filter(
|
arr = json.data.metrics;
|
||||||
|
}
|
||||||
|
states.metricList = (arr || []).filter(
|
||||||
(d: { catalog: string; type: string }) => {
|
(d: { catalog: string; type: string }) => {
|
||||||
if (states.isList) {
|
if (states.isList) {
|
||||||
if (d.type === MetricsType.REGULAR_VALUE) {
|
if (d.type === MetricsType.REGULAR_VALUE) {
|
||||||
|
@ -110,16 +110,8 @@ import { useRoute } from "vue-router";
|
|||||||
import type { PropType } from "vue";
|
import type { PropType } from "vue";
|
||||||
import { LayoutConfig } from "@/types/dashboard";
|
import { LayoutConfig } from "@/types/dashboard";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import Topology from "./Topology.vue";
|
import controls from "./tab";
|
||||||
import Widget from "./Widget.vue";
|
|
||||||
import Trace from "./Trace.vue";
|
|
||||||
import Profile from "./Profile.vue";
|
|
||||||
import Log from "./Log.vue";
|
|
||||||
import Text from "./Text.vue";
|
|
||||||
import Ebpf from "./Ebpf.vue";
|
|
||||||
import Event from "./Event.vue";
|
|
||||||
import { dragIgnoreFrom } from "../data";
|
import { dragIgnoreFrom } from "../data";
|
||||||
import DemandLog from "./DemandLog.vue";
|
|
||||||
import copy from "@/utils/copy";
|
import copy from "@/utils/copy";
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
@ -132,15 +124,7 @@ const props = {
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "Tab",
|
name: "Tab",
|
||||||
components: {
|
components: {
|
||||||
Topology,
|
...controls,
|
||||||
Widget,
|
|
||||||
Trace,
|
|
||||||
Profile,
|
|
||||||
Log,
|
|
||||||
Text,
|
|
||||||
Ebpf,
|
|
||||||
DemandLog,
|
|
||||||
Event,
|
|
||||||
},
|
},
|
||||||
props,
|
props,
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
187
src/views/dashboard/controls/TimeRange.vue
Normal file
187
src/views/dashboard/controls/TimeRange.vue
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
<!-- 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>
|
||||||
|
<div class="time-range">
|
||||||
|
<div class="header">
|
||||||
|
<el-popover
|
||||||
|
placement="bottom"
|
||||||
|
trigger="click"
|
||||||
|
:width="100"
|
||||||
|
v-if="dashboardStore.editMode"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<span>
|
||||||
|
<Icon iconName="ellipsis_v" size="middle" class="operation" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<div class="tools" @click="editConfig">
|
||||||
|
<span>{{ t("edit") }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="tools" @click="removeTopo">
|
||||||
|
<span>{{ t("delete") }}</span>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="body"
|
||||||
|
:style="{
|
||||||
|
backgroundColor: TextColors[graph.backgroundColor],
|
||||||
|
justifyContent: graph.textAlign,
|
||||||
|
color: TextColors[graph.fontColor],
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="mr-5"
|
||||||
|
:style="{
|
||||||
|
fontSize: graph.fontSize + 'px',
|
||||||
|
}"
|
||||||
|
>{{ graph.text }}
|
||||||
|
</span>
|
||||||
|
<Icon iconName="time_range" size="middle" />
|
||||||
|
<span
|
||||||
|
class="ml-5"
|
||||||
|
:style="{
|
||||||
|
fontSize: graph.fontSize + 'px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ content }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed } from "vue";
|
||||||
|
import type { PropType } from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
|
import { TextColors } from "@/views/dashboard/data";
|
||||||
|
|
||||||
|
/*global defineProps */
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object as PropType<any>,
|
||||||
|
default: () => ({ graph: {} }),
|
||||||
|
},
|
||||||
|
activeIndex: { type: String, default: "" },
|
||||||
|
});
|
||||||
|
const { t } = useI18n();
|
||||||
|
const graph = computed(() => props.data.graph || {});
|
||||||
|
const dashboardStore = useDashboardStore();
|
||||||
|
const appStore = useAppStoreWithOut();
|
||||||
|
const content = computed(() => {
|
||||||
|
const text = [appStore.durationRow.start, appStore.durationRow.end]
|
||||||
|
.map((date: Date) => tf(date, "YYYY-MM-DD HH:mm"))
|
||||||
|
.join(` ~ `);
|
||||||
|
return text;
|
||||||
|
});
|
||||||
|
|
||||||
|
function removeTopo() {
|
||||||
|
dashboardStore.removeControls(props.data);
|
||||||
|
}
|
||||||
|
function editConfig() {
|
||||||
|
dashboardStore.setConfigPanel(true);
|
||||||
|
dashboardStore.selectWidget(props.data);
|
||||||
|
}
|
||||||
|
function tf(time: Date, format: any): string {
|
||||||
|
const local = {
|
||||||
|
dow: 1, // Monday is the first day of the week
|
||||||
|
hourTip: t("hourTip"), // tip of select hour
|
||||||
|
minuteTip: t("minuteTip"), // tip of select minute
|
||||||
|
secondTip: t("secondTip"), // tip of select second
|
||||||
|
yearSuffix: t("yearSuffix"), // format of head
|
||||||
|
monthsHead: t("monthsHead").split("_"), // months of head
|
||||||
|
months: t("months").split("_"), // months of panel
|
||||||
|
weeks: t("weeks").split("_"), // weeks
|
||||||
|
cancelTip: t("cancel"), // default text for cancel button
|
||||||
|
submitTip: t("confirm"), // default text for submit button
|
||||||
|
quarterHourCutTip: t("quarterHourCutTip"),
|
||||||
|
halfHourCutTip: t("halfHourCutTip"),
|
||||||
|
hourCutTip: t("hourCutTip"),
|
||||||
|
dayCutTip: t("dayCutTip"),
|
||||||
|
weekCutTip: t("weekCutTip"),
|
||||||
|
monthCutTip: t("monthCutTip"),
|
||||||
|
};
|
||||||
|
const year = time.getFullYear();
|
||||||
|
const month = time.getMonth();
|
||||||
|
const day = time.getDate();
|
||||||
|
const hours24 = time.getHours();
|
||||||
|
const hours = hours24 % 12 === 0 ? 12 : hours24 % 12;
|
||||||
|
const minutes = time.getMinutes();
|
||||||
|
const seconds = time.getSeconds();
|
||||||
|
const milliseconds = time.getMilliseconds();
|
||||||
|
const dd = (t: number) => `0${t}`.slice(-2);
|
||||||
|
const map: { [key: string]: string | number } = {
|
||||||
|
YYYY: year,
|
||||||
|
MM: dd(month + 1),
|
||||||
|
MMM: local.months[month],
|
||||||
|
MMMM: local.monthsHead[month],
|
||||||
|
M: month + 1,
|
||||||
|
DD: dd(day),
|
||||||
|
D: day,
|
||||||
|
HH: dd(hours24),
|
||||||
|
H: hours24,
|
||||||
|
hh: dd(hours),
|
||||||
|
h: hours,
|
||||||
|
mm: dd(minutes),
|
||||||
|
m: minutes,
|
||||||
|
ss: dd(seconds),
|
||||||
|
s: seconds,
|
||||||
|
S: milliseconds,
|
||||||
|
};
|
||||||
|
return format.replace(/Y+|M+|D+|H+|h+|m+|s+|S+/g, (str: string) => map[str]);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.time-range {
|
||||||
|
font-size: 12px;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operation {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
padding: 0 20px 0 10px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: auto;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools {
|
||||||
|
padding: 5px 0;
|
||||||
|
color: #999;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #409eff;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -213,7 +213,10 @@ export default defineComponent({
|
|||||||
watch(
|
watch(
|
||||||
() => [selectorStore.currentPod, selectorStore.currentDestPod],
|
() => [selectorStore.currentPod, selectorStore.currentDestPod],
|
||||||
() => {
|
() => {
|
||||||
if (dashboardStore.entity === EntityType[0].value) {
|
if (
|
||||||
|
dashboardStore.entity === EntityType[0].value ||
|
||||||
|
dashboardStore.entity === EntityType[7].value
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isList.value) {
|
if (isList.value) {
|
||||||
@ -222,6 +225,14 @@ export default defineComponent({
|
|||||||
queryMetrics();
|
queryMetrics();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
watch(
|
||||||
|
() => [selectorStore.currentProcess, selectorStore.currentDestProcess],
|
||||||
|
() => {
|
||||||
|
if (dashboardStore.entity === EntityType[7].value) {
|
||||||
|
queryMetrics();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
watch(
|
watch(
|
||||||
() => appStore.durationTime,
|
() => appStore.durationTime,
|
||||||
() => {
|
() => {
|
||||||
|
@ -24,6 +24,7 @@ import Text from "./Text.vue";
|
|||||||
import Ebpf from "./Ebpf.vue";
|
import Ebpf from "./Ebpf.vue";
|
||||||
import DemandLog from "./DemandLog.vue";
|
import DemandLog from "./DemandLog.vue";
|
||||||
import Event from "./Event.vue";
|
import Event from "./Event.vue";
|
||||||
|
import TimeRange from "./TimeRange.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Tab,
|
Tab,
|
||||||
@ -36,4 +37,5 @@ export default {
|
|||||||
Ebpf,
|
Ebpf,
|
||||||
DemandLog,
|
DemandLog,
|
||||||
Event,
|
Event,
|
||||||
|
TimeRange,
|
||||||
};
|
};
|
||||||
|
39
src/views/dashboard/controls/tab.ts
Normal file
39
src/views/dashboard/controls/tab.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* 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 Topology from "./Topology.vue";
|
||||||
|
import Widget from "./Widget.vue";
|
||||||
|
import Trace from "./Trace.vue";
|
||||||
|
import Profile from "./Profile.vue";
|
||||||
|
import Log from "./Log.vue";
|
||||||
|
import Text from "./Text.vue";
|
||||||
|
import Ebpf from "./Ebpf.vue";
|
||||||
|
import DemandLog from "./DemandLog.vue";
|
||||||
|
import Event from "./Event.vue";
|
||||||
|
import TimeRange from "./TimeRange.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
Widget,
|
||||||
|
Trace,
|
||||||
|
Topology,
|
||||||
|
Profile,
|
||||||
|
Log,
|
||||||
|
Text,
|
||||||
|
Ebpf,
|
||||||
|
DemandLog,
|
||||||
|
Event,
|
||||||
|
TimeRange,
|
||||||
|
};
|
@ -159,6 +159,7 @@ export const EntityType = [
|
|||||||
key: 4,
|
key: 4,
|
||||||
},
|
},
|
||||||
{ value: "EndpointRelation", label: "Endpoint Relation", key: 4 },
|
{ value: "EndpointRelation", label: "Endpoint Relation", key: 4 },
|
||||||
|
{ value: "ProcessRelation", label: "Process Relation", key: 5 },
|
||||||
];
|
];
|
||||||
export const ListEntity: any = {
|
export const ListEntity: any = {
|
||||||
InstanceList: EntityType[3].value,
|
InstanceList: EntityType[3].value,
|
||||||
@ -207,6 +208,12 @@ export const EndpointTools = [
|
|||||||
{ name: "assignment", content: "Add Log", id: "addLog" },
|
{ name: "assignment", content: "Add Log", id: "addLog" },
|
||||||
{ name: "event", content: "Add Event", id: "addEvent" },
|
{ name: "event", content: "Add Event", id: "addEvent" },
|
||||||
];
|
];
|
||||||
|
export const ProcessTools = [
|
||||||
|
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||||
|
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||||
|
{ name: "library_books", content: "Add Text", id: "addText" },
|
||||||
|
{ name: "time_range", content: "Add Time Range Text", id: "addTimeRange" },
|
||||||
|
];
|
||||||
export const ServiceRelationTools = [
|
export const ServiceRelationTools = [
|
||||||
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
{ name: "playlist_add", content: "Add Widget", id: "addWidget" },
|
||||||
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
{ name: "all_inbox", content: "Add Tab", id: "addTab" },
|
||||||
|
32
src/views/dashboard/graphs/topology.ts
Normal file
32
src/views/dashboard/graphs/topology.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* 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 Area from "./Area.vue";
|
||||||
|
import Line from "./Line.vue";
|
||||||
|
import Bar from "./Bar.vue";
|
||||||
|
import TopList from "./TopList.vue";
|
||||||
|
import Table from "./Table.vue";
|
||||||
|
import Card from "./Card.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
Line,
|
||||||
|
Bar,
|
||||||
|
TopList,
|
||||||
|
Area,
|
||||||
|
Table,
|
||||||
|
Card,
|
||||||
|
};
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License. -->
|
limitations under the License. -->
|
||||||
<template>
|
<template>
|
||||||
<div class="dashboard-tool flex-h">
|
<div class="dashboard-tool flex-h">
|
||||||
|
<div :class="isRelation ? 'flex-v' : 'flex-h'">
|
||||||
<div class="flex-h">
|
<div class="flex-h">
|
||||||
<div class="selectors-item" v-if="key !== 10">
|
<div class="selectors-item" v-if="key !== 10">
|
||||||
<span class="label">$Service</span>
|
<span class="label">$Service</span>
|
||||||
@ -26,7 +27,7 @@ limitations under the License. -->
|
|||||||
class="selectors"
|
class="selectors"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectors-item" v-if="key === 3 || key === 4">
|
<div class="selectors-item" v-if="key === 3 || key === 4 || key === 5">
|
||||||
<span class="label">
|
<span class="label">
|
||||||
{{
|
{{
|
||||||
["EndpointRelation", "Endpoint"].includes(dashboardStore.entity)
|
["EndpointRelation", "Endpoint"].includes(dashboardStore.entity)
|
||||||
@ -47,7 +48,20 @@ limitations under the License. -->
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectors-item" v-if="key === 2 || key === 4">
|
<div class="selectors-item" v-if="key === 5">
|
||||||
|
<span class="label"> $Process </span>
|
||||||
|
<Selector
|
||||||
|
v-model="states.currentProcess"
|
||||||
|
:options="selectorStore.processes"
|
||||||
|
size="small"
|
||||||
|
placeholder="Select a data"
|
||||||
|
@change="changeProcess"
|
||||||
|
class="selectors"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-h" :class="isRelation ? 'relation' : ''">
|
||||||
|
<div class="selectors-item" v-if="key === 2 || key === 4 || key === 5">
|
||||||
<span class="label">$DestinationService</span>
|
<span class="label">$DestinationService</span>
|
||||||
<Selector
|
<Selector
|
||||||
v-model="states.currentDestService"
|
v-model="states.currentDestService"
|
||||||
@ -58,7 +72,7 @@ limitations under the License. -->
|
|||||||
class="selectors"
|
class="selectors"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectors-item" v-if="key === 4">
|
<div class="selectors-item" v-if="key === 4 || key === 5">
|
||||||
<span class="label">
|
<span class="label">
|
||||||
{{
|
{{
|
||||||
dashboardStore.entity === "EndpointRelation"
|
dashboardStore.entity === "EndpointRelation"
|
||||||
@ -77,9 +91,21 @@ limitations under the License. -->
|
|||||||
:isRemote="dashboardStore.entity === 'EndpointRelation'"
|
:isRemote="dashboardStore.entity === 'EndpointRelation'"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="selectors-item" v-if="key === 5">
|
||||||
|
<span class="label"> $DestinationProcess </span>
|
||||||
|
<Selector
|
||||||
|
v-model="states.currentDestProcess"
|
||||||
|
:options="selectorStore.destProcesses"
|
||||||
|
size="small"
|
||||||
|
placeholder="Select a data"
|
||||||
|
@change="changeDestProcess"
|
||||||
|
class="selectors"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-h tools" v-loading="loading" v-if="!appStore.isMobile">
|
<div class="flex-h tools" v-loading="loading" v-if="!appStore.isMobile">
|
||||||
<div class="tool-icons flex-h" v-if="dashboardStore.editMode">
|
<div class="tool-icons" v-if="dashboardStore.editMode">
|
||||||
<el-dropdown content="Controls" placement="bottom" :persistent="false">
|
<el-dropdown content="Controls" placement="bottom" :persistent="false">
|
||||||
<i>
|
<i>
|
||||||
<Icon class="icon-btn" size="sm" iconName="control" />
|
<Icon class="icon-btn" size="sm" iconName="control" />
|
||||||
@ -133,6 +159,7 @@ import {
|
|||||||
EndpointRelationTools,
|
EndpointRelationTools,
|
||||||
InstanceRelationTools,
|
InstanceRelationTools,
|
||||||
ServiceRelationTools,
|
ServiceRelationTools,
|
||||||
|
ProcessTools,
|
||||||
} from "../data";
|
} from "../data";
|
||||||
import { useSelectorStore } from "@/store/modules/selectors";
|
import { useSelectorStore } from "@/store/modules/selectors";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
@ -144,9 +171,8 @@ const dashboardStore = useDashboardStore();
|
|||||||
const selectorStore = useSelectorStore();
|
const selectorStore = useSelectorStore();
|
||||||
const appStore = useAppStoreWithOut();
|
const appStore = useAppStoreWithOut();
|
||||||
const params = useRoute().params;
|
const params = useRoute().params;
|
||||||
const toolIcons = ref<{ name: string; content: string; id: string }[]>(
|
const toolIcons =
|
||||||
EndpointRelationTools
|
ref<{ name: string; content: string; id: string }[]>(AllTools);
|
||||||
);
|
|
||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
const states = reactive<{
|
const states = reactive<{
|
||||||
destService: string;
|
destService: string;
|
||||||
@ -154,16 +180,20 @@ const states = reactive<{
|
|||||||
key: number;
|
key: number;
|
||||||
currentService: string;
|
currentService: string;
|
||||||
currentPod: string;
|
currentPod: string;
|
||||||
|
currentProcess: string;
|
||||||
currentDestService: string;
|
currentDestService: string;
|
||||||
currentDestPod: string;
|
currentDestPod: string;
|
||||||
|
currentDestProcess: string;
|
||||||
}>({
|
}>({
|
||||||
destService: "",
|
destService: "",
|
||||||
destPod: "",
|
destPod: "",
|
||||||
key: 0,
|
key: 0,
|
||||||
currentService: "",
|
currentService: "",
|
||||||
currentPod: "",
|
currentPod: "",
|
||||||
|
currentProcess: "",
|
||||||
currentDestService: "",
|
currentDestService: "",
|
||||||
currentDestPod: "",
|
currentDestPod: "",
|
||||||
|
currentDestProcess: "",
|
||||||
});
|
});
|
||||||
const key = computed(() => {
|
const key = computed(() => {
|
||||||
const type = EntityType.find(
|
const type = EntityType.find(
|
||||||
@ -172,6 +202,14 @@ const key = computed(() => {
|
|||||||
return (type && type.key) || 0;
|
return (type && type.key) || 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isRelation = computed(() => {
|
||||||
|
return [
|
||||||
|
EntityType[7].value,
|
||||||
|
EntityType[6].value,
|
||||||
|
EntityType[5].value,
|
||||||
|
].includes(dashboardStore.entity);
|
||||||
|
});
|
||||||
|
|
||||||
setCurrentDashboard();
|
setCurrentDashboard();
|
||||||
appStore.setEventStack([initSelector]);
|
appStore.setEventStack([initSelector]);
|
||||||
initSelector();
|
initSelector();
|
||||||
@ -199,6 +237,7 @@ async function setSelector() {
|
|||||||
EntityType[3].value,
|
EntityType[3].value,
|
||||||
EntityType[5].value,
|
EntityType[5].value,
|
||||||
EntityType[6].value,
|
EntityType[6].value,
|
||||||
|
EntityType[7].value,
|
||||||
].includes(String(params.entity))
|
].includes(String(params.entity))
|
||||||
) {
|
) {
|
||||||
setSourceSelector();
|
setSourceSelector();
|
||||||
@ -252,6 +291,7 @@ async function setSourceSelector() {
|
|||||||
if (!(selectorStore.pods.length && selectorStore.pods[0])) {
|
if (!(selectorStore.pods.length && selectorStore.pods[0])) {
|
||||||
selectorStore.setCurrentPod(null);
|
selectorStore.setCurrentPod(null);
|
||||||
states.currentPod = "";
|
states.currentPod = "";
|
||||||
|
states.currentProcess = "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const pod = params.podId || selectorStore.pods[0].id;
|
const pod = params.podId || selectorStore.pods[0].id;
|
||||||
@ -263,9 +303,25 @@ async function setSourceSelector() {
|
|||||||
} else {
|
} else {
|
||||||
currentPod = selectorStore.pods.find((d: { id: string }) => d.id === pod);
|
currentPod = selectorStore.pods.find((d: { id: string }) => d.id === pod);
|
||||||
}
|
}
|
||||||
if (currentPod) {
|
if (!currentPod) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
selectorStore.setCurrentPod(currentPod);
|
selectorStore.setCurrentPod(currentPod);
|
||||||
states.currentPod = currentPod.label;
|
states.currentPod = currentPod.label;
|
||||||
|
const process = params.processId || selectorStore.processes[0].id;
|
||||||
|
let currentProcess;
|
||||||
|
if (states.currentProcess) {
|
||||||
|
currentProcess = selectorStore.processes.find(
|
||||||
|
(d: { label: string }) => d.label === states.currentProcess
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
currentProcess = selectorStore.processes.find(
|
||||||
|
(d: { id: string }) => d.id === process
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (currentProcess) {
|
||||||
|
selectorStore.setCurrentProcess(currentProcess);
|
||||||
|
states.currentProcess = currentProcess.label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,9 +349,25 @@ async function setDestSelector() {
|
|||||||
(d: { id: string }) => d.id === destPod
|
(d: { id: string }) => d.id === destPod
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (currentDestPod) {
|
if (!currentDestPod) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
selectorStore.setCurrentDestPod(currentDestPod);
|
selectorStore.setCurrentDestPod(currentDestPod);
|
||||||
states.currentDestPod = currentDestPod.label;
|
states.currentDestPod = currentDestPod.label;
|
||||||
|
const destProcess = params.destProcessId || selectorStore.destProcesses[0].id;
|
||||||
|
let currentDestProcess;
|
||||||
|
if (states.currentDestProcess) {
|
||||||
|
currentDestProcess = selectorStore.destProcesses.find(
|
||||||
|
(d: { label: string }) => d.label === states.currentProcess
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
currentDestProcess = selectorStore.destProcesses.find(
|
||||||
|
(d: { id: string }) => d.id === destProcess
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (currentDestProcess) {
|
||||||
|
selectorStore.setCurrentProcess(currentDestProcess);
|
||||||
|
states.currentProcess = currentDestProcess.label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,16 +397,21 @@ async function getServices() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
selectorStore.setCurrentService(s || null);
|
selectorStore.setCurrentService(s || null);
|
||||||
let d;
|
let d,
|
||||||
|
val = 1;
|
||||||
|
if (key.value === 5) {
|
||||||
|
val = 0;
|
||||||
|
}
|
||||||
if (states.currentService) {
|
if (states.currentService) {
|
||||||
d = (selectorStore.services || []).find(
|
d = (selectorStore.services || []).find(
|
||||||
(d: { label: string }) => d.label === states.currentDestService
|
(d: { label: string }) => d.label === states.currentDestService
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
d = (selectorStore.services || []).find(
|
d = (selectorStore.services || []).find(
|
||||||
(d: unknown, index: number) => index === 1
|
(d: unknown, index: number) => index === val
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
selectorStore.setCurrentDestService(d || null);
|
selectorStore.setCurrentDestService(d || null);
|
||||||
if (!selectorStore.currentService) {
|
if (!selectorStore.currentService) {
|
||||||
return;
|
return;
|
||||||
@ -347,62 +424,84 @@ async function getServices() {
|
|||||||
EntityType[3].value,
|
EntityType[3].value,
|
||||||
EntityType[5].value,
|
EntityType[5].value,
|
||||||
EntityType[6].value,
|
EntityType[6].value,
|
||||||
|
EntityType[7].value,
|
||||||
].includes(dashboardStore.entity)
|
].includes(dashboardStore.entity)
|
||||||
) {
|
) {
|
||||||
fetchPods(e, selectorStore.currentService.id, true);
|
await fetchPods(e, selectorStore.currentService.id, true);
|
||||||
}
|
}
|
||||||
if (!selectorStore.currentDestService) {
|
if (!selectorStore.currentDestService) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
states.currentDestService = selectorStore.currentDestService.value;
|
states.currentDestService = selectorStore.currentDestService.value;
|
||||||
if (
|
if (
|
||||||
[EntityType[5].value, EntityType[6].value].includes(dashboardStore.entity)
|
[EntityType[5].value, EntityType[6].value, EntityType[7].value].includes(
|
||||||
|
dashboardStore.entity
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
fetchPods(dashboardStore.entity, selectorStore.currentDestService.id, true);
|
await fetchPods(
|
||||||
|
dashboardStore.entity,
|
||||||
|
selectorStore.currentDestService.id,
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function changeService(service: any) {
|
async function changeService(service: Option[]) {
|
||||||
if (service[0]) {
|
if (service[0]) {
|
||||||
states.currentService = service[0].value;
|
states.currentService = service[0].value;
|
||||||
selectorStore.setCurrentService(service[0]);
|
selectorStore.setCurrentService(service[0]);
|
||||||
const e = dashboardStore.entity.split("Relation")[0];
|
|
||||||
selectorStore.setCurrentPod(null);
|
selectorStore.setCurrentPod(null);
|
||||||
states.currentPod = "";
|
states.currentPod = "";
|
||||||
fetchPods(e, selectorStore.currentService.id, true);
|
states.currentProcess = "";
|
||||||
|
if (dashboardStore.entity === EntityType[7].value) {
|
||||||
|
fetchPods("Process", selectorStore.currentService.id, true);
|
||||||
|
} else {
|
||||||
|
fetchPods(dashboardStore.entity, selectorStore.currentService.id, true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
selectorStore.setCurrentService(null);
|
selectorStore.setCurrentService(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeDestService(service: any) {
|
function changeDestService(service: Option[]) {
|
||||||
if (service[0]) {
|
if (service[0]) {
|
||||||
states.currentDestService = service[0].value;
|
states.currentDestService = service[0].value;
|
||||||
selectorStore.setCurrentDestService(service[0]);
|
selectorStore.setCurrentDestService(service[0]);
|
||||||
selectorStore.setCurrentDestPod(null);
|
selectorStore.setCurrentDestPod(null);
|
||||||
states.currentDestPod = "";
|
states.currentDestPod = "";
|
||||||
|
states.currentDestProcess = "";
|
||||||
fetchPods(dashboardStore.entity, selectorStore.currentDestService.id, true);
|
fetchPods(dashboardStore.entity, selectorStore.currentDestService.id, true);
|
||||||
} else {
|
} else {
|
||||||
selectorStore.setCurrentDestService(null);
|
selectorStore.setCurrentDestService(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePods(pod: any) {
|
async function changePods(pod: Option[]) {
|
||||||
if (pod[0]) {
|
selectorStore.setCurrentPod(pod[0] || null);
|
||||||
selectorStore.setCurrentPod(pod[0]);
|
if (dashboardStore.entity === EntityType[7].value) {
|
||||||
} else {
|
selectorStore.setCurrentProcess(null);
|
||||||
selectorStore.setCurrentPod("");
|
states.currentProcess = "";
|
||||||
|
fetchProcess(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeDestPods(pod: any) {
|
function changeDestPods(pod: Option[]) {
|
||||||
if (pod[0]) {
|
selectorStore.setCurrentDestPod(pod[0] || null);
|
||||||
selectorStore.setCurrentDestPod(pod[0]);
|
if (dashboardStore.entity === EntityType[7].value) {
|
||||||
} else {
|
selectorStore.setCurrentDestProcess(null);
|
||||||
selectorStore.setCurrentDestPod(null);
|
states.currentDestProcess = "";
|
||||||
|
fetchDestProcess(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeDestProcess(pod: Option[]) {
|
||||||
|
selectorStore.setCurrentDestProcess(pod[0] || null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeProcess(pod: Option[]) {
|
||||||
|
selectorStore.setCurrentProcess(pod[0] || null);
|
||||||
|
}
|
||||||
|
|
||||||
function changeMode() {
|
function changeMode() {
|
||||||
if (dashboardStore.editMode) {
|
if (dashboardStore.editMode) {
|
||||||
ElMessage.warning(t("editWarning"));
|
ElMessage.warning(t("editWarning"));
|
||||||
@ -461,6 +560,9 @@ function setTabControls(id: string) {
|
|||||||
case "addEvent":
|
case "addEvent":
|
||||||
dashboardStore.addTabControls("Event");
|
dashboardStore.addTabControls("Event");
|
||||||
break;
|
break;
|
||||||
|
case "addTimeRange":
|
||||||
|
dashboardStore.addTabControls("TimeRange");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ElMessage.info("Don't support this control");
|
ElMessage.info("Don't support this control");
|
||||||
break;
|
break;
|
||||||
@ -499,6 +601,9 @@ function setControls(id: string) {
|
|||||||
case "addEvent":
|
case "addEvent":
|
||||||
dashboardStore.addControl("Event");
|
dashboardStore.addControl("Event");
|
||||||
break;
|
break;
|
||||||
|
case "addTimeRange":
|
||||||
|
dashboardStore.addControl("TimeRange");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dashboardStore.addControl("Widget");
|
dashboardStore.addControl("Widget");
|
||||||
}
|
}
|
||||||
@ -587,6 +692,14 @@ async function fetchPods(
|
|||||||
states.currentDestPod = selectorStore.currentDestPod.label;
|
states.currentDestPod = selectorStore.currentDestPod.label;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case EntityType[7].value:
|
||||||
|
await fetchPods(EntityType[5].value, serviceId, setPod, param);
|
||||||
|
resp = await fetchDestProcess(setPod);
|
||||||
|
break;
|
||||||
|
case "Process":
|
||||||
|
await fetchPods(EntityType[3].value, serviceId, setPod, param);
|
||||||
|
resp = await fetchProcess(setPod);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
resp = {};
|
resp = {};
|
||||||
}
|
}
|
||||||
@ -594,6 +707,48 @@ async function fetchPods(
|
|||||||
ElMessage.error(resp.errors);
|
ElMessage.error(resp.errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchProcess(setPod: boolean) {
|
||||||
|
const resp = await selectorStore.getProcesses({
|
||||||
|
instanceId: selectorStore.currentPod.id,
|
||||||
|
});
|
||||||
|
if (setPod) {
|
||||||
|
let m;
|
||||||
|
if (states.currentProcess) {
|
||||||
|
m = selectorStore.processes.find(
|
||||||
|
(d: { label: string }) => d.label === states.currentProcess
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
m = selectorStore.processes.find(
|
||||||
|
(d: { label: string }, index: number) => index === 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
selectorStore.setCurrentProcess(m || null);
|
||||||
|
states.currentProcess = m && m.label;
|
||||||
|
}
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
async function fetchDestProcess(setPod: boolean) {
|
||||||
|
const resp = await selectorStore.getProcesses({
|
||||||
|
instanceId: selectorStore.currentDestPod.id,
|
||||||
|
isRelation: true,
|
||||||
|
});
|
||||||
|
if (setPod) {
|
||||||
|
let m;
|
||||||
|
if (states.currentDestProcess) {
|
||||||
|
m = selectorStore.destProcesses.find(
|
||||||
|
(d: { label: string }) => d.label === states.currentDestProcess
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
m = selectorStore.destProcesses.find(
|
||||||
|
(d: { label: string }, index: number) => index === 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
selectorStore.setCurrentDestProcess(m || null);
|
||||||
|
states.currentDestProcess = m && m.label;
|
||||||
|
}
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
function getTools() {
|
function getTools() {
|
||||||
switch (params.entity) {
|
switch (params.entity) {
|
||||||
case EntityType[1].value:
|
case EntityType[1].value:
|
||||||
@ -617,8 +772,11 @@ function getTools() {
|
|||||||
case EntityType[6].value:
|
case EntityType[6].value:
|
||||||
toolIcons.value = EndpointRelationTools;
|
toolIcons.value = EndpointRelationTools;
|
||||||
break;
|
break;
|
||||||
|
case EntityType[7].value:
|
||||||
|
toolIcons.value = ProcessTools;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
toolIcons.value = EndpointRelationTools;
|
toolIcons.value = AllTools;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function searchPods(query: string) {
|
function searchPods(query: string) {
|
||||||
@ -701,4 +859,8 @@ watch(
|
|||||||
.selectorPod {
|
.selectorPod {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.relation {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -18,7 +18,7 @@ import icons from "@/assets/img/icons";
|
|||||||
import { Node } from "@/types/topology";
|
import { Node } from "@/types/topology";
|
||||||
|
|
||||||
icons["KAFKA-CONSUMER"] = icons.KAFKA;
|
icons["KAFKA-CONSUMER"] = icons.KAFKA;
|
||||||
export default (d3: any, graph: any, funcs: any, tip: any, legend: any) => {
|
export default (d3: any, graph: any, funcs: any, tip: any, legend?: any) => {
|
||||||
const nodeEnter = graph
|
const nodeEnter = graph
|
||||||
.append("g")
|
.append("g")
|
||||||
.call(
|
.call(
|
82
src/views/dashboard/related/components/TaskDetails.vue
Normal file
82
src/views/dashboard/related/components/TaskDetails.vue
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<!-- 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>
|
||||||
|
<div class="profile-detail flex-v">
|
||||||
|
<div>
|
||||||
|
<h5 class="mb-10">{{ t("task") }}.</h5>
|
||||||
|
<div class="mb-10 clear item">
|
||||||
|
<span class="g-sm-4 grey">{{ t("taskId") }}:</span>
|
||||||
|
<span class="g-sm-8 wba">
|
||||||
|
{{ details.taskId }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-10 clear item">
|
||||||
|
<span class="g-sm-4 grey">{{ t("service") }}:</span>
|
||||||
|
<span class="g-sm-8 wba">
|
||||||
|
{{ details.serviceName }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-10 clear item">
|
||||||
|
<span class="g-sm-4 grey">{{ t("labels") }}:</span>
|
||||||
|
<span class="g-sm-8 wba">
|
||||||
|
{{ details.processLabels.join(";") }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-10 clear item">
|
||||||
|
<span class="g-sm-4 grey">{{ t("monitorTime") }}:</span>
|
||||||
|
<span class="g-sm-8 wba">
|
||||||
|
{{ dateFormat(details.taskStartTime) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-10 clear item">
|
||||||
|
<span class="g-sm-4 grey">{{ t("monitorDuration") }}:</span>
|
||||||
|
<span class="g-sm-8 wba">
|
||||||
|
{{ details.fixedTriggerDuration / 60 }} min
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-10 clear item">
|
||||||
|
<span class="g-sm-4 grey">{{ t("triggerType") }}:</span>
|
||||||
|
<span class="g-sm-8 wba">{{ details.triggerType }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-10 clear item">
|
||||||
|
<span class="g-sm-4 grey">{{ t("targetType") }}:</span>
|
||||||
|
<span class="g-sm-8 wba">{{ details.targetType }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
import type { PropType } from "vue";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { EBPFTaskList } from "@/types/ebpf";
|
||||||
|
|
||||||
|
/*global defineProps */
|
||||||
|
defineProps({
|
||||||
|
details: {
|
||||||
|
type: Object as PropType<EBPFTaskList>,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { t } = useI18n();
|
||||||
|
const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
|
||||||
|
dayjs(date).format(pattern);
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.item span {
|
||||||
|
height: 21px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -152,7 +152,6 @@ const keywordsOfContent = ref<string[]>([]);
|
|||||||
const excludingKeywordsOfContent = ref<string[]>([]);
|
const excludingKeywordsOfContent = ref<string[]>([]);
|
||||||
const contentStr = ref<string>("");
|
const contentStr = ref<string>("");
|
||||||
const excludingContentStr = ref<string>("");
|
const excludingContentStr = ref<string>("");
|
||||||
// const limit = ref<number>(20);
|
|
||||||
const state = reactive<any>({
|
const state = reactive<any>({
|
||||||
instance: { value: "", label: "" },
|
instance: { value: "", label: "" },
|
||||||
container: { value: "", label: "" },
|
container: { value: "", label: "" },
|
||||||
|
@ -57,7 +57,10 @@ if (props.needQuery) {
|
|||||||
async function searchTasks() {
|
async function searchTasks() {
|
||||||
const serviceId =
|
const serviceId =
|
||||||
(selectorStore.currentService && selectorStore.currentService.id) || "";
|
(selectorStore.currentService && selectorStore.currentService.id) || "";
|
||||||
const res = await ebpfStore.getTaskList(serviceId);
|
const res = await ebpfStore.getTaskList({
|
||||||
|
serviceId,
|
||||||
|
targets: ["ON_CPU", "OFF_CPU"],
|
||||||
|
});
|
||||||
|
|
||||||
if (res.errors) {
|
if (res.errors) {
|
||||||
ElMessage.error(res.errors);
|
ElMessage.error(res.errors);
|
||||||
|
@ -79,7 +79,7 @@ limitations under the License. -->
|
|||||||
/>
|
/>
|
||||||
<el-table-column width="300" label="Attributes">
|
<el-table-column width="300" label="Attributes">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{ scope.row.attributes.map((d: {name: string, value: string}) => `${d.name}=${d.value}`).join("; ") }}
|
{{ attributes(scope.row.attributes) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -125,6 +125,11 @@ const aggregateType = ref<string>(AggregateTypes[0].value);
|
|||||||
const duration = ref<string[]>([]);
|
const duration = ref<string[]>([]);
|
||||||
const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
|
const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
|
||||||
dayjs(date).format(pattern);
|
dayjs(date).format(pattern);
|
||||||
|
const attributes = (attr: { name: string; value: string }[]) => {
|
||||||
|
return attr
|
||||||
|
.map((d: { name: string; value: string }) => `${d.name}=${d.value}`)
|
||||||
|
.join("; ");
|
||||||
|
};
|
||||||
|
|
||||||
function changeLabels(opt: any[]) {
|
function changeLabels(opt: any[]) {
|
||||||
const arr = opt.map((d) => d.value);
|
const arr = opt.map((d) => d.value);
|
||||||
|
@ -30,7 +30,7 @@ limitations under the License. -->
|
|||||||
<td
|
<td
|
||||||
class="profile-td"
|
class="profile-td"
|
||||||
:class="{
|
:class="{
|
||||||
selected: selectedTask.taskId === i.taskId,
|
selected: ebpfStore.selectedTask.taskId === i.taskId,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="ell">
|
<div class="ell">
|
||||||
@ -67,66 +67,25 @@ limitations under the License. -->
|
|||||||
fullscreen
|
fullscreen
|
||||||
@closed="viewDetail = false"
|
@closed="viewDetail = false"
|
||||||
>
|
>
|
||||||
<div class="profile-detail flex-v">
|
<TaskDetails :details="ebpfStore.selectedTask" />
|
||||||
<div>
|
|
||||||
<h5 class="mb-10">{{ t("task") }}.</h5>
|
|
||||||
<div class="mb-10 clear item">
|
|
||||||
<span class="g-sm-4 grey">{{ t("taskId") }}:</span>
|
|
||||||
<span class="g-sm-8 wba">
|
|
||||||
{{ selectedTask.taskId }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="mb-10 clear item">
|
|
||||||
<span class="g-sm-4 grey">{{ t("service") }}:</span>
|
|
||||||
<span class="g-sm-8 wba">{{ selectedTask.serviceName }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="mb-10 clear item">
|
|
||||||
<span class="g-sm-4 grey">{{ t("labels") }}:</span>
|
|
||||||
<span class="g-sm-8 wba">
|
|
||||||
{{ selectedTask.processLabels.join(";") }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="mb-10 clear item">
|
|
||||||
<span class="g-sm-4 grey">{{ t("monitorTime") }}:</span>
|
|
||||||
<span class="g-sm-8 wba">
|
|
||||||
{{ dateFormat(selectedTask.taskStartTime) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="mb-10 clear item">
|
|
||||||
<span class="g-sm-4 grey">{{ t("monitorDuration") }}:</span>
|
|
||||||
<span class="g-sm-8 wba">
|
|
||||||
{{ selectedTask.fixedTriggerDuration / 60 }} min
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="mb-10 clear item">
|
|
||||||
<span class="g-sm-4 grey">{{ t("triggerType") }}:</span>
|
|
||||||
<span class="g-sm-8 wba">{{ selectedTask.triggerType }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="mb-10 clear item">
|
|
||||||
<span class="g-sm-4 grey">{{ t("targetType") }}:</span>
|
|
||||||
<span class="g-sm-8 wba">{{ selectedTask.targetType }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, watch } from "vue";
|
import { ref } from "vue";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useEbpfStore } from "@/store/modules/ebpf";
|
import { useEbpfStore } from "@/store/modules/ebpf";
|
||||||
import { EBPFTaskList } from "@/types/ebpf";
|
import { EBPFTaskList } from "@/types/ebpf";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
import TaskDetails from "../../components/TaskDetails.vue";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const ebpfStore = useEbpfStore();
|
const ebpfStore = useEbpfStore();
|
||||||
const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
|
const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
|
||||||
dayjs(date).format(pattern);
|
dayjs(date).format(pattern);
|
||||||
const selectedTask = ref<EBPFTaskList | Record<string, never>>({});
|
|
||||||
const viewDetail = ref<boolean>(false);
|
const viewDetail = ref<boolean>(false);
|
||||||
|
|
||||||
async function changeTask(item: EBPFTaskList) {
|
async function changeTask(item: EBPFTaskList) {
|
||||||
selectedTask.value = item;
|
|
||||||
ebpfStore.setSelectedTask(item);
|
ebpfStore.setSelectedTask(item);
|
||||||
const res = await ebpfStore.getEBPFSchedules({
|
const res = await ebpfStore.getEBPFSchedules({
|
||||||
taskId: item.taskId,
|
taskId: item.taskId,
|
||||||
@ -135,13 +94,6 @@ async function changeTask(item: EBPFTaskList) {
|
|||||||
ElMessage.error(res.errors);
|
ElMessage.error(res.errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
watch(
|
|
||||||
() => ebpfStore.taskList,
|
|
||||||
() => {
|
|
||||||
selectedTask.value = ebpfStore.taskList[0] || {};
|
|
||||||
ebpfStore.setSelectedTask(selectedTask.value);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.profile-task-list {
|
.profile-task-list {
|
||||||
|
@ -146,10 +146,10 @@ async function queryEvents() {
|
|||||||
let endpoint = state.endpoint.value,
|
let endpoint = state.endpoint.value,
|
||||||
instance = state.instance.value;
|
instance = state.instance.value;
|
||||||
if (dashboardStore.entity === EntityType[2].value) {
|
if (dashboardStore.entity === EntityType[2].value) {
|
||||||
endpoint = selectorStore.currentPod.id;
|
endpoint = selectorStore.currentPod && selectorStore.currentPod.id;
|
||||||
}
|
}
|
||||||
if (dashboardStore.entity === EntityType[3].value) {
|
if (dashboardStore.entity === EntityType[3].value) {
|
||||||
instance = selectorStore.currentPod.id;
|
instance = selectorStore.currentPod && selectorStore.currentPod.id;
|
||||||
}
|
}
|
||||||
if (!selectorStore.currentService) {
|
if (!selectorStore.currentService) {
|
||||||
return;
|
return;
|
||||||
|
@ -94,10 +94,17 @@ import {
|
|||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
import d3tip from "d3-tip";
|
import d3tip from "d3-tip";
|
||||||
import zoom from "../utils/zoom";
|
import zoom from "../../components/D3Graph/zoom";
|
||||||
import { simulationInit, simulationSkip } from "../utils/simulation";
|
import {
|
||||||
import nodeElement from "../utils/nodeElement";
|
simulationInit,
|
||||||
import { linkElement, anchorElement, arrowMarker } from "../utils/linkElement";
|
simulationSkip,
|
||||||
|
} from "../../components/D3Graph/simulation";
|
||||||
|
import nodeElement from "../../components/D3Graph/nodeElement";
|
||||||
|
import {
|
||||||
|
linkElement,
|
||||||
|
anchorElement,
|
||||||
|
arrowMarker,
|
||||||
|
} from "../../components/D3Graph/linkElement";
|
||||||
import { Node, Call } from "@/types/topology";
|
import { Node, Call } from "@/types/topology";
|
||||||
import { useSelectorStore } from "@/store/modules/selectors";
|
import { useSelectorStore } from "@/store/modules/selectors";
|
||||||
import { useTopologyStore } from "@/store/modules/topology";
|
import { useTopologyStore } from "@/store/modules/topology";
|
||||||
|
Loading…
Reference in New Issue
Block a user