mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-18 15:25:24 +00:00
add ebpf
This commit is contained in:
parent
91aeb45604
commit
493ec4bec2
@ -32,7 +32,7 @@ interface Option {
|
||||
const emit = defineEmits(["change"]);
|
||||
const props = defineProps({
|
||||
options: {
|
||||
type: Array as PropType<(Option & { disabled: boolean })[]>,
|
||||
type: Array as PropType<Option[]>,
|
||||
default: () => [],
|
||||
},
|
||||
value: {
|
||||
@ -44,7 +44,7 @@ const props = defineProps({
|
||||
|
||||
const selected = ref<string>(props.value);
|
||||
|
||||
function checked(opt: string) {
|
||||
function checked(opt: unknown) {
|
||||
emit("change", opt);
|
||||
}
|
||||
</script>
|
||||
|
@ -0,0 +1,227 @@
|
||||
/**
|
||||
* 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 { Duration, Option } from "@/types/app";
|
||||
import { Endpoint } from "@/types/selector";
|
||||
import {
|
||||
TaskListItem,
|
||||
SegmentSpan,
|
||||
ProfileAnalyzationTrees,
|
||||
TaskLog,
|
||||
ProfileTaskCreationRequest,
|
||||
} from "@/types/profile";
|
||||
import { Trace, Span } from "@/types/trace";
|
||||
import { store } from "@/store";
|
||||
import graphql from "@/graphql";
|
||||
import { AxiosResponse } from "axios";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
|
||||
interface EbpfStore {
|
||||
endpoints: Endpoint[];
|
||||
taskEndpoints: Endpoint[];
|
||||
durationTime: Duration;
|
||||
condition: { serviceId: string; endpointName: string };
|
||||
taskList: TaskListItem[];
|
||||
segmentList: Trace[];
|
||||
currentSegment: Trace | Record<string, never>;
|
||||
segmentSpans: SegmentSpan[];
|
||||
currentSpan: SegmentSpan | Record<string, never>;
|
||||
analyzeTrees: ProfileAnalyzationTrees;
|
||||
taskLogs: TaskLog[];
|
||||
highlightTop: boolean;
|
||||
labels: Option[];
|
||||
}
|
||||
|
||||
export const ebpfStore = defineStore({
|
||||
id: "profile",
|
||||
state: (): EbpfStore => ({
|
||||
endpoints: [{ value: "", label: "All" }],
|
||||
taskEndpoints: [{ value: "", label: "All" }],
|
||||
durationTime: useAppStoreWithOut().durationTime,
|
||||
condition: { serviceId: "", endpointName: "" },
|
||||
taskList: [],
|
||||
segmentList: [],
|
||||
currentSegment: {},
|
||||
segmentSpans: [],
|
||||
currentSpan: {},
|
||||
analyzeTrees: [],
|
||||
taskLogs: [],
|
||||
highlightTop: true,
|
||||
labels: [{ value: "", label: "" }],
|
||||
}),
|
||||
actions: {
|
||||
setConditions(data: { serviceId?: string; endpointName?: string }) {
|
||||
this.condition = {
|
||||
...this.condition,
|
||||
...data,
|
||||
};
|
||||
},
|
||||
setCurrentSpan(span: Span) {
|
||||
this.currentSpan = span;
|
||||
},
|
||||
setCurrentSegment(s: Trace) {
|
||||
this.currentSegment = s;
|
||||
},
|
||||
setHighlightTop() {
|
||||
this.highlightTop = !this.highlightTop;
|
||||
},
|
||||
async getEndpoints(serviceId: string, keyword?: string) {
|
||||
const res: AxiosResponse = await graphql.query("queryEndpoints").params({
|
||||
serviceId,
|
||||
duration: this.durationTime,
|
||||
keyword: keyword || "",
|
||||
});
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
}
|
||||
this.endpoints = [{ value: "", label: "All" }, ...res.data.data.pods];
|
||||
return res.data;
|
||||
},
|
||||
async getTaskEndpoints(serviceId: string, keyword?: string) {
|
||||
const res: AxiosResponse = await graphql.query("queryEndpoints").params({
|
||||
serviceId,
|
||||
duration: this.durationTime,
|
||||
keyword: keyword || "",
|
||||
});
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
}
|
||||
this.taskEndpoints = [{ value: "", label: "All" }, ...res.data.data.pods];
|
||||
return res.data;
|
||||
},
|
||||
async getTaskList() {
|
||||
const res: AxiosResponse = await graphql
|
||||
.query("getProfileTaskList")
|
||||
.params(this.condition);
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
}
|
||||
const list = res.data.data.taskList;
|
||||
this.taskList = list;
|
||||
if (!list.length) {
|
||||
this.segmentList = [];
|
||||
this.segmentSpans = [];
|
||||
this.analyzeTrees = [];
|
||||
|
||||
return res.data;
|
||||
}
|
||||
this.getSegmentList({ taskID: list[0].id });
|
||||
return res.data;
|
||||
},
|
||||
async getSegmentList(params: { taskID: string }) {
|
||||
const res: AxiosResponse = await graphql
|
||||
.query("getProfileTaskSegmentList")
|
||||
.params(params);
|
||||
|
||||
if (res.data.errors) {
|
||||
this.segmentList = [];
|
||||
return res.data;
|
||||
}
|
||||
const { segmentList } = res.data.data;
|
||||
|
||||
this.segmentList = segmentList;
|
||||
if (!segmentList.length) {
|
||||
this.segmentSpans = [];
|
||||
this.analyzeTrees = [];
|
||||
|
||||
return res.data;
|
||||
}
|
||||
if (segmentList[0]) {
|
||||
this.currentSegment = segmentList[0];
|
||||
this.getSegmentSpans({ segmentId: segmentList[0].segmentId });
|
||||
} else {
|
||||
this.currentSegment = null;
|
||||
}
|
||||
return res.data;
|
||||
},
|
||||
async getSegmentSpans(params: { segmentId: string }) {
|
||||
const res: AxiosResponse = await graphql
|
||||
.query("queryProfileSegment")
|
||||
.params(params);
|
||||
if (res.data.errors) {
|
||||
this.segmentSpans = [];
|
||||
return res.data;
|
||||
}
|
||||
const { segment } = res.data.data;
|
||||
if (!segment) {
|
||||
this.segmentSpans = [];
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
}
|
||||
this.segmentSpans = segment.spans;
|
||||
if (!(segment.spans && segment.spans.length)) {
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
}
|
||||
const index = segment.spans.length - 1 || 0;
|
||||
this.currentSpan = segment.spans[index];
|
||||
return res.data;
|
||||
},
|
||||
async getProfileAnalyze(params: {
|
||||
segmentId: string;
|
||||
timeRanges: Array<{ start: number; end: number }>;
|
||||
}) {
|
||||
const res: AxiosResponse = await graphql
|
||||
.query("getProfileAnalyze")
|
||||
.params(params);
|
||||
|
||||
if (res.data.errors) {
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
}
|
||||
const { analyze, tip } = res.data.data;
|
||||
if (tip) {
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
}
|
||||
|
||||
if (!analyze) {
|
||||
this.analyzeTrees = [];
|
||||
return res.data;
|
||||
}
|
||||
this.analyzeTrees = analyze.trees;
|
||||
return res.data;
|
||||
},
|
||||
async createTask(param: ProfileTaskCreationRequest) {
|
||||
const res: AxiosResponse = await graphql
|
||||
.query("saveProfileTask")
|
||||
.params({ creationRequest: param });
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
}
|
||||
this.getTaskList();
|
||||
return res.data;
|
||||
},
|
||||
async getTaskLogs(param: { taskID: string }) {
|
||||
const res: AxiosResponse = await graphql
|
||||
.query("getProfileTaskLogs")
|
||||
.params(param);
|
||||
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
}
|
||||
this.taskLogs = res.data.data.taskLogs;
|
||||
return res.data;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export function useEbpfStore(): any {
|
||||
return ebpfStore(store);
|
||||
}
|
@ -32,6 +32,7 @@ import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
|
||||
interface ProfileState {
|
||||
endpoints: Endpoint[];
|
||||
taskEndpoints: Endpoint[];
|
||||
durationTime: Duration;
|
||||
condition: { serviceId: string; endpointName: string };
|
||||
taskList: TaskListItem[];
|
||||
@ -48,6 +49,7 @@ export const profileStore = defineStore({
|
||||
id: "profile",
|
||||
state: (): ProfileState => ({
|
||||
endpoints: [{ value: "", label: "All" }],
|
||||
taskEndpoints: [{ value: "", label: "All" }],
|
||||
durationTime: useAppStoreWithOut().durationTime,
|
||||
condition: { serviceId: "", endpointName: "" },
|
||||
taskList: [],
|
||||
@ -87,6 +89,18 @@ export const profileStore = defineStore({
|
||||
this.endpoints = [{ value: "", label: "All" }, ...res.data.data.pods];
|
||||
return res.data;
|
||||
},
|
||||
async getTaskEndpoints(serviceId: string, keyword?: string) {
|
||||
const res: AxiosResponse = await graphql.query("queryEndpoints").params({
|
||||
serviceId,
|
||||
duration: this.durationTime,
|
||||
keyword: keyword || "",
|
||||
});
|
||||
if (res.data.errors) {
|
||||
return res.data;
|
||||
}
|
||||
this.taskEndpoints = [{ value: "", label: "All" }, ...res.data.data.pods];
|
||||
return res.data;
|
||||
},
|
||||
async getTaskList() {
|
||||
const res: AxiosResponse = await graphql
|
||||
.query("getProfileTaskList")
|
||||
|
@ -37,8 +37,8 @@ limitations under the License. -->
|
||||
import type { PropType } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import Header from "../related/profile/Header.vue";
|
||||
import Content from "../related/profile/Content.vue";
|
||||
import Header from "../related/ebpf/Header.vue";
|
||||
import Content from "../related/ebpf/Content.vue";
|
||||
|
||||
/*global defineProps */
|
||||
const props = defineProps({
|
||||
|
@ -122,6 +122,7 @@ 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";
|
||||
|
||||
const props = {
|
||||
data: {
|
||||
@ -132,7 +133,7 @@ const props = {
|
||||
};
|
||||
export default defineComponent({
|
||||
name: "Tab",
|
||||
components: { Topology, Widget, Trace, Profile, Log, Text },
|
||||
components: { Topology, Widget, Trace, Profile, Log, Text, Ebpf },
|
||||
props,
|
||||
setup(props) {
|
||||
const { t } = useI18n();
|
||||
|
@ -21,5 +21,6 @@ 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";
|
||||
|
||||
export default { Tab, Widget, Trace, Topology, Profile, Log, Text };
|
||||
export default { Tab, Widget, Trace, Topology, Profile, Log, Text, Ebpf };
|
||||
|
17
src/views/dashboard/related/ebpf/Content.vue
Normal file
17
src/views/dashboard/related/ebpf/Content.vue
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. -->
|
||||
<template>
|
||||
<div>content</div>
|
||||
</template>
|
133
src/views/dashboard/related/ebpf/Header.vue
Normal file
133
src/views/dashboard/related/ebpf/Header.vue
Normal file
@ -0,0 +1,133 @@
|
||||
<!-- 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="flex-h header">
|
||||
<div class="mr-10">
|
||||
<span class="grey mr-5">{{ t("endpointName") }}:</span>
|
||||
<Selector
|
||||
class="name"
|
||||
size="small"
|
||||
:value="endpointName"
|
||||
:options="ebpfStore.endpoints"
|
||||
placeholder="Select a endpoint"
|
||||
:isRemote="true"
|
||||
@change="changeEndpoint"
|
||||
@query="searchEndpoints"
|
||||
/>
|
||||
</div>
|
||||
<el-button
|
||||
class="search-btn"
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="searchTasks"
|
||||
>
|
||||
{{ t("search") }}
|
||||
</el-button>
|
||||
<el-button class="search-btn" size="small" @click="createTask">
|
||||
{{ t("newTask") }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-dialog
|
||||
v-model="newTask"
|
||||
:destroy-on-close="true"
|
||||
fullscreen
|
||||
@closed="newTask = false"
|
||||
>
|
||||
<NewTask @close="newTask = false" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useEbpfStore } from "@/store/modules/ebpf";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { ElMessage } from "element-plus";
|
||||
import NewTask from "./components/NewTask.vue";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { EntityType } from "../../data";
|
||||
|
||||
const ebpfStore = useEbpfStore();
|
||||
const appStore = useAppStoreWithOut();
|
||||
const selectorStore = useSelectorStore();
|
||||
const dashboardStore = useDashboardStore();
|
||||
const { t } = useI18n();
|
||||
const endpointName = ref<string>("");
|
||||
const newTask = ref<boolean>(false);
|
||||
|
||||
searchTasks();
|
||||
searchEndpoints("");
|
||||
|
||||
async function searchEndpoints(keyword: string) {
|
||||
if (!selectorStore.currentService) {
|
||||
return;
|
||||
}
|
||||
const service = selectorStore.currentService.value;
|
||||
const res = await ebpfStore.getEndpoints(service, keyword);
|
||||
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
return;
|
||||
}
|
||||
endpointName.value = ebpfStore.endpoints[0].value;
|
||||
}
|
||||
|
||||
function changeEndpoint(opt: any[]) {
|
||||
endpointName.value = opt[0].value;
|
||||
}
|
||||
|
||||
async function searchTasks() {
|
||||
ebpfStore.setConditions({
|
||||
serviceId:
|
||||
(selectorStore.currentService && selectorStore.currentService.id) || "",
|
||||
endpointName: endpointName.value,
|
||||
});
|
||||
const res = await ebpfStore.getTaskList();
|
||||
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
}
|
||||
}
|
||||
|
||||
function createTask() {
|
||||
newTask.value = true;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => selectorStore.currentService,
|
||||
() => {
|
||||
searchTasks();
|
||||
}
|
||||
);
|
||||
watch(
|
||||
() => appStore.durationTime,
|
||||
() => {
|
||||
if (dashboardStore.entity === EntityType[1].value) {
|
||||
searchTasks();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.header {
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
}
|
||||
|
||||
.name {
|
||||
width: 270px;
|
||||
}
|
||||
</style>
|
203
src/views/dashboard/related/ebpf/components/NewTask.vue
Normal file
203
src/views/dashboard/related/ebpf/components/NewTask.vue
Normal file
@ -0,0 +1,203 @@
|
||||
<!-- 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-task">
|
||||
<div>
|
||||
<div class="label">{{ t("endpointName") }}</div>
|
||||
<Selector
|
||||
class="profile-input"
|
||||
size="small"
|
||||
:value="endpointName"
|
||||
:options="eBPFStore.taskEndpoints"
|
||||
placeholder="Select a endpoint"
|
||||
:isRemote="true"
|
||||
@change="changeEndpoint"
|
||||
@query="searchEndpoints"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="label">{{ t("monitorTime") }}</div>
|
||||
<div>
|
||||
<Radio
|
||||
class="mb-5"
|
||||
:value="monitorTime"
|
||||
:options="InitTaskField.monitorTimeEn"
|
||||
@change="changeMonitorTime"
|
||||
/>
|
||||
<span class="date">
|
||||
<TimePicker
|
||||
:value="time"
|
||||
position="bottom"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
@input="changeTimeRange"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="label">{{ t("monitorDuration") }}</div>
|
||||
<Radio
|
||||
class="mb-5"
|
||||
:value="monitorDuration"
|
||||
:options="InitTaskField.monitorDuration"
|
||||
@change="changeMonitorDuration"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="label">{{ t("minThreshold") }} (ms)</div>
|
||||
<el-input-number
|
||||
size="small"
|
||||
class="profile-input"
|
||||
:min="0"
|
||||
v-model="minThreshold"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="label">{{ t("dumpPeriod") }}</div>
|
||||
<Radio
|
||||
class="mb-5"
|
||||
:value="dumpPeriod"
|
||||
:options="InitTaskField.dumpPeriod"
|
||||
@change="changeDumpPeriod"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="label">{{ t("maxSamplingCount") }}</div>
|
||||
<Selector
|
||||
size="small"
|
||||
:value="maxSamplingCount"
|
||||
:options="InitTaskField.maxSamplingCount"
|
||||
placeholder="Select a data"
|
||||
@change="changeMaxSamplingCount"
|
||||
class="profile-input"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<el-button @click="createTask" type="primary" class="create-task-btn">
|
||||
{{ t("createTask") }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useEbpfStore } from "@/store/modules/ebpf";
|
||||
import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { InitTaskField } from "./data";
|
||||
/* global defineEmits */
|
||||
const emits = defineEmits(["close"]);
|
||||
const eBPFStore = useEbpfStore();
|
||||
const selectorStore = useSelectorStore();
|
||||
const appStore = useAppStoreWithOut();
|
||||
const { t } = useI18n();
|
||||
const endpointName = ref<string>("");
|
||||
const monitorTime = ref<string>(InitTaskField.monitorTimeEn[0].value);
|
||||
const monitorDuration = ref<string>(InitTaskField.monitorDuration[0].value);
|
||||
const time = ref<Date>(appStore.durationRow.start);
|
||||
const minThreshold = ref<number>(0);
|
||||
const dumpPeriod = ref<string>(InitTaskField.dumpPeriod[0].value);
|
||||
const maxSamplingCount = ref<string>(InitTaskField.maxSamplingCount[0].value);
|
||||
|
||||
async function searchEndpoints(keyword: string) {
|
||||
if (!selectorStore.currentService) {
|
||||
return;
|
||||
}
|
||||
const service = selectorStore.currentService.value;
|
||||
const res = await eBPFStore.getEndpoints(service, keyword);
|
||||
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
return;
|
||||
}
|
||||
endpointName.value = eBPFStore.taskEndpoints[0].value;
|
||||
}
|
||||
|
||||
function changeMonitorTime(opt: string) {
|
||||
monitorTime.value = opt;
|
||||
}
|
||||
|
||||
function changeMonitorDuration(val: string) {
|
||||
monitorDuration.value = val;
|
||||
}
|
||||
|
||||
function changeDumpPeriod(val: string) {
|
||||
dumpPeriod.value = val;
|
||||
}
|
||||
|
||||
function changeMaxSamplingCount(opt: any[]) {
|
||||
maxSamplingCount.value = opt[0].value;
|
||||
}
|
||||
|
||||
function changeEndpoint(opt: any[]) {
|
||||
endpointName.value = opt[0].value;
|
||||
}
|
||||
|
||||
async function createTask() {
|
||||
emits("close");
|
||||
const date =
|
||||
monitorTime.value === "0" ? appStore.durationRow.start : time.value;
|
||||
const params = {
|
||||
serviceId: selectorStore.currentService.id,
|
||||
endpointName: endpointName.value,
|
||||
startTime: date.getTime(),
|
||||
duration: Number(monitorDuration.value),
|
||||
minDurationThreshold: Number(minThreshold.value),
|
||||
dumpPeriod: Number(dumpPeriod.value),
|
||||
maxSamplingCount: Number(maxSamplingCount.value),
|
||||
};
|
||||
const res = await eBPFStore.createTask(params);
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
return;
|
||||
}
|
||||
const { tip } = res.data;
|
||||
if (tip) {
|
||||
ElMessage.error(tip);
|
||||
return;
|
||||
}
|
||||
ElMessage.success("Task created successfully");
|
||||
}
|
||||
function changeTimeRange(val: Date) {
|
||||
time.value = val;
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.profile-task {
|
||||
margin: 0 auto;
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.label {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.profile-input {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.create-task-btn {
|
||||
width: 300px;
|
||||
margin-top: 50px;
|
||||
}
|
||||
</style>
|
63
src/views/dashboard/related/ebpf/components/data.ts
Normal file
63
src/views/dashboard/related/ebpf/components/data.ts
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* 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 ProfileMode: any[] = [
|
||||
{ label: "Include Children", value: "include" },
|
||||
{ label: "Exclude Children", value: "exclude" },
|
||||
];
|
||||
export const NewTaskField = {
|
||||
service: { key: "", label: "None" },
|
||||
monitorTime: { key: "0", label: "monitor now" },
|
||||
monitorDuration: { key: 5, label: "5 min" },
|
||||
minThreshold: 0,
|
||||
dumpPeriod: { key: 10, label: "10ms" },
|
||||
endpointName: "",
|
||||
maxSamplingCount: { key: 5, label: "5" },
|
||||
};
|
||||
|
||||
export const InitTaskField = {
|
||||
serviceSource: [{ key: "", label: "None" }],
|
||||
monitorTimeEn: [
|
||||
{ value: "0", label: "monitor now" },
|
||||
{ value: "1", label: "set start time" },
|
||||
],
|
||||
monitorTimeCn: [
|
||||
{ value: "0", label: "此刻" },
|
||||
{ value: "1", label: "设置时间" },
|
||||
],
|
||||
monitorDuration: [
|
||||
{ value: "5", label: "5 min" },
|
||||
{ value: "10", label: "10 min" },
|
||||
{ value: "15", label: "15 min" },
|
||||
],
|
||||
dumpPeriod: [
|
||||
{ value: "10", label: "10 ms" },
|
||||
{ value: "20", label: "20 ms" },
|
||||
{ value: "50", label: "50 ms" },
|
||||
{ value: "100", label: "100 ms" },
|
||||
],
|
||||
maxSamplingCount: [
|
||||
{ value: "1", label: "1" },
|
||||
{ value: "2", label: "2" },
|
||||
{ value: "3", label: "3" },
|
||||
{ value: "4", label: "4" },
|
||||
{ value: "5", label: "5" },
|
||||
{ value: "6", label: "6" },
|
||||
{ value: "7", label: "7" },
|
||||
{ value: "8", label: "8" },
|
||||
{ value: "9", label: "9" },
|
||||
],
|
||||
};
|
@ -17,7 +17,16 @@ limitations under the License. -->
|
||||
<div class="profile-task">
|
||||
<div>
|
||||
<div class="label">{{ t("endpointName") }}</div>
|
||||
<el-input v-model="endpointName" class="profile-input" size="small" />
|
||||
<Selector
|
||||
class="profile-input"
|
||||
size="small"
|
||||
:value="endpointName"
|
||||
:options="profileStore.taskEndpoints"
|
||||
placeholder="Select a endpoint"
|
||||
:isRemote="true"
|
||||
@change="changeEndpoint"
|
||||
@query="searchEndpoints"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="label">{{ t("monitorTime") }}</div>
|
||||
@ -105,6 +114,20 @@ const minThreshold = ref<number>(0);
|
||||
const dumpPeriod = ref<string>(InitTaskField.dumpPeriod[0].value);
|
||||
const maxSamplingCount = ref<string>(InitTaskField.maxSamplingCount[0].value);
|
||||
|
||||
async function searchEndpoints(keyword: string) {
|
||||
if (!selectorStore.currentService) {
|
||||
return;
|
||||
}
|
||||
const service = selectorStore.currentService.value;
|
||||
const res = await profileStore.getEndpoints(service, keyword);
|
||||
|
||||
if (res.errors) {
|
||||
ElMessage.error(res.errors);
|
||||
return;
|
||||
}
|
||||
endpointName.value = profileStore.taskEndpoints[0].value;
|
||||
}
|
||||
|
||||
function changeMonitorTime(opt: string) {
|
||||
monitorTime.value = opt;
|
||||
}
|
||||
@ -121,6 +144,10 @@ function changeMaxSamplingCount(opt: any[]) {
|
||||
maxSamplingCount.value = opt[0].value;
|
||||
}
|
||||
|
||||
function changeEndpoint(opt: any[]) {
|
||||
endpointName.value = opt[0].value;
|
||||
}
|
||||
|
||||
async function createTask() {
|
||||
emits("close");
|
||||
const date =
|
||||
@ -153,7 +180,7 @@ function changeTimeRange(val: Date) {
|
||||
<style lang="scss" scoped>
|
||||
.profile-task {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.date {
|
||||
|
Loading…
Reference in New Issue
Block a user