diff --git a/src/assets/icons/keyboard_arrow_down.svg b/src/assets/icons/keyboard_arrow_down.svg
new file mode 100644
index 00000000..73d197b8
--- /dev/null
+++ b/src/assets/icons/keyboard_arrow_down.svg
@@ -0,0 +1,17 @@
+
+
diff --git a/src/assets/icons/keyboard_arrow_up.svg b/src/assets/icons/keyboard_arrow_up.svg
new file mode 100644
index 00000000..11cba421
--- /dev/null
+++ b/src/assets/icons/keyboard_arrow_up.svg
@@ -0,0 +1,17 @@
+
+
diff --git a/src/components/Graph.vue b/src/components/Graph.vue
index 6b87334a..200cb1d8 100644
--- a/src/components/Graph.vue
+++ b/src/components/Graph.vue
@@ -94,6 +94,71 @@ onMounted(async () => {
}, 1000);
});
+function updateOptions() {
+ const instance = getInstance();
+ if (!instance) {
+ return;
+ }
+ if (!props.filters) {
+ return;
+ }
+ 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(
+ (d: (number | string)[]) => d[0]
+ );
+ if (!list.includes(props.filters.duration.endTime)) {
+ return;
+ }
+ const markArea = {
+ silent: true,
+ itemStyle: {
+ opacity: 0.3,
+ },
+ data: [
+ [
+ {
+ xAxis: props.filters.duration.startTime,
+ },
+ {
+ xAxis: props.filters.duration.endTime,
+ },
+ ],
+ ],
+ };
+ const series = (window as any).structuredClone(props.option.series);
+ for (const [key, temp] of series.entries()) {
+ if (key === 0) {
+ temp.markArea = markArea;
+ }
+ }
+ const options = {
+ ...props.option,
+ series,
+ };
+ return options;
+}
+
watch(
() => props.option,
(newVal, oldVal) => {
@@ -103,62 +168,17 @@ watch(
if (JSON.stringify(newVal) === JSON.stringify(oldVal)) {
return;
}
- setOptions(newVal);
+ let options;
+ if (props.filters && props.filters.isRange) {
+ options = eventAssociate();
+ }
+ setOptions(options || props.option);
}
);
watch(
() => props.filters,
() => {
- const instance = getInstance();
- if (!instance) {
- return;
- }
- if (props.filters) {
- if (props.filters.isRange) {
- const list = props.option.series[0].data.map(
- (d: (number | string)[]) => d[0]
- );
- if (!list.includes(props.filters.duration.endTime)) {
- return;
- }
- const markArea = {
- silent: true,
- itemStyle: {
- opacity: 0.3,
- },
- data: [
- [
- {
- xAxis: props.filters.duration.startTime,
- },
- {
- xAxis: props.filters.duration.endTime,
- },
- ],
- ],
- };
- const series = (window as any).structuredClone(props.option.series);
- for (const [key, temp] of series.entries()) {
- if (key === 0) {
- temp.markArea = markArea;
- }
- }
- const options = {
- ...props.option,
- series,
- };
- if (JSON.stringify(options) === JSON.stringify(props.option)) {
- return;
- }
- setOptions(options);
- return;
- }
- instance.dispatchAction({
- type: "showTip",
- dataIndex: props.filters.dataIndex,
- seriesIndex: 0,
- });
- }
+ updateOptions();
}
);
diff --git a/src/store/modules/log.ts b/src/store/modules/log.ts
index 241297de..ea0c9c0f 100644
--- a/src/store/modules/log.ts
+++ b/src/store/modules/log.ts
@@ -53,7 +53,8 @@ export const logStore = defineStore({
setLogCondition(data: any) {
this.conditions = { ...this.conditions, ...data };
},
- resetCondition() {
+ resetState() {
+ this.logs = [];
this.conditions = {
queryDuration: useAppStoreWithOut().durationTime,
paging: { pageNum: 1, pageSize: 15 },
diff --git a/src/store/modules/trace.ts b/src/store/modules/trace.ts
index 16aa422b..36c55dd4 100644
--- a/src/store/modules/trace.ts
+++ b/src/store/modules/trace.ts
@@ -63,7 +63,10 @@ export const traceStore = defineStore({
setTraceSpans(spans: Span) {
this.traceSpans = spans;
},
- resetCondition() {
+ resetState() {
+ this.traceSpans = [];
+ this.traceList = [];
+ this.currentTrace = {};
this.conditions = {
queryDuration: useAppStoreWithOut().durationTime,
paging: { pageNum: 1, pageSize: 20 },
diff --git a/src/views/dashboard/related/event/Content.vue b/src/views/dashboard/related/event/Content.vue
index 5dc8c501..a8a71f8c 100644
--- a/src/views/dashboard/related/event/Content.vue
+++ b/src/views/dashboard/related/event/Content.vue
@@ -26,8 +26,9 @@ import { DataSet, Timeline } from "vis-timeline/standalone";
import "vis-timeline/styles/vis-timeline-graph2d.css";
import { useDashboardStore } from "@/store/modules/dashboard";
import getDashboard from "@/hooks/useDashboardsSession";
-import { dateFormatTime } from "@/utils/dateFormat";
import { useAppStoreWithOut } from "@/store/modules/app";
+import dateFormatStep, { dateFormatTime } from "@/utils/dateFormat";
+import getLocalTime from "@/utils/localtime";
const eventStore = useEventStore();
/*global defineProps, Nullable */
@@ -105,53 +106,139 @@ function visTimeline() {
return;
}
dashboardStore.selectWidget(props.data);
- const all = getDashboard(dashboardStore.currentDashboard).widgets;
- const widgets = all.filter(
- (d: { value: string; label: string } & LayoutConfig) => {
- const isLinear = ["Bar", "Line", "Area"].includes(
- (d.graph && d.graph.type) || ""
- );
- if (isLinear) {
- return d;
- }
- }
- );
- const index = properties.items[0];
- const i = events[index - 1 || 0];
-
- for (const widget of widgets) {
- let end = i.end;
- if (!isNaN(index)) {
- let diff = 60000;
- switch (appStore.duration.step) {
- case "MINUTE":
- diff = 60000;
- break;
- case "HOUR":
- diff = 3600000;
- break;
- case "DAY":
- diff = 3600000 * 24;
- break;
- }
- if (!i.end || i.end.getTime() - i.start.getTime() < diff) {
- end = i.start.getTime() + diff;
- }
- }
- 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);
- }
+ const dashboard = getDashboard(dashboardStore.currentDashboard).widgets;
+ associateMetrics(properties.items, events, dashboard);
+ 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(
+ (d.graph && d.graph.type) || ""
+ );
+ if (isLinear) {
+ return d;
+ }
+ });
+ const index = items[0];
+ const i = events[index - 1 || 0];
+
+ for (const widget of widgets) {
+ 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;
+ switch (appStore.duration.step) {
+ case "MINUTE":
+ diff = 60000;
+ break;
+ case "HOUR":
+ diff = 3600000;
+ break;
+ case "DAY":
+ diff = 3600000 * 24;
+ break;
+ }
+ if (!end || end.getTime() - start.getTime() < diff) {
+ time = start.getTime() + diff;
+ }
+ return { start, end: new Date(time) };
+}
+
function resize() {
const observer = new ResizeObserver((entries) => {
const entry = entries[0];
diff --git a/src/views/dashboard/related/log/Header.vue b/src/views/dashboard/related/log/Header.vue
index 7b16c4d6..33732011 100644
--- a/src/views/dashboard/related/log/Header.vue
+++ b/src/views/dashboard/related/log/Header.vue
@@ -143,6 +143,7 @@ import { ElMessage } from "element-plus";
import { EntityType } from "../../data";
import { ErrorCategory } from "./data";
import { LayoutConfig } from "@/types/dashboard";
+import { DurationTime } from "@/types/app";
/*global defineProps, Recordable */
const props = defineProps({
@@ -160,6 +161,9 @@ const logStore = useLogStore();
const traceId = ref(
(props.data.filters && props.data.filters.traceId) || ""
);
+const duration = ref(
+ (props.data.filters && props.data.filters.duration) || appStore.durationTime
+);
const keywordsOfContent = ref([]);
const excludingKeywordsOfContent = ref([]);
const tagsList = ref([]);
@@ -252,7 +256,7 @@ function searchLogs() {
pagePathId: endpoint || state.endpoint.id || undefined,
serviceVersionId: instance || state.instance.id || undefined,
paging: { pageNum: 1, pageSize: 15 },
- queryDuration: appStore.durationTime,
+ queryDuration: duration,
category: state.category.value,
});
} else {
@@ -339,13 +343,14 @@ function removeExcludeContent(index: number) {
excludingContentStr.value = "";
}
onUnmounted(() => {
- logStore.resetCondition();
+ logStore.resetState();
const item = {
...props.data,
filters: undefined,
};
dashboardStore.setWidget(item);
traceId.value = "";
+ duration.value = appStore.durationTime;
});
watch(
() => selectorStore.currentService,
@@ -375,12 +380,12 @@ watch(
watch(
() => props.data.filters,
(newJson, oldJson) => {
- console.log(props.data.filters);
if (props.data.filters) {
if (JSON.stringify(newJson) === JSON.stringify(oldJson)) {
return;
}
traceId.value = props.data.filters.traceId || "";
+ duration.value = props.data.filters.duration || appStore.durationTime;
init();
}
}
diff --git a/src/views/dashboard/related/trace/Filter.vue b/src/views/dashboard/related/trace/Filter.vue
index 77753b4a..cb351e99 100644
--- a/src/views/dashboard/related/trace/Filter.vue
+++ b/src/views/dashboard/related/trace/Filter.vue
@@ -105,6 +105,7 @@ import ConditionTags from "@/views/components/ConditionTags.vue";
import { ElMessage } from "element-plus";
import { EntityType } from "../../data";
import { LayoutConfig } from "@/types/dashboard";
+import { DurationTime } from "@/types/app";
/*global defineProps, Recordable */
const props = defineProps({
@@ -122,6 +123,9 @@ const appStore = useAppStoreWithOut();
const selectorStore = useSelectorStore();
const dashboardStore = useDashboardStore();
const traceStore = useTraceStore();
+const duration = ref(
+ (props.data.filters && props.data.filters.duration) || appStore.durationTime
+);
const minTraceDuration = ref();
const maxTraceDuration = ref();
const tagsList = ref([]);
@@ -198,7 +202,7 @@ function searchTraces() {
endpointId: endpoint || state.endpoint.id || undefined,
serviceInstanceId: instance || state.instance.id || undefined,
traceState: state.status.value || "ALL",
- queryDuration: appStore.durationTime,
+ queryDuration: duration.value,
minTraceDuration: Number(minTraceDuration.value),
maxTraceDuration: Number(maxTraceDuration.value),
queryOrder: "BY_DURATION",
@@ -231,13 +235,14 @@ async function searchEndpoints(keyword: string) {
}
}
onUnmounted(() => {
- traceStore.resetCondition();
+ traceStore.resetState();
const item = {
...props.data,
filters: undefined,
};
dashboardStore.setWidget(item);
traceId.value = "";
+ duration.value = appStore.durationTime;
});
watch(
() => [selectorStore.currentPod],
@@ -273,6 +278,7 @@ watch(
return;
}
traceId.value = props.data.filters.traceId || "";
+ duration.value = props.data.filters.duration || appStore.durationTime;
init();
}
}