feat: support cold stage data for metrics, trace and log (#469)

This commit is contained in:
Fine0830
2025-05-21 09:19:06 +08:00
committed by GitHub
parent 0c2cfa5630
commit a28972bc5c
17 changed files with 432 additions and 61 deletions

View File

@@ -30,6 +30,16 @@ limitations under the License. -->
<span class="grey">{{ t("searchKeyword") }}: </span>
<el-input size="small" v-model="keyword" class="alarm-tool-input" @change="refreshAlarms({ pageNum: 1 })" />
</div>
<div>
<span class="sm b grey mr-5">{{ t("timeRange") }}:</span>
<TimePicker
:value="[durationRow.start, durationRow.end]"
:maxRange="maxRange"
position="bottom"
format="YYYY-MM-DD HH:mm"
@input="changeDuration"
/>
</div>
<div class="pagination">
<el-pagination
v-model="pageNum"
@@ -51,31 +61,40 @@ limitations under the License. -->
</nav>
</template>
<script lang="ts" setup>
import { ref, computed } from "vue";
import { ref, computed, watch } from "vue";
import { useI18n } from "vue-i18n";
import { ElMessage } from "element-plus";
import ConditionTags from "@/views/components/ConditionTags.vue";
import { AlarmOptions } from "./data";
import { useAppStoreWithOut } from "@/store/modules/app";
import { useAppStoreWithOut, InitializationDurationRow } from "@/store/modules/app";
import { useAlarmStore } from "@/store/modules/alarm";
import { ElMessage } from "element-plus";
import { useDuration } from "@/hooks/useDuration";
import timeFormat from "@/utils/timeFormat";
import type { DurationTime, Duration } from "@/types/app";
import { Themes } from "@/constants/data";
/*global Recordable */
const appStore = useAppStoreWithOut();
const alarmStore = useAlarmStore();
const { t } = useI18n();
const { setDurationRow, getDurationTime, getMaxRange } = useDuration();
const pageSize = 20;
const entity = ref<string>("");
const keyword = ref<string>("");
const pageNum = ref<number>(1);
const duration = ref<DurationTime>(getDurationTime());
const durationRow = ref<Duration>(InitializationDurationRow);
const total = computed(() =>
alarmStore.alarms.length === pageSize ? pageSize * pageNum.value + 1 : pageSize * pageNum.value,
);
const maxRange = computed(() =>
getMaxRange(appStore.coldStageMode ? appStore.recordsTTL.coldValue : appStore.recordsTTL.value),
);
refreshAlarms({ pageNum: 1 });
async function refreshAlarms(param: { pageNum: number; tagsMap?: any }) {
const params: any = {
duration: appStore.durationTime,
async function refreshAlarms(param: { pageNum: number; tagsMap?: Recordable }) {
const params: Recordable = {
duration: duration.value,
paging: {
pageNum: param.pageNum,
pageSize,
@@ -91,7 +110,14 @@ limitations under the License. -->
}
}
function changeEntity(param: any) {
function changeDuration(val: Date[]) {
durationRow.value = timeFormat(val);
setDurationRow(durationRow.value);
duration.value = getDurationTime();
refreshAlarms({ pageNum: 1 });
}
function changeEntity(param: { value: string }[]) {
entity.value = param[0].value;
refreshAlarms({ pageNum: 1 });
}
@@ -100,6 +126,16 @@ limitations under the License. -->
pageNum.value = p;
refreshAlarms({ pageNum: p });
}
watch(
() => appStore.coldStageMode,
() => {
durationRow.value = InitializationDurationRow;
setDurationRow(durationRow.value);
duration.value = getDurationTime();
refreshAlarms({ pageNum: 1 });
},
);
</script>
<style lang="scss" scoped>
.alarm-tool {

View File

@@ -56,6 +56,16 @@ limitations under the License. -->
@change="changeField('category', $event)"
/>
</div>
<div>
<span class="sm b grey mr-5">{{ t("timeRange") }}:</span>
<TimePicker
:value="[durationRow.start, durationRow.end]"
:maxRange="maxRange"
position="bottom"
format="YYYY-MM-DD HH:mm"
@input="changeDuration"
/>
</div>
<el-button class="search-btn" size="small" type="primary" @click="searchLogs">
{{ t("search") }}
</el-button>
@@ -119,20 +129,21 @@ limitations under the License. -->
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, watch, onUnmounted } from "vue";
import { ref, reactive, watch, onUnmounted, computed } from "vue";
import type { PropType } from "vue";
import { useI18n } from "vue-i18n";
import type { Option } from "@/types/app";
import { ElMessage } from "element-plus";
import { useLogStore } from "@/store/modules/log";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app";
import { useAppStoreWithOut, InitializationDurationRow } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors";
import { useDuration } from "@/hooks/useDuration";
import ConditionTags from "@/views/components/ConditionTags.vue";
import { ElMessage } from "element-plus";
import timeFormat from "@/utils/timeFormat";
import { EntityType } from "../../data";
import { ErrorCategory } from "./data";
import type { LayoutConfig } from "@/types/dashboard";
import type { DurationTime } from "@/types/app";
import type { Option, DurationTime, Duration } from "@/types/app";
/*global defineProps, Recordable */
const props = defineProps({
@@ -147,8 +158,9 @@ limitations under the License. -->
const selectorStore = useSelectorStore();
const dashboardStore = useDashboardStore();
const logStore = useLogStore();
const { setDurationRow, getDurationTime, getMaxRange } = useDuration();
const traceId = ref<string>((props.data.filters && props.data.filters.traceId) || "");
const duration = ref<DurationTime>((props.data.filters && props.data.filters.duration) || appStore.durationTime);
const duration = ref<DurationTime>((props.data.filters && props.data.filters.duration) || getDurationTime());
const keywordsOfContent = ref<string[]>([]);
const excludingKeywordsOfContent = ref<string[]>([]);
const tagsList = ref<string[]>([]);
@@ -156,12 +168,16 @@ limitations under the License. -->
const contentStr = ref<string>("");
const excludingContentStr = ref<string>("");
const isBrowser = ref<boolean>(dashboardStore.layerId === "BROWSER");
const durationRow = ref<Duration>(InitializationDurationRow);
const state = reactive<Recordable>({
instance: { value: "0", label: "All" },
endpoint: { value: "0", label: "All" },
service: { value: "", label: "" },
category: { value: "ALL", label: "All" },
});
const maxRange = computed(() =>
getMaxRange(appStore.coldStageMode ? appStore.recordsTTL.coldSuperDataset : appStore.recordsTTL.superDataset),
);
if (props.needQuery) {
init();
}
@@ -275,6 +291,11 @@ limitations under the License. -->
ElMessage.error(res.errors);
}
}
function changeDuration(val: Date[]) {
durationRow.value = timeFormat(val);
setDurationRow(durationRow.value);
duration.value = getDurationTime();
}
function changeField(type: string, opt: any) {
state[type] = opt[0];
if (type === "service") {
@@ -352,12 +373,12 @@ limitations under the License. -->
},
);
watch(
() => appStore.durationTime,
() => appStore.coldStageMode,
() => {
duration.value = appStore.durationTime;
if (dashboardStore.entity === EntityType[1].value) {
init();
}
durationRow.value = InitializationDurationRow;
setDurationRow(durationRow.value);
duration.value = getDurationTime();
init();
},
);
watch(
@@ -368,7 +389,7 @@ limitations under the License. -->
return;
}
traceId.value = props.data.filters.traceId || "";
duration.value = props.data.filters.duration || appStore.durationTime;
duration.value = props.data.filters.duration || getDurationTime();
init();
}
},

View File

@@ -71,24 +71,36 @@ limitations under the License. -->
<span class="grey mr-5">-</span>
<el-input size="small" class="inputs" v-model="maxTraceDuration" type="number" />
</div>
<div>
<span class="sm b grey mr-5">{{ t("timeRange") }}:</span>
<TimePicker
:value="[durationRow.start, durationRow.end]"
:maxRange="maxRange"
position="bottom"
format="YYYY-MM-DD HH:mm"
@input="changeDuration"
/>
</div>
</div>
<div class="flex-h">
<ConditionTags :type="'TRACE'" @update="updateTags" />
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, watch, onUnmounted } from "vue";
import { ref, reactive, watch, onUnmounted, computed } from "vue";
import type { PropType } from "vue";
import { useI18n } from "vue-i18n";
import type { Option, DurationTime } from "@/types/app";
import type { Option, DurationTime, Duration } from "@/types/app";
import { useTraceStore } from "@/store/modules/trace";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app";
import { useAppStoreWithOut, InitializationDurationRow } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors";
import timeFormat from "@/utils/timeFormat";
import ConditionTags from "@/views/components/ConditionTags.vue";
import { ElMessage } from "element-plus";
import { EntityType, QueryOrders, Status } from "../../data";
import type { LayoutConfig } from "@/types/dashboard";
import { useDuration } from "@/hooks/useDuration";
/*global defineProps, defineEmits, Recordable */
const emits = defineEmits(["get", "search"]);
@@ -99,14 +111,15 @@ limitations under the License. -->
default: () => ({ graph: {} }),
},
});
const filters = reactive<Recordable>(props.data.filters || {});
const traceId = ref<string>(filters.traceId || "");
const { t } = useI18n();
const appStore = useAppStoreWithOut();
const selectorStore = useSelectorStore();
const dashboardStore = useDashboardStore();
const traceStore = useTraceStore();
const duration = ref<DurationTime>(filters.duration || appStore.durationTime);
const { setDurationRow, getDurationTime, getMaxRange } = useDuration();
const filters = reactive<Recordable>(props.data.filters || {});
const traceId = ref<string>(filters.traceId || "");
const duration = ref<DurationTime>(filters.duration || getDurationTime());
const minTraceDuration = ref<number>();
const maxTraceDuration = ref<number>();
const tagsList = ref<string[]>([]);
@@ -117,6 +130,10 @@ limitations under the License. -->
endpoint: { value: "0", label: "All" },
service: { value: "", label: "" },
});
const durationRow = ref<Duration>(InitializationDurationRow);
const maxRange = computed(() =>
getMaxRange(appStore.coldStageMode ? appStore.recordsTTL.coldSuperDataset : appStore.recordsTTL.superDataset),
);
if (filters.queryOrder) {
traceStore.setTraceCondition({
queryOrder: filters.queryOrder,
@@ -255,6 +272,11 @@ limitations under the License. -->
ElMessage.error(resp.errors);
}
}
function changeDuration(val: Date[]) {
durationRow.value = timeFormat(val);
setDurationRow(durationRow.value);
duration.value = getDurationTime();
}
onUnmounted(() => {
traceStore.resetState();
const config = props.data;
@@ -280,12 +302,12 @@ limitations under the License. -->
},
);
watch(
() => appStore.durationTime,
() => appStore.coldStageMode,
() => {
duration.value = appStore.durationTime;
if (dashboardStore.entity === EntityType[1].value) {
init();
}
durationRow.value = InitializationDurationRow;
setDurationRow(durationRow.value);
duration.value = getDurationTime();
init();
},
);
// Event widget associate with trace widget
@@ -299,7 +321,7 @@ limitations under the License. -->
return;
}
traceId.value = props.data.filters.traceId || "";
duration.value = props.data.filters.duration || appStore.durationTime;
duration.value = props.data.filters.duration || getDurationTime();
init();
},
);

View File

@@ -31,6 +31,12 @@ limitations under the License. -->
@change="changeLatency"
class="ml-10"
/>
<TimePicker
:value="[appStore.durationRow.start, appStore.durationRow.end]"
position="bottom"
format="YYYY-MM-DD HH:mm"
@input="changeTimeRange"
/>
<el-popover trigger="hover" width="250" placement="bottom">
<template #reference>
<div class="cp conditions-popup">
@@ -82,6 +88,7 @@ limitations under the License. -->
import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors";
import timeFormat from "@/utils/timeFormat";
import ConditionTags from "@/views/components/ConditionTags.vue";
import { ElMessage } from "element-plus";
import { EntityType, QueryOrders, Status } from "../../data";
@@ -107,6 +114,7 @@ limitations under the License. -->
const selectorStore = useSelectorStore();
const dashboardStore = useDashboardStore();
const traceStore = useTraceStore();
const timeRange = ref<number>(NaN);
const tagsList = ref<string[]>([]);
const tagsMap = ref<Option[]>([]);
const traceId = ref<string>(filters.refId || "");
@@ -169,6 +177,15 @@ limitations under the License. -->
}
await queryTraces();
}
function changeTimeRange(val: Date[]) {
timeRange.value = val[1].getTime() - val[0].getTime() > 60 * 24 * 60 * 60 * 1000 ? 1 : 0;
if (timeRange.value) {
return;
}
appStore.setDuration(timeFormat(val));
}
function changeCondition() {
if (conditions.value === "latency") {
currentLatency.value = filters.latency ? filters.latency[0].data : [];