mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-02 06:34:01 +00:00
feat: event widget associates with trace and log widget (#130)
This commit is contained in:
parent
dc8e4bf273
commit
3b3e790dd9
17
src/assets/icons/keyboard_arrow_down.svg
Normal file
17
src/assets/icons/keyboard_arrow_down.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="M7.406 8.578l4.594 4.594 4.594-4.594 1.406 1.406-6 6-6-6z"></path>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 946 B |
17
src/assets/icons/keyboard_arrow_up.svg
Normal file
17
src/assets/icons/keyboard_arrow_up.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="M7.406 15.422l-1.406-1.406 6-6 6 6-1.406 1.406-4.594-4.594z"></path>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 948 B |
@ -94,27 +94,36 @@ onMounted(async () => {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
function updateOptions() {
|
||||||
() => props.option,
|
|
||||||
(newVal, oldVal) => {
|
|
||||||
if (!available.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (JSON.stringify(newVal) === JSON.stringify(oldVal)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setOptions(newVal);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
watch(
|
|
||||||
() => props.filters,
|
|
||||||
() => {
|
|
||||||
const instance = getInstance();
|
const instance = getInstance();
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (props.filters) {
|
if (!props.filters) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (props.filters.isRange) {
|
if (props.filters.isRange) {
|
||||||
|
const options = eventAssociate();
|
||||||
|
setOptions(options || props.option);
|
||||||
|
} else {
|
||||||
|
instance.dispatchAction({
|
||||||
|
type: "showTip",
|
||||||
|
dataIndex: props.filters.dataIndex,
|
||||||
|
seriesIndex: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function eventAssociate() {
|
||||||
|
if (!props.filters) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!props.filters.duration) {
|
||||||
|
return props.option;
|
||||||
|
}
|
||||||
|
if (!props.option.series[0]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const list = props.option.series[0].data.map(
|
const list = props.option.series[0].data.map(
|
||||||
(d: (number | string)[]) => d[0]
|
(d: (number | string)[]) => d[0]
|
||||||
);
|
);
|
||||||
@ -147,18 +156,29 @@ watch(
|
|||||||
...props.option,
|
...props.option,
|
||||||
series,
|
series,
|
||||||
};
|
};
|
||||||
if (JSON.stringify(options) === JSON.stringify(props.option)) {
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.option,
|
||||||
|
(newVal, oldVal) => {
|
||||||
|
if (!available.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setOptions(options);
|
if (JSON.stringify(newVal) === JSON.stringify(oldVal)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
instance.dispatchAction({
|
let options;
|
||||||
type: "showTip",
|
if (props.filters && props.filters.isRange) {
|
||||||
dataIndex: props.filters.dataIndex,
|
options = eventAssociate();
|
||||||
seriesIndex: 0,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
setOptions(options || props.option);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => props.filters,
|
||||||
|
() => {
|
||||||
|
updateOptions();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -53,7 +53,8 @@ export const logStore = defineStore({
|
|||||||
setLogCondition(data: any) {
|
setLogCondition(data: any) {
|
||||||
this.conditions = { ...this.conditions, ...data };
|
this.conditions = { ...this.conditions, ...data };
|
||||||
},
|
},
|
||||||
resetCondition() {
|
resetState() {
|
||||||
|
this.logs = [];
|
||||||
this.conditions = {
|
this.conditions = {
|
||||||
queryDuration: useAppStoreWithOut().durationTime,
|
queryDuration: useAppStoreWithOut().durationTime,
|
||||||
paging: { pageNum: 1, pageSize: 15 },
|
paging: { pageNum: 1, pageSize: 15 },
|
||||||
|
@ -63,7 +63,10 @@ export const traceStore = defineStore({
|
|||||||
setTraceSpans(spans: Span) {
|
setTraceSpans(spans: Span) {
|
||||||
this.traceSpans = spans;
|
this.traceSpans = spans;
|
||||||
},
|
},
|
||||||
resetCondition() {
|
resetState() {
|
||||||
|
this.traceSpans = [];
|
||||||
|
this.traceList = [];
|
||||||
|
this.currentTrace = {};
|
||||||
this.conditions = {
|
this.conditions = {
|
||||||
queryDuration: useAppStoreWithOut().durationTime,
|
queryDuration: useAppStoreWithOut().durationTime,
|
||||||
paging: { pageNum: 1, pageSize: 20 },
|
paging: { pageNum: 1, pageSize: 20 },
|
||||||
|
@ -26,8 +26,9 @@ import { DataSet, Timeline } from "vis-timeline/standalone";
|
|||||||
import "vis-timeline/styles/vis-timeline-graph2d.css";
|
import "vis-timeline/styles/vis-timeline-graph2d.css";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import getDashboard from "@/hooks/useDashboardsSession";
|
import getDashboard from "@/hooks/useDashboardsSession";
|
||||||
import { dateFormatTime } from "@/utils/dateFormat";
|
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
|
import dateFormatStep, { dateFormatTime } from "@/utils/dateFormat";
|
||||||
|
import getLocalTime from "@/utils/localtime";
|
||||||
|
|
||||||
const eventStore = useEventStore();
|
const eventStore = useEventStore();
|
||||||
/*global defineProps, Nullable */
|
/*global defineProps, Nullable */
|
||||||
@ -105,23 +106,121 @@ function visTimeline() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dashboardStore.selectWidget(props.data);
|
dashboardStore.selectWidget(props.data);
|
||||||
const all = getDashboard(dashboardStore.currentDashboard).widgets;
|
const dashboard = getDashboard(dashboardStore.currentDashboard).widgets;
|
||||||
const widgets = all.filter(
|
associateMetrics(properties.items, events, dashboard);
|
||||||
(d: { value: string; label: string } & LayoutConfig) => {
|
associateTraceLog(properties.items, events, dashboard);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function associateTraceLog(
|
||||||
|
items: number[],
|
||||||
|
events: {
|
||||||
|
id: number;
|
||||||
|
content: string;
|
||||||
|
start: Date;
|
||||||
|
end: Date;
|
||||||
|
data: unknown;
|
||||||
|
className: string;
|
||||||
|
}[],
|
||||||
|
dashboard: LayoutConfig[]
|
||||||
|
) {
|
||||||
|
const widgets = dashboard.filter((d: { type: string }) =>
|
||||||
|
["Trace", "Log"].includes(d.type)
|
||||||
|
);
|
||||||
|
const index = items[0];
|
||||||
|
const i = events[index - 1 || 0];
|
||||||
|
for (const widget of widgets) {
|
||||||
|
if (isNaN(index)) {
|
||||||
|
const item = {
|
||||||
|
...widget,
|
||||||
|
filters: {
|
||||||
|
sourceId: props.data.id || "",
|
||||||
|
duration: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
dashboardStore.setWidget(item);
|
||||||
|
} else {
|
||||||
|
const { start, end } = setEndTime(i.start, i.end);
|
||||||
|
const item = {
|
||||||
|
...widget,
|
||||||
|
filters: {
|
||||||
|
sourceId: props.data.id || "",
|
||||||
|
duration: {
|
||||||
|
start: dateFormatStep(
|
||||||
|
getLocalTime(appStore.utc, start),
|
||||||
|
appStore.duration.step,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
end: dateFormatStep(
|
||||||
|
getLocalTime(appStore.utc, end),
|
||||||
|
appStore.duration.step,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
step: appStore.duration.step,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
dashboardStore.setWidget(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function associateMetrics(
|
||||||
|
items: number[],
|
||||||
|
events: {
|
||||||
|
id: number;
|
||||||
|
content: string;
|
||||||
|
start: Date;
|
||||||
|
end: Date;
|
||||||
|
data: unknown;
|
||||||
|
className: string;
|
||||||
|
}[],
|
||||||
|
dashboard: LayoutConfig[]
|
||||||
|
) {
|
||||||
|
const widgets = dashboard.filter((d: LayoutConfig) => {
|
||||||
const isLinear = ["Bar", "Line", "Area"].includes(
|
const isLinear = ["Bar", "Line", "Area"].includes(
|
||||||
(d.graph && d.graph.type) || ""
|
(d.graph && d.graph.type) || ""
|
||||||
);
|
);
|
||||||
if (isLinear) {
|
if (isLinear) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
const index = items[0];
|
||||||
const index = properties.items[0];
|
|
||||||
const i = events[index - 1 || 0];
|
const i = events[index - 1 || 0];
|
||||||
|
|
||||||
for (const widget of widgets) {
|
for (const widget of widgets) {
|
||||||
let end = i.end;
|
if (isNaN(index)) {
|
||||||
if (!isNaN(index)) {
|
const item = {
|
||||||
|
...widget,
|
||||||
|
filters: {
|
||||||
|
sourceId: dashboardStore.selectedGrid.id || "",
|
||||||
|
isRange: true,
|
||||||
|
duration: {
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
dashboardStore.setWidget(item);
|
||||||
|
} else {
|
||||||
|
const { start, end } = setEndTime(i.start, i.end);
|
||||||
|
const startTime = dateFormatTime(start, appStore.duration.step);
|
||||||
|
const endTime = dateFormatTime(end, appStore.duration.step);
|
||||||
|
const item = {
|
||||||
|
...widget,
|
||||||
|
filters: {
|
||||||
|
sourceId: dashboardStore.selectedGrid.id || "",
|
||||||
|
isRange: true,
|
||||||
|
duration: {
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
dashboardStore.setWidget(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function setEndTime(start: Date, end: Date) {
|
||||||
|
let time: Date | number = end;
|
||||||
let diff = 60000;
|
let diff = 60000;
|
||||||
switch (appStore.duration.step) {
|
switch (appStore.duration.step) {
|
||||||
case "MINUTE":
|
case "MINUTE":
|
||||||
@ -134,24 +233,12 @@ function visTimeline() {
|
|||||||
diff = 3600000 * 24;
|
diff = 3600000 * 24;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!i.end || i.end.getTime() - i.start.getTime() < diff) {
|
if (!end || end.getTime() - start.getTime() < diff) {
|
||||||
end = i.start.getTime() + diff;
|
time = start.getTime() + diff;
|
||||||
}
|
}
|
||||||
}
|
return { start, end: new Date(time) };
|
||||||
const startTime = dateFormatTime(i.start, appStore.duration.step);
|
|
||||||
const endTime = dateFormatTime(new Date(end), appStore.duration.step);
|
|
||||||
widget.filters = {
|
|
||||||
sourceId: dashboardStore.selectedGrid.id || "",
|
|
||||||
isRange: true,
|
|
||||||
duration: {
|
|
||||||
startTime,
|
|
||||||
endTime,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
dashboardStore.setWidget(widget);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resize() {
|
function resize() {
|
||||||
const observer = new ResizeObserver((entries) => {
|
const observer = new ResizeObserver((entries) => {
|
||||||
const entry = entries[0];
|
const entry = entries[0];
|
||||||
|
@ -143,6 +143,7 @@ import { ElMessage } from "element-plus";
|
|||||||
import { EntityType } from "../../data";
|
import { EntityType } from "../../data";
|
||||||
import { ErrorCategory } from "./data";
|
import { ErrorCategory } from "./data";
|
||||||
import { LayoutConfig } from "@/types/dashboard";
|
import { LayoutConfig } from "@/types/dashboard";
|
||||||
|
import { DurationTime } from "@/types/app";
|
||||||
|
|
||||||
/*global defineProps, Recordable */
|
/*global defineProps, Recordable */
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -160,6 +161,9 @@ const logStore = useLogStore();
|
|||||||
const traceId = ref<string>(
|
const traceId = ref<string>(
|
||||||
(props.data.filters && props.data.filters.traceId) || ""
|
(props.data.filters && props.data.filters.traceId) || ""
|
||||||
);
|
);
|
||||||
|
const duration = ref<DurationTime>(
|
||||||
|
(props.data.filters && props.data.filters.duration) || appStore.durationTime
|
||||||
|
);
|
||||||
const keywordsOfContent = ref<string[]>([]);
|
const keywordsOfContent = ref<string[]>([]);
|
||||||
const excludingKeywordsOfContent = ref<string[]>([]);
|
const excludingKeywordsOfContent = ref<string[]>([]);
|
||||||
const tagsList = ref<string[]>([]);
|
const tagsList = ref<string[]>([]);
|
||||||
@ -252,7 +256,7 @@ function searchLogs() {
|
|||||||
pagePathId: endpoint || state.endpoint.id || undefined,
|
pagePathId: endpoint || state.endpoint.id || undefined,
|
||||||
serviceVersionId: instance || state.instance.id || undefined,
|
serviceVersionId: instance || state.instance.id || undefined,
|
||||||
paging: { pageNum: 1, pageSize: 15 },
|
paging: { pageNum: 1, pageSize: 15 },
|
||||||
queryDuration: appStore.durationTime,
|
queryDuration: duration,
|
||||||
category: state.category.value,
|
category: state.category.value,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -339,13 +343,14 @@ function removeExcludeContent(index: number) {
|
|||||||
excludingContentStr.value = "";
|
excludingContentStr.value = "";
|
||||||
}
|
}
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
logStore.resetCondition();
|
logStore.resetState();
|
||||||
const item = {
|
const item = {
|
||||||
...props.data,
|
...props.data,
|
||||||
filters: undefined,
|
filters: undefined,
|
||||||
};
|
};
|
||||||
dashboardStore.setWidget(item);
|
dashboardStore.setWidget(item);
|
||||||
traceId.value = "";
|
traceId.value = "";
|
||||||
|
duration.value = appStore.durationTime;
|
||||||
});
|
});
|
||||||
watch(
|
watch(
|
||||||
() => selectorStore.currentService,
|
() => selectorStore.currentService,
|
||||||
@ -375,12 +380,12 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => props.data.filters,
|
() => props.data.filters,
|
||||||
(newJson, oldJson) => {
|
(newJson, oldJson) => {
|
||||||
console.log(props.data.filters);
|
|
||||||
if (props.data.filters) {
|
if (props.data.filters) {
|
||||||
if (JSON.stringify(newJson) === JSON.stringify(oldJson)) {
|
if (JSON.stringify(newJson) === JSON.stringify(oldJson)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
traceId.value = props.data.filters.traceId || "";
|
traceId.value = props.data.filters.traceId || "";
|
||||||
|
duration.value = props.data.filters.duration || appStore.durationTime;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@ import ConditionTags from "@/views/components/ConditionTags.vue";
|
|||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { EntityType } from "../../data";
|
import { EntityType } from "../../data";
|
||||||
import { LayoutConfig } from "@/types/dashboard";
|
import { LayoutConfig } from "@/types/dashboard";
|
||||||
|
import { DurationTime } from "@/types/app";
|
||||||
|
|
||||||
/*global defineProps, Recordable */
|
/*global defineProps, Recordable */
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -122,6 +123,9 @@ const appStore = useAppStoreWithOut();
|
|||||||
const selectorStore = useSelectorStore();
|
const selectorStore = useSelectorStore();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
const traceStore = useTraceStore();
|
const traceStore = useTraceStore();
|
||||||
|
const duration = ref<DurationTime>(
|
||||||
|
(props.data.filters && props.data.filters.duration) || appStore.durationTime
|
||||||
|
);
|
||||||
const minTraceDuration = ref<number>();
|
const minTraceDuration = ref<number>();
|
||||||
const maxTraceDuration = ref<number>();
|
const maxTraceDuration = ref<number>();
|
||||||
const tagsList = ref<string[]>([]);
|
const tagsList = ref<string[]>([]);
|
||||||
@ -198,7 +202,7 @@ function searchTraces() {
|
|||||||
endpointId: endpoint || state.endpoint.id || undefined,
|
endpointId: endpoint || state.endpoint.id || undefined,
|
||||||
serviceInstanceId: instance || state.instance.id || undefined,
|
serviceInstanceId: instance || state.instance.id || undefined,
|
||||||
traceState: state.status.value || "ALL",
|
traceState: state.status.value || "ALL",
|
||||||
queryDuration: appStore.durationTime,
|
queryDuration: duration.value,
|
||||||
minTraceDuration: Number(minTraceDuration.value),
|
minTraceDuration: Number(minTraceDuration.value),
|
||||||
maxTraceDuration: Number(maxTraceDuration.value),
|
maxTraceDuration: Number(maxTraceDuration.value),
|
||||||
queryOrder: "BY_DURATION",
|
queryOrder: "BY_DURATION",
|
||||||
@ -231,13 +235,14 @@ async function searchEndpoints(keyword: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
traceStore.resetCondition();
|
traceStore.resetState();
|
||||||
const item = {
|
const item = {
|
||||||
...props.data,
|
...props.data,
|
||||||
filters: undefined,
|
filters: undefined,
|
||||||
};
|
};
|
||||||
dashboardStore.setWidget(item);
|
dashboardStore.setWidget(item);
|
||||||
traceId.value = "";
|
traceId.value = "";
|
||||||
|
duration.value = appStore.durationTime;
|
||||||
});
|
});
|
||||||
watch(
|
watch(
|
||||||
() => [selectorStore.currentPod],
|
() => [selectorStore.currentPod],
|
||||||
@ -273,6 +278,7 @@ watch(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
traceId.value = props.data.filters.traceId || "";
|
traceId.value = props.data.filters.traceId || "";
|
||||||
|
duration.value = props.data.filters.duration || appStore.durationTime;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user