diff --git a/src/assets/icons/cross.svg b/src/assets/icons/cross.svg new file mode 100644 index 00000000..3f531cd6 --- /dev/null +++ b/src/assets/icons/cross.svg @@ -0,0 +1,15 @@ + + \ No newline at end of file diff --git a/src/assets/icons/entry.svg b/src/assets/icons/entry.svg new file mode 100644 index 00000000..4a85fcfc --- /dev/null +++ b/src/assets/icons/entry.svg @@ -0,0 +1,15 @@ + + \ No newline at end of file diff --git a/src/assets/icons/exit.svg b/src/assets/icons/exit.svg new file mode 100644 index 00000000..5eb99adf --- /dev/null +++ b/src/assets/icons/exit.svg @@ -0,0 +1,15 @@ + + \ No newline at end of file diff --git a/src/assets/img/tools/ENTRY.png b/src/assets/img/tools/ENTRY.png new file mode 100644 index 00000000..52a33a0c Binary files /dev/null and b/src/assets/img/tools/ENTRY.png differ diff --git a/src/assets/img/tools/EXIT.png b/src/assets/img/tools/EXIT.png new file mode 100644 index 00000000..88aca495 Binary files /dev/null and b/src/assets/img/tools/EXIT.png differ diff --git a/src/assets/img/tools/STREAM.png b/src/assets/img/tools/STREAM.png new file mode 100644 index 00000000..8e1c57f9 Binary files /dev/null and b/src/assets/img/tools/STREAM.png differ diff --git a/src/graphql/fragments/profile.ts b/src/graphql/fragments/profile.ts index c1053083..01744eea 100644 --- a/src/graphql/fragments/profile.ts +++ b/src/graphql/fragments/profile.ts @@ -15,37 +15,6 @@ * limitations under the License. */ -export const ProfileSegment = { - variable: "$segmentId: String", - query: ` - segment: getProfiledSegment(segmentId: $segmentId) { - spans { - spanId - parentSpanId - serviceCode - startTime - endTime - endpointName - type - peer - component - isError - layer - tags { - key value - } - logs { - time - data { - key - value - } - } - } - } - `, -}; - export const CreateProfileTask = { variable: "$creationRequest: ProfileTaskCreationRequest", query: ` @@ -79,23 +48,55 @@ export const GetProfileTaskList = { `, }; export const GetProfileTaskSegmentList = { - variable: "$taskID: String", + variable: "$taskID: ID!", query: ` - segmentList: getProfileTaskSegmentList(taskID: $taskID) { - segmentId + segmentList: getProfileTaskSegments(taskID: $taskID) { + traceId + instanceId + instanceName endpointNames - start duration - traceIds - isError + start + spans { + spanId + parentSpanId + segmentId + refs { + traceId + parentSegmentId + parentSpanId + type + } + serviceCode + serviceInstanceName + startTime + endTime + endpointName + type + peer + component + isError + layer + tags { + key value + } + logs { + time + data { + key + value + } + } + profiled + } } `, }; export const GetProfileAnalyze = { - variable: "$segmentId: String!, $timeRanges: [ProfileAnalyzeTimeRange!]!", + variable: "$queries: [SegmentProfileAnalyzeQuery!]!", query: ` - analyze: getProfileAnalyze(segmentId: $segmentId, timeRanges: $timeRanges) { + analyze: getSegmentsProfileAnalyze(queries: $queries) { tip trees { elements { diff --git a/src/graphql/query/profile.ts b/src/graphql/query/profile.ts index 3534140e..6b762f02 100644 --- a/src/graphql/query/profile.ts +++ b/src/graphql/query/profile.ts @@ -16,7 +16,6 @@ */ import { - ProfileSegment, CreateProfileTask, GetProfileTaskList, GetProfileTaskSegmentList, @@ -24,8 +23,6 @@ import { GetProfileTaskLogs, } from "../fragments/profile"; -export const queryProfileSegment = `query queryProfileSegment(${ProfileSegment.variable}) {${ProfileSegment.query}}`; - export const saveProfileTask = `mutation createProfileTask(${CreateProfileTask.variable}) {${CreateProfileTask.query}}`; export const getProfileTaskList = `query getProfileTaskList(${GetProfileTaskList.variable}) { diff --git a/src/store/modules/profile.ts b/src/store/modules/profile.ts index e1414695..780629b0 100644 --- a/src/store/modules/profile.ts +++ b/src/store/modules/profile.ts @@ -34,6 +34,7 @@ interface ProfileState { taskEndpoints: Endpoint[]; condition: { serviceId: string; endpointName: string }; taskList: TaskListItem[]; + currentTask: Recordable; segmentList: Trace[]; currentSegment: Recordable; segmentSpans: Array>; @@ -51,6 +52,7 @@ export const profileStore = defineStore({ condition: { serviceId: "", endpointName: "" }, taskList: [], segmentList: [], + currentTask: {}, currentSegment: {}, segmentSpans: [], currentSpan: {}, @@ -65,11 +67,27 @@ export const profileStore = defineStore({ ...data, }; }, + setCurrentTask(task: TaskListItem) { + this.currentTask = task || {}; + this.analyzeTrees = []; + }, + setSegmentSpans(spans: Recordable[]) { + this.currentSpan = spans[0] || {}; + this.segmentSpans = spans; + }, setCurrentSpan(span: Recordable) { this.currentSpan = span; + this.analyzeTrees = []; }, - setCurrentSegment(s: Recordable) { - this.currentSegment = s; + setCurrentSegment(segment: Trace) { + this.currentSegment = segment; + this.segmentSpans = segment.spans || []; + if (segment.spans) { + this.currentSpan = segment.spans[0] || {}; + } else { + this.currentSpan = {}; + } + this.analyzeTrees = []; }, setHighlightTop() { this.highlightTop = !this.highlightTop; @@ -104,8 +122,9 @@ export const profileStore = defineStore({ if (res.data.errors) { return res.data; } - const list = res.data.data.taskList; + const list = res.data.data.taskList || []; this.taskList = list; + this.currentTask = list[0] || {}; if (!list.length) { this.segmentList = []; this.segmentSpans = []; @@ -128,7 +147,7 @@ export const profileStore = defineStore({ } const { segmentList } = res.data.data; - this.segmentList = segmentList; + this.segmentList = segmentList || []; if (!segmentList.length) { this.segmentSpans = []; this.analyzeTrees = []; @@ -137,50 +156,22 @@ export const profileStore = defineStore({ } if (segmentList[0]) { this.currentSegment = segmentList[0]; - this.getSegmentSpans({ segmentId: segmentList[0].segmentId }); + this.getSegmentSpans(segmentList[0].segmentId); } else { this.currentSegment = {}; } return res.data; }, - async getSegmentSpans(params: { segmentId: string }) { - if (!params.segmentId) { - return new Promise((resolve) => resolve({})); - } - 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.map((d: SegmentSpan) => { - return { - ...d, - segmentId: this.currentSegment?.segmentId, - traceId: (this.currentSegment.traceIds as any)[0], - }; - }); - 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 getSegmentSpans() { + this.analyzeTrees = []; + this.segmentSpans = this.currentSegment.spans; + this.currentSpan = this.currentSegment.spans[0] || {}; }, - async getProfileAnalyze(params: { segmentId: string; timeRanges: Array<{ start: number; end: number }> }) { - if (!params.segmentId) { + async getProfileAnalyze(params: Array<{ segmentId: string; timeRange: { start: number; end: number } }>) { + if (!params.length) { return new Promise((resolve) => resolve({})); } - if (!params.timeRanges.length) { - return new Promise((resolve) => resolve({})); - } - const res: AxiosResponse = await graphql.query("getProfileAnalyze").params(params); + const res: AxiosResponse = await graphql.query("getProfileAnalyze").params({ queries: params }); if (res.data.errors) { this.analyzeTrees = []; diff --git a/src/styles/lib.scss b/src/styles/lib.scss index d0c1ecbe..9ea6b3d2 100644 --- a/src/styles/lib.scss +++ b/src/styles/lib.scss @@ -215,3 +215,31 @@ box-shadow: inset 0 0 6px #888; background-color: #999; } +.d3-tip { + line-height: 1; + padding: 8px; + color: #eee; + border-radius: 4px; + font-size: 12px; +} +.d3-tip { + background: #252a2f; +} + +.d3-tip:after { + box-sizing: border-box; + display: block; + font-size: 10px; + width: 100%; + line-height: 0.8; + color: #252a2f; + content: "\25BC"; + position: absolute; + text-align: center; +} + +.d3-tip.n:after { + margin: -2px 0 0 0; + top: 100%; + left: 0; +} diff --git a/src/types/trace.d.ts b/src/types/trace.d.ts index 9055e8a8..b71be5bb 100644 --- a/src/types/trace.d.ts +++ b/src/types/trace.d.ts @@ -22,6 +22,7 @@ export interface Trace { start: string; traceIds: Array; segmentId: string; + spans: Span[]; } export interface Span { diff --git a/src/views/dashboard/related/profile/components/SegmentList.vue b/src/views/dashboard/related/profile/components/SegmentList.vue index e19aeba1..23be2152 100644 --- a/src/views/dashboard/related/profile/components/SegmentList.vue +++ b/src/views/dashboard/related/profile/components/SegmentList.vue @@ -20,11 +20,11 @@ limitations under the License. --> {{ t("noData") }} - +
diff --git a/src/views/dashboard/related/profile/components/TaskList.vue b/src/views/dashboard/related/profile/components/TaskList.vue index 55c7f145..a3854227 100644 --- a/src/views/dashboard/related/profile/components/TaskList.vue +++ b/src/views/dashboard/related/profile/components/TaskList.vue @@ -25,7 +25,7 @@ limitations under the License. -->
@@ -49,7 +49,7 @@ limitations under the License. -->
-
+
{{ t("task") }}.
@@ -58,33 +58,35 @@ limitations under the License. -->
{{ t("endpoint") }}: - {{ selectedTask.endpointName }} + {{ profileStore.currentTask.endpointName }}
{{ t("monitorTime") }}: - {{ dateFormat(selectedTask.startTime) }} + {{ dateFormat(profileStore.currentTask.startTime) }}
{{ t("monitorDuration") }}:{{ selectedTask.duration }} min + >{{ profileStore.currentTask.duration }} min
{{ t("minThreshold") }}: - {{ selectedTask.minDurationThreshold }} ms + {{ profileStore.currentTask.minDurationThreshold }} ms
{{ t("dumpPeriod") }}: - {{ selectedTask.dumpPeriod }} + {{ profileStore.currentTask.dumpPeriod }}
{{ t("maxSamplingCount") }}: - {{ selectedTask.maxSamplingCount }} + {{ profileStore.currentTask.maxSamplingCount }}
-
{{ t("logs") }}.
+
+ {{ t("logs") }}. +
{{ t("instance") }}: @@ -115,12 +117,12 @@ limitations under the License. --> const selectorStore = useSelectorStore(); const viewDetail = ref(false); const service = ref(""); - const selectedTask = ref>({}); + // const selectedTask = ref>({}); const instanceLogs = ref({}); async function changeTask(item: TaskListItem) { profileStore.setCurrentSegment({}); - selectedTask.value = item; + profileStore.setCurrentTask(item); const res = await profileStore.getSegmentList({ taskID: item.id }); if (res.errors) { ElMessage.error(res.errors); @@ -130,7 +132,7 @@ limitations under the License. --> async function viewTask(e: Event, item: TaskListItem) { window.event ? (window.event.cancelBubble = true) : e.stopPropagation(); viewDetail.value = true; - selectedTask.value = item; + profileStore.setCurrentTask(item); service.value = (selectorStore.services.filter((s: any) => s.id === item.serviceId)[0] || {}).label; const res = await profileStore.getTaskLogs({ taskID: item.id }); @@ -150,7 +152,7 @@ limitations under the License. --> instanceLogs.value[d.instanceName] = [{ operationType: d.operationType, operationTime: d.operationTime }]; } } - selectedTask.value = item; + profileStore.setCurrentTask(item); }