mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-01 19:03:40 +00:00
feat: enhance associating metrics with traces by refId
(#192)
This commit is contained in:
parent
7a1c83b5fb
commit
23e9742946
@ -124,7 +124,7 @@ export default defineComponent({
|
||||
const title = computed(() => encodeURIComponent(widget.value.title || ""));
|
||||
const tips = computed(() => encodeURIComponent(widget.value.tips || ""));
|
||||
const hasAssociate = computed(() =>
|
||||
["Bar", "Line", "Area"].includes(
|
||||
["Bar", "Line", "Area", "TopList"].includes(
|
||||
dashboardStore.selectedGrid.graph &&
|
||||
dashboardStore.selectedGrid.graph.type
|
||||
)
|
||||
|
@ -13,7 +13,18 @@ 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="item">
|
||||
<div v-if="type === 'TopList'" class="item">
|
||||
<span class="label">RefId</span>
|
||||
<Selector
|
||||
size="small"
|
||||
:value="refIdType"
|
||||
:options="RefIdTypes"
|
||||
placeholder="Select a refId"
|
||||
@change="updateConfig({ refIdType: $event[0].value })"
|
||||
class="selector"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="item">
|
||||
<span class="label">{{ t("enableRelatedTrace") }}</span>
|
||||
<el-switch
|
||||
v-model="enableRelate"
|
||||
@ -22,7 +33,7 @@ limitations under the License. -->
|
||||
@change="updateConfig({ enableRelate })"
|
||||
/>
|
||||
</div>
|
||||
<div v-show="enableRelate">
|
||||
<div v-if="enableRelate">
|
||||
<div class="item">
|
||||
<span class="label">{{ t("status") }}</span>
|
||||
<Selector
|
||||
@ -60,15 +71,18 @@ limitations under the License. -->
|
||||
import { ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||
import { Status, QueryOrders } from "../../data";
|
||||
import { Status, QueryOrders, RefIdTypes } from "../../data";
|
||||
|
||||
const { t } = useI18n();
|
||||
const dashboardStore = useDashboardStore();
|
||||
const traceOpt = dashboardStore.selectedGrid.relatedTrace || {};
|
||||
const { graph, relatedTrace } = dashboardStore.selectedGrid;
|
||||
const traceOpt = (relatedTrace && relatedTrace.traceOpt) || {};
|
||||
const status = ref<string>(traceOpt.status || Status[0].value);
|
||||
const queryOrder = ref<string>(traceOpt.queryOrder || QueryOrders[0].value);
|
||||
const latency = ref<boolean>(traceOpt.latency || false);
|
||||
const enableRelate = ref<boolean>(traceOpt.enableRelate || false);
|
||||
const type = ref<string>((graph && graph.type) || "");
|
||||
const refIdType = ref<string>(traceOpt.refIdType || "traceId");
|
||||
|
||||
function updateConfig(param: { [key: string]: unknown }) {
|
||||
const relatedTrace = {
|
||||
|
@ -298,3 +298,7 @@ export const CalculationOpts = [
|
||||
{ label: "Seconds to days", value: "secondToDay" },
|
||||
{ label: "Nanoseconds to milliseconds", value: "nanosecondToMillisecond" },
|
||||
];
|
||||
export const RefIdTypes = [
|
||||
{ label: "Trace ID", value: "traceId" },
|
||||
{ label: "None", value: "none" },
|
||||
];
|
||||
|
@ -32,7 +32,11 @@ limitations under the License. -->
|
||||
<div class="operation" @click="handleClick(i.name)">
|
||||
<span>{{ t("copy") }}</span>
|
||||
</div>
|
||||
<div class="operation" @click="viewTrace(i)">
|
||||
<div
|
||||
class="operation"
|
||||
@click="viewTrace(i)"
|
||||
v-show="refIdType === RefIdTypes[0].value"
|
||||
>
|
||||
<span>{{ t("viewTrace") }}</span>
|
||||
</div>
|
||||
</el-popover>
|
||||
@ -63,7 +67,7 @@ import { computed, ref } from "vue";
|
||||
import copy from "@/utils/copy";
|
||||
import { TextColors } from "@/views/dashboard/data";
|
||||
import Trace from "@/views/dashboard/related/trace/Index.vue";
|
||||
import { QueryOrders, Status } from "../data";
|
||||
import { QueryOrders, Status, RefIdTypes } from "../data";
|
||||
/*global defineProps */
|
||||
const props = defineProps({
|
||||
data: {
|
||||
@ -73,7 +77,11 @@ const props = defineProps({
|
||||
default: () => ({}),
|
||||
},
|
||||
config: {
|
||||
type: Object as PropType<{ color: string; metrics: string[] }>,
|
||||
type: Object as PropType<{
|
||||
color: string;
|
||||
metrics: string[];
|
||||
relatedTrace: any;
|
||||
}>,
|
||||
default: () => ({ color: "purple" }),
|
||||
},
|
||||
intervalTime: { type: Array as PropType<string[]>, default: () => [] },
|
||||
@ -83,6 +91,11 @@ const showTrace = ref<boolean>(false);
|
||||
const traceOptions = ref<{ type: string; filters?: unknown }>({
|
||||
type: "Trace",
|
||||
});
|
||||
const refIdType = computed(
|
||||
() =>
|
||||
(props.config.relatedTrace && props.config.relatedTrace.refIdType) ||
|
||||
RefIdTypes[0].value
|
||||
);
|
||||
const key = computed(() => Object.keys(props.data)[0] || "");
|
||||
const available = computed(
|
||||
() =>
|
||||
@ -105,6 +118,7 @@ function viewTrace(item: { name: string; id: string; value: unknown }) {
|
||||
...item,
|
||||
queryOrder: QueryOrders[1].value,
|
||||
status: Status[2].value,
|
||||
id: item.id || item.name,
|
||||
metricValue: [
|
||||
{ label: props.config.metrics[0], data: item.value, value: item.name },
|
||||
],
|
||||
|
@ -13,7 +13,11 @@ 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="conditions flex-h">
|
||||
<div v-if="filters.id" class="conditions flex-h">
|
||||
<div class="label grey">TraceId:</div>
|
||||
<el-input size="small" v-model="traceId" class="trace-id" />
|
||||
</div>
|
||||
<div class="conditions flex-h" v-else>
|
||||
<el-radio-group v-model="conditions" @change="changeCondition">
|
||||
<el-radio-button
|
||||
v-for="(item, index) in items"
|
||||
@ -40,12 +44,18 @@ limitations under the License. -->
|
||||
</template>
|
||||
<div>
|
||||
<div class="title">{{ t("queryConditions") }}</div>
|
||||
<div
|
||||
v-for="key in Object.keys(FiltersKeys)"
|
||||
:key="key"
|
||||
v-show="traceStore.conditions[FiltersKeys[key]]"
|
||||
>
|
||||
<span v-if="key !== 'duration'">
|
||||
<div v-for="key in Object.keys(FiltersKeys)" :key="key">
|
||||
<span
|
||||
v-if="
|
||||
[
|
||||
FiltersKeys.minTraceDuration,
|
||||
FiltersKeys.maxTraceDuration,
|
||||
].includes(key) && !isNaN(traceStore.conditions[FiltersKeys[key]])
|
||||
"
|
||||
>
|
||||
{{ t(key) }}: {{ traceStore.conditions[FiltersKeys[key]] }}
|
||||
</span>
|
||||
<span v-else-if="key !== 'duration'">
|
||||
{{ t(key) }}: {{ traceStore.conditions[FiltersKeys[key]] }}
|
||||
</span>
|
||||
</div>
|
||||
@ -111,6 +121,7 @@ const dashboardStore = useDashboardStore();
|
||||
const traceStore = useTraceStore();
|
||||
const tagsList = ref<string[]>([]);
|
||||
const tagsMap = ref<Option[]>([]);
|
||||
const traceId = ref<string>(filters.refId || "");
|
||||
const duration = ref<DurationTime>(filters.duration || appStore.durationTime);
|
||||
const state = reactive<Recordable>({
|
||||
instance: "",
|
||||
@ -122,13 +133,13 @@ const items = ref<{ label: string; value: string }[]>([]);
|
||||
const currentLatency = ref<number[]>(
|
||||
filters.latency ? filters.latency[0].data : []
|
||||
);
|
||||
|
||||
init();
|
||||
|
||||
async function init() {
|
||||
for (const d of Object.keys(filters)) {
|
||||
if (
|
||||
["status", "queryOrder"].includes(d) ||
|
||||
["queryOrder"].includes(d) ||
|
||||
(d === "status" && filters[d] && filters[d] !== "ALL") ||
|
||||
(filters[d] && d === "latency")
|
||||
) {
|
||||
items.value.push({ label: d, value: FiltersKeys[d] });
|
||||
@ -199,20 +210,14 @@ function setCondition() {
|
||||
traceState: Status[0].value,
|
||||
queryOrder: QueryOrders[0].value,
|
||||
queryDuration: duration.value,
|
||||
minTraceDuration: isNaN(currentLatency.value[0])
|
||||
? undefined
|
||||
: currentLatency.value[0] === currentLatency.value[1]
|
||||
? currentLatency.value[0] - 10
|
||||
: currentLatency.value[0],
|
||||
maxTraceDuration:
|
||||
isNaN(currentLatency.value[1]) || currentLatency.value[1] === Infinity
|
||||
? undefined
|
||||
: currentLatency.value[1],
|
||||
minTraceDuration: currentLatency.value[0],
|
||||
maxTraceDuration: currentLatency.value[1],
|
||||
tags: tagsMap.value.length ? tagsMap.value : undefined,
|
||||
paging: { pageNum: 1, pageSize: 20 },
|
||||
serviceId: state.service || undefined,
|
||||
endpointId: state.endpoint || undefined,
|
||||
serviceInstanceId: state.instance || undefined,
|
||||
traceId: traceId.value || undefined,
|
||||
};
|
||||
for (const k of items.value) {
|
||||
if (
|
||||
@ -271,4 +276,13 @@ onUnmounted(() => {
|
||||
margin-bottom: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.trace-id {
|
||||
width: 300px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.label {
|
||||
line-height: 22px;
|
||||
}
|
||||
</style>
|
||||
|
@ -101,28 +101,41 @@ limitations under the License. -->
|
||||
@closed="showEventDetail = false"
|
||||
>
|
||||
<div>
|
||||
<div>Name: {{ currentEvent.event || "" }}</div>
|
||||
<div>
|
||||
Start Time:
|
||||
<div class="mb-10">
|
||||
<span class="grey">Name:</span>
|
||||
{{ currentEvent.event || "" }}
|
||||
</div>
|
||||
<div class="mb-10">
|
||||
<span class="grey">Start Time:</span>
|
||||
{{
|
||||
currentEvent.startTime ? visDate(Number(currentEvent.startTime)) : ""
|
||||
}}
|
||||
</div>
|
||||
<div>
|
||||
End Time:
|
||||
<div class="mb-10">
|
||||
<span class="grey">End Time:</span>
|
||||
{{ currentEvent.endTime ? visDate(Number(currentEvent.endTime)) : "" }}
|
||||
</div>
|
||||
<div>
|
||||
Summary:
|
||||
{{(currentEvent.summary || [])
|
||||
.map((d: any) => d.key + "=" + d.value)
|
||||
.join("; ")}}
|
||||
<div class="mb-10">
|
||||
<span class="grey">Summary:</span>
|
||||
<div
|
||||
class="mb-5"
|
||||
v-for="(d, index) in currentEvent.summary || []"
|
||||
:key="index"
|
||||
style="white-space: pre-wrap"
|
||||
>
|
||||
{{ d.key + "=" + d.value }};
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
Tags:
|
||||
{{(currentEvent.tags || [])
|
||||
.map((d: any) => d.key + "=" + d.value)
|
||||
.join("; ")}}
|
||||
<span class="grey">Tags:</span>
|
||||
<div
|
||||
class="mb-5"
|
||||
v-for="(tag, index) in currentEvent.tags || []"
|
||||
:key="index"
|
||||
style="white-space: pre-wrap"
|
||||
>
|
||||
{{ tag.key + "=" + tag.value }};
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -241,9 +254,7 @@ function visTimeline() {
|
||||
width: "100%",
|
||||
locale: "en",
|
||||
groupHeightMode: "fitItems",
|
||||
autoResize: false,
|
||||
zoomMin: 80,
|
||||
zoomMax: 3600000,
|
||||
};
|
||||
|
||||
visGraph.value = new Timeline(timeline.value, items, options);
|
||||
|
Loading…
Reference in New Issue
Block a user