mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-09 04:03:31 +00:00
fix: enhance VNode logic and support multiple Trace IDs in span's ref (#369)
This commit is contained in:
parent
7d24e065e9
commit
860af150f7
@ -24,7 +24,7 @@ export default function getDashboard(param?: { name?: string; layer: string; ent
|
||||
const dashboardStore = useDashboardStore();
|
||||
const opt = param || dashboardStore.currentDashboard;
|
||||
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
|
||||
let dashboard;
|
||||
let dashboard: Recordable;
|
||||
if (type === ConfigFieldTypes.NAME) {
|
||||
dashboard = list.find(
|
||||
(d: { name: string; layer: string; entity: string }) =>
|
||||
@ -62,6 +62,9 @@ export default function getDashboard(param?: { name?: string; layer: string; ent
|
||||
filters,
|
||||
};
|
||||
dashboardStore.setWidget(item);
|
||||
if (widget.id === sourceId) {
|
||||
return;
|
||||
}
|
||||
const targetTabIndex = (widget.id || "").split("-");
|
||||
const sourceTabindex = (sourceId || "").split("-") || [];
|
||||
let container: Nullable<Element>;
|
||||
|
@ -24,7 +24,6 @@ import { useSelectorStore } from "@/store/modules/selectors";
|
||||
import { NewControl, TextConfig, TimeRangeConfig, ControlsTypes } from "../data";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { EntityType, MetricModes, WidgetType } from "@/views/dashboard/data";
|
||||
interface DashboardState {
|
||||
showConfig: boolean;
|
||||
|
@ -150,7 +150,13 @@ limitations under the License. -->
|
||||
ElMessage.error(resp.errors);
|
||||
return;
|
||||
}
|
||||
if (props.data.filters && props.data.filters.id === "0") {
|
||||
state.service = { value: "", label: "" };
|
||||
return;
|
||||
} else {
|
||||
state.service = getCurrentNode(traceStore.services) || traceStore.services[0];
|
||||
}
|
||||
|
||||
emits("get", state.service.id);
|
||||
|
||||
getEndpoints(state.service.id);
|
||||
@ -198,7 +204,7 @@ limitations under the License. -->
|
||||
if (props.data.filters && props.data.filters.id) {
|
||||
param = {
|
||||
...param,
|
||||
serviceId: props.data.filters.id || undefined,
|
||||
serviceId: props.data.filters.id && props.data.filters.id !== "0" ? props.data.filters.id : undefined,
|
||||
endpointId: state.endpoint.id || undefined,
|
||||
serviceInstanceId: state.instance.id || undefined,
|
||||
};
|
||||
|
@ -227,7 +227,8 @@ limitations under the License. -->
|
||||
|
||||
.no-data {
|
||||
padding-top: 50px;
|
||||
width: 100%;
|
||||
width: 280px;
|
||||
text-align: center;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
@ -139,11 +139,18 @@ limitations under the License. -->
|
||||
}
|
||||
segmentHeaders.forEach((span: Span) => {
|
||||
if (span.refs.length) {
|
||||
let exit = 0;
|
||||
span.refs.forEach((ref) => {
|
||||
const index = props.data.findIndex(
|
||||
const i = props.data.findIndex(
|
||||
(i: Recordable) => ref.parentSegmentId === i.segmentId && ref.parentSpanId === i.spanId,
|
||||
);
|
||||
if (index === -1) {
|
||||
if (i > -1) {
|
||||
exit = 1;
|
||||
}
|
||||
});
|
||||
|
||||
if (!exit) {
|
||||
const ref = span.refs[0];
|
||||
// create a known broken node.
|
||||
const i = ref.parentSpanId;
|
||||
const fixSpanKeyContent = {
|
||||
@ -198,16 +205,14 @@ limitations under the License. -->
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
[...fixSpans, ...props.data].forEach((i) => {
|
||||
i.label = i.endpointName || "no operation name";
|
||||
i.children = [];
|
||||
if (segmentGroup[i.segmentId] === undefined) {
|
||||
if (!segmentGroup[i.segmentId]) {
|
||||
segmentIdGroup.push(i.segmentId);
|
||||
segmentGroup[i.segmentId] = [];
|
||||
segmentGroup[i.segmentId].push(i);
|
||||
segmentGroup[i.segmentId] = [i];
|
||||
} else {
|
||||
segmentGroup[i.segmentId].push(i);
|
||||
}
|
||||
|
@ -42,6 +42,12 @@ limitations under the License. -->
|
||||
<span class="g-sm-4 grey">{{ t("isError") }}:</span>
|
||||
<span class="g-sm-8 wba">{{ currentSpan.isError }}</span>
|
||||
</div>
|
||||
<h5 class="mb-10" v-if="diffRefs.length"> {{ t("traceID") }}. </h5>
|
||||
<div class="mb-10 clear item" v-for="item in diffRefs" :key="item.traceId">
|
||||
<span class="g-sm-12 wba cp link" @click="viewRelateTrace(item)">
|
||||
{{ item.traceId }}
|
||||
</span>
|
||||
</div>
|
||||
<h5 class="mb-10" v-if="currentSpan.tags && currentSpan.tags.length"> {{ t("tags") }}. </h5>
|
||||
<div class="mb-10 clear item" v-for="i in currentSpan.tags" :key="i.key">
|
||||
<span class="g-sm-4 grey">{{ i.key }}:</span>
|
||||
@ -127,7 +133,7 @@ limitations under the License. -->
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, onMounted } from "vue";
|
||||
import { ref, computed, onMounted, inject } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import type { PropType } from "vue";
|
||||
import dayjs from "dayjs";
|
||||
@ -138,14 +144,20 @@ limitations under the License. -->
|
||||
import { useTraceStore } from "@/store/modules/trace";
|
||||
import LogTable from "@/views/dashboard/related/log/LogTable/Index.vue";
|
||||
import type { SpanAttachedEvent } from "@/types/trace";
|
||||
import getDashboard from "@/hooks/useDashboardsSession";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import { WidgetType } from "@/views/dashboard/data";
|
||||
import type { LayoutConfig } from "@/types/dashboard";
|
||||
|
||||
/*global defineProps, Nullable, Recordable */
|
||||
const props = defineProps({
|
||||
currentSpan: { type: Object as PropType<Recordable>, default: () => ({}) },
|
||||
traceId: { type: String, default: "" },
|
||||
});
|
||||
const options: Recordable<LayoutConfig> = inject("options") || {};
|
||||
const { t } = useI18n();
|
||||
const traceStore = useTraceStore();
|
||||
const dashboardStore = useDashboardStore();
|
||||
const pageNum = ref<number>(1);
|
||||
const showRelatedLogs = ref<boolean>(false);
|
||||
const showEventDetail = ref<boolean>(false);
|
||||
@ -154,6 +166,9 @@ limitations under the License. -->
|
||||
const total = computed(() =>
|
||||
traceStore.traceList.length === pageSize ? pageSize * pageNum.value + 1 : pageSize * pageNum.value,
|
||||
);
|
||||
const diffRefs = computed(() =>
|
||||
props.currentSpan.refs.filter((d: Recordable) => d.traceId !== props.currentSpan.traceId),
|
||||
);
|
||||
const tree = ref<any>(null);
|
||||
const eventGraph = ref<Nullable<HTMLDivElement>>(null);
|
||||
const visDate = (date: number, pattern = "YYYY-MM-DD HH:mm:ss:SSS") => dayjs(date).format(pattern);
|
||||
@ -217,6 +232,19 @@ limitations under the License. -->
|
||||
tree.value.draw();
|
||||
}
|
||||
|
||||
function viewRelateTrace(item: Recordable) {
|
||||
const { associationWidget } = getDashboard(dashboardStore.currentDashboard);
|
||||
associationWidget(
|
||||
(options.id as any) || "",
|
||||
{
|
||||
sourceId: options.id || "",
|
||||
traceId: item.traceId || "",
|
||||
id: "0",
|
||||
},
|
||||
WidgetType.Trace,
|
||||
);
|
||||
}
|
||||
|
||||
function selectEvent(i: any) {
|
||||
currentEvent.value = i.data;
|
||||
showEventDetail.value = true;
|
||||
@ -259,7 +287,12 @@ limitations under the License. -->
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.link,
|
||||
.link-hover:hover {
|
||||
color: #448dfe;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user