mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-06-17 10:07:36 +00:00
feat: support cold stage data for metrics, trace and log (#469)
This commit is contained in:
parent
0c2cfa5630
commit
a28972bc5c
@ -169,12 +169,13 @@ limitations under the License. -->
|
|||||||
value: { type: Date },
|
value: { type: Date },
|
||||||
left: { type: Boolean, default: false },
|
left: { type: Boolean, default: false },
|
||||||
right: { type: Boolean, default: false },
|
right: { type: Boolean, default: false },
|
||||||
dates: { type: Array as PropType<number[] | string[]>, default: () => [] },
|
dates: { type: Array as PropType<Date[]>, default: () => [] },
|
||||||
disabledDate: { type: Function, default: () => false },
|
disabledDate: { type: Function, default: () => false },
|
||||||
format: {
|
format: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "YYYY-MM-DD",
|
default: "YYYY-MM-DD",
|
||||||
},
|
},
|
||||||
|
maxRange: { type: Array as PropType<Date[]>, default: () => [] },
|
||||||
});
|
});
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
pre: "",
|
pre: "",
|
||||||
@ -241,6 +242,12 @@ limitations under the License. -->
|
|||||||
const end = computed(() => {
|
const end = computed(() => {
|
||||||
return parse(Number(props.dates[1]));
|
return parse(Number(props.dates[1]));
|
||||||
});
|
});
|
||||||
|
const minStart = computed(() => {
|
||||||
|
return parse(Number(props.maxRange[0]));
|
||||||
|
});
|
||||||
|
const maxEnd = computed(() => {
|
||||||
|
return parse(Number(props.maxRange[1]));
|
||||||
|
});
|
||||||
const ys = computed(() => {
|
const ys = computed(() => {
|
||||||
return Math.floor(state.year / 10) * 10;
|
return Math.floor(state.year / 10) * 10;
|
||||||
});
|
});
|
||||||
@ -369,7 +376,10 @@ limitations under the License. -->
|
|||||||
flag = tf(props.value, format) === tf(time, format);
|
flag = tf(props.value, format) === tf(time, format);
|
||||||
}
|
}
|
||||||
classObj[`${state.pre}-date`] = true;
|
classObj[`${state.pre}-date`] = true;
|
||||||
classObj[`${state.pre}-date-disabled`] = (props.right && t < start.value) || props.disabledDate(time, format);
|
const rightDisabled = props.right && (t < start.value || t > maxEnd.value || !props.maxRange?.length);
|
||||||
|
const leftDisabled =
|
||||||
|
props.left && (t < minStart.value || t > end.value || !props.maxRange?.length || t > maxEnd.value);
|
||||||
|
classObj[`${state.pre}-date-disabled`] = rightDisabled || leftDisabled || props.disabledDate(time, format);
|
||||||
classObj[`${state.pre}-date-on`] = (props.left && t > start.value) || (props.right && t < end.value);
|
classObj[`${state.pre}-date-on`] = (props.left && t > start.value) || (props.right && t < end.value);
|
||||||
classObj[`${state.pre}-date-selected`] = flag;
|
classObj[`${state.pre}-date-selected`] = flag;
|
||||||
return classObj;
|
return classObj;
|
||||||
|
@ -68,6 +68,7 @@ limitations under the License. -->
|
|||||||
:left="true"
|
:left="true"
|
||||||
:disabledDate="disabledDate"
|
:disabledDate="disabledDate"
|
||||||
:format="format"
|
:format="format"
|
||||||
|
:maxRange="maxRange"
|
||||||
@ok="ok"
|
@ok="ok"
|
||||||
@setDates="setDates"
|
@setDates="setDates"
|
||||||
/>
|
/>
|
||||||
@ -78,6 +79,7 @@ limitations under the License. -->
|
|||||||
:right="true"
|
:right="true"
|
||||||
:disabledDate="disabledDate"
|
:disabledDate="disabledDate"
|
||||||
:format="format"
|
:format="format"
|
||||||
|
:maxRange="maxRange"
|
||||||
@ok="ok"
|
@ok="ok"
|
||||||
@setDates="setDates"
|
@setDates="setDates"
|
||||||
/>
|
/>
|
||||||
@ -112,11 +114,11 @@ limitations under the License. -->
|
|||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import DateCalendar from "./DateCalendar.vue";
|
import DateCalendar from "./DateCalendar.vue";
|
||||||
import { useTimeoutFn } from "@/hooks/useTimeout";
|
import { useTimeoutFn } from "@/hooks/useTimeout";
|
||||||
/*global defineProps, defineEmits*/
|
/*global PropType, defineProps, defineEmits*/
|
||||||
const datepicker = ref(null);
|
const datepicker = ref(null);
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const show = ref<boolean>(false);
|
const show = ref<boolean>(false);
|
||||||
const dates = ref<Date | string[] | any>([]);
|
const dates = ref<Date[]>([]);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
position: { type: String, default: "bottom" },
|
position: { type: String, default: "bottom" },
|
||||||
name: [String],
|
name: [String],
|
||||||
@ -149,7 +151,7 @@ limitations under the License. -->
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
dateRangeSelect: [Function],
|
maxRange: { type: Array as PropType<Date[]>, default: () => [] },
|
||||||
});
|
});
|
||||||
const emit = defineEmits(["clear", "input", "confirm", "cancel"]);
|
const emit = defineEmits(["clear", "input", "confirm", "cancel"]);
|
||||||
const local = computed(() => {
|
const local = computed(() => {
|
||||||
|
@ -49,3 +49,22 @@ export const MenuItems = {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const RecordsTTL = {
|
||||||
|
query: `getRecordsTTL {
|
||||||
|
value
|
||||||
|
superDataset
|
||||||
|
coldValue
|
||||||
|
coldSuperDataset
|
||||||
|
}`,
|
||||||
|
};
|
||||||
|
export const MetricsTTL = {
|
||||||
|
query: `getMetricsTTL {
|
||||||
|
minute
|
||||||
|
hour
|
||||||
|
day
|
||||||
|
coldMinute
|
||||||
|
coldHour
|
||||||
|
coldDay
|
||||||
|
}`,
|
||||||
|
};
|
||||||
|
@ -103,3 +103,63 @@ export const TraceTagValues = {
|
|||||||
query: `
|
query: `
|
||||||
tagValues: queryTraceTagAutocompleteValues(tagKey: $tagKey, duration: $duration)`,
|
tagValues: queryTraceTagAutocompleteValues(tagKey: $tagKey, duration: $duration)`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const TraceSpansFromColdStage = {
|
||||||
|
variable: "$traceId: ID!, $duration: Duration!, $debug: Boolean",
|
||||||
|
query: `
|
||||||
|
trace: queryTrace(traceId: $traceId, duration: $duration, debug: $debug) {
|
||||||
|
spans {
|
||||||
|
traceId
|
||||||
|
segmentId
|
||||||
|
spanId
|
||||||
|
parentSpanId
|
||||||
|
refs {
|
||||||
|
traceId
|
||||||
|
parentSegmentId
|
||||||
|
parentSpanId
|
||||||
|
type
|
||||||
|
}
|
||||||
|
serviceCode
|
||||||
|
serviceInstanceName
|
||||||
|
startTime
|
||||||
|
endTime
|
||||||
|
endpointName
|
||||||
|
type
|
||||||
|
peer
|
||||||
|
component
|
||||||
|
isError
|
||||||
|
layer
|
||||||
|
tags {
|
||||||
|
key
|
||||||
|
value
|
||||||
|
}
|
||||||
|
logs {
|
||||||
|
time
|
||||||
|
data {
|
||||||
|
key
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attachedEvents {
|
||||||
|
startTime {
|
||||||
|
seconds
|
||||||
|
nanos
|
||||||
|
}
|
||||||
|
event
|
||||||
|
endTime {
|
||||||
|
seconds
|
||||||
|
nanos
|
||||||
|
}
|
||||||
|
tags {
|
||||||
|
key
|
||||||
|
value
|
||||||
|
}
|
||||||
|
summary {
|
||||||
|
key
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
@ -14,10 +14,14 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { OAPTimeInfo, OAPVersion, MenuItems } from "../fragments/app";
|
import { OAPTimeInfo, OAPVersion, MenuItems, MetricsTTL, RecordsTTL } from "../fragments/app";
|
||||||
|
|
||||||
export const queryOAPTimeInfo = `query queryOAPTimeInfo {${OAPTimeInfo.query}}`;
|
export const queryOAPTimeInfo = `query queryOAPTimeInfo {${OAPTimeInfo.query}}`;
|
||||||
|
|
||||||
export const queryOAPVersion = `query ${OAPVersion.query}`;
|
export const queryOAPVersion = `query ${OAPVersion.query}`;
|
||||||
|
|
||||||
export const queryMenuItems = `query menuItems {${MenuItems.query}}`;
|
export const queryMenuItems = `query menuItems {${MenuItems.query}}`;
|
||||||
|
|
||||||
|
export const queryMetricsTTL = `query MetricsTTL {${MetricsTTL.query}}`;
|
||||||
|
|
||||||
|
export const queryRecordsTTL = `query RecordsTTL {${RecordsTTL.query}}`;
|
||||||
|
@ -15,12 +15,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Traces, TraceSpans, TraceTagKeys, TraceTagValues } from "../fragments/trace";
|
import { Traces, TraceSpans, TraceTagKeys, TraceTagValues, TraceSpansFromColdStage } from "../fragments/trace";
|
||||||
|
|
||||||
export const queryTraces = `query queryTraces(${Traces.variable}) {${Traces.query}}`;
|
export const queryTraces = `query queryTraces(${Traces.variable}) {${Traces.query}}`;
|
||||||
|
|
||||||
export const queryTrace = `query queryTrace(${TraceSpans.variable}) {${TraceSpans.query}}`;
|
export const querySpans = `query querySpans(${TraceSpans.variable}) {${TraceSpans.query}}`;
|
||||||
|
|
||||||
export const queryTraceTagKeys = `query queryTraceTagKeys(${TraceTagKeys.variable}) {${TraceTagKeys.query}}`;
|
export const queryTraceTagKeys = `query queryTraceTagKeys(${TraceTagKeys.variable}) {${TraceTagKeys.query}}`;
|
||||||
|
|
||||||
export const queryTraceTagValues = `query queryTraceTagValues(${TraceTagValues.variable}) {${TraceTagValues.query}}`;
|
export const queryTraceTagValues = `query queryTraceTagValues(${TraceTagValues.variable}) {${TraceTagValues.query}}`;
|
||||||
|
|
||||||
|
export const queryTraceSpansFromColdStage = `query queryTraceSpansFromColdStage(${TraceSpansFromColdStage.variable}) {${TraceSpansFromColdStage.query}}`;
|
||||||
|
55
src/hooks/useDuration.ts
Normal file
55
src/hooks/useDuration.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
import { useAppStoreWithOut, InitializationDurationRow } from "@/store/modules/app";
|
||||||
|
import type { Duration, DurationTime } from "@/types/app";
|
||||||
|
import getLocalTime from "@/utils/localtime";
|
||||||
|
import dateFormatStep from "@/utils/dateFormat";
|
||||||
|
|
||||||
|
export function useDuration() {
|
||||||
|
let durationRow: Duration = InitializationDurationRow;
|
||||||
|
|
||||||
|
function getDuration() {
|
||||||
|
const appStore = useAppStoreWithOut();
|
||||||
|
return {
|
||||||
|
start: getLocalTime(appStore.utc, durationRow.start),
|
||||||
|
end: getLocalTime(appStore.utc, durationRow.end),
|
||||||
|
step: durationRow.step,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getDurationTime(): DurationTime {
|
||||||
|
const { start, step, end } = getDuration();
|
||||||
|
return {
|
||||||
|
start: dateFormatStep(start, step, true),
|
||||||
|
end: dateFormatStep(end, step, true),
|
||||||
|
step: step,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function setDurationRow(data: Duration) {
|
||||||
|
durationRow = data;
|
||||||
|
}
|
||||||
|
function getMaxRange(day: number) {
|
||||||
|
if (day === -1) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const gap = (day + 1) * 24 * 60 * 60 * 1000;
|
||||||
|
const dates: Date[] = [new Date(new Date().getTime() - gap), new Date()];
|
||||||
|
|
||||||
|
return dates;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { setDurationRow, getDurationTime, getMaxRange };
|
||||||
|
}
|
@ -40,14 +40,25 @@ limitations under the License. -->
|
|||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
<div class="title" v-else>{{ pageTitle }}</div>
|
<div class="title" v-else>{{ pageTitle }}</div>
|
||||||
<div class="app-config">
|
<div class="app-config">
|
||||||
<span class="red" v-show="timeRange">{{ t("timeTips") }}</span>
|
<span class="red" v-show="showTimeRangeTips">{{ t("timeTips") }}</span>
|
||||||
<TimePicker
|
<TimePicker
|
||||||
:value="[appStore.durationRow.start, appStore.durationRow.end]"
|
:value="[appStore.durationRow.start, appStore.durationRow.end]"
|
||||||
|
:maxRange="appStore.maxRange"
|
||||||
position="bottom"
|
position="bottom"
|
||||||
format="YYYY-MM-DD HH:mm"
|
format="YYYY-MM-DD HH:mm"
|
||||||
@input="changeTimeRange"
|
@input="changeTimeRange"
|
||||||
/>
|
/>
|
||||||
<span> UTC{{ appStore.utcHour >= 0 ? "+" : "" }}{{ `${appStore.utcHour}:${appStore.utcMin}` }} </span>
|
<span> UTC{{ appStore.utcHour >= 0 ? "+" : "" }}{{ `${appStore.utcHour}:${appStore.utcMin}` }} </span>
|
||||||
|
<span class="ml-5">
|
||||||
|
<el-switch
|
||||||
|
v-model="coldStage"
|
||||||
|
inline-prompt
|
||||||
|
active-text="Active Data"
|
||||||
|
inactive-text="Cold Data"
|
||||||
|
@change="changeDataMode"
|
||||||
|
width="90px"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
<span class="ml-5" ref="themeSwitchRef">
|
<span class="ml-5" ref="themeSwitchRef">
|
||||||
<el-switch
|
<el-switch
|
||||||
v-model="theme"
|
v-model="theme"
|
||||||
@ -75,7 +86,7 @@ limitations under the License. -->
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Themes } from "@/constants/data";
|
import { Themes } from "@/constants/data";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut, InitializationDurationRow } from "@/store/modules/app";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import type { DashboardItem } from "@/types/dashboard";
|
import type { DashboardItem } from "@/types/dashboard";
|
||||||
import timeFormat from "@/utils/timeFormat";
|
import timeFormat from "@/utils/timeFormat";
|
||||||
@ -92,10 +103,11 @@ limitations under the License. -->
|
|||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const pathNames = ref<{ path?: string; name: string; selected: boolean }[][]>([]);
|
const pathNames = ref<{ path?: string; name: string; selected: boolean }[][]>([]);
|
||||||
const timeRange = ref<number>(0);
|
const showTimeRangeTips = ref<boolean>(false);
|
||||||
const pageTitle = ref<string>("");
|
const pageTitle = ref<string>("");
|
||||||
const theme = ref<boolean>(true);
|
const theme = ref<boolean>(true);
|
||||||
const themeSwitchRef = ref<HTMLElement>();
|
const themeSwitchRef = ref<HTMLElement>();
|
||||||
|
const coldStage = ref<boolean>(false);
|
||||||
|
|
||||||
const savedTheme = window.localStorage.getItem("theme-is-dark");
|
const savedTheme = window.localStorage.getItem("theme-is-dark");
|
||||||
if (savedTheme === "false") {
|
if (savedTheme === "false") {
|
||||||
@ -110,6 +122,7 @@ limitations under the License. -->
|
|||||||
resetDuration();
|
resetDuration();
|
||||||
getVersion();
|
getVersion();
|
||||||
getNavPaths();
|
getNavPaths();
|
||||||
|
setTTL();
|
||||||
|
|
||||||
function changeTheme() {
|
function changeTheme() {
|
||||||
const root = document.documentElement;
|
const root = document.documentElement;
|
||||||
@ -126,6 +139,24 @@ limitations under the License. -->
|
|||||||
window.localStorage.setItem("theme-is-dark", String(theme.value));
|
window.localStorage.setItem("theme-is-dark", String(theme.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeDataMode() {
|
||||||
|
appStore.setColdStageMode(coldStage.value);
|
||||||
|
if (coldStage.value) {
|
||||||
|
handleMetricsTTL({
|
||||||
|
minute: appStore.metricsTTL.coldMinute,
|
||||||
|
hour: appStore.metricsTTL.coldHour,
|
||||||
|
day: appStore.metricsTTL.coldDay,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
handleMetricsTTL({
|
||||||
|
minute: appStore.metricsTTL.minute,
|
||||||
|
hour: appStore.metricsTTL.hour,
|
||||||
|
day: appStore.metricsTTL.day,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
appStore.setDuration(InitializationDurationRow);
|
||||||
|
}
|
||||||
|
|
||||||
function handleChangeTheme() {
|
function handleChangeTheme() {
|
||||||
const x = themeSwitchRef.value?.offsetLeft ?? 0;
|
const x = themeSwitchRef.value?.offsetLeft ?? 0;
|
||||||
const y = themeSwitchRef.value?.offsetTop ?? 0;
|
const y = themeSwitchRef.value?.offsetTop ?? 0;
|
||||||
@ -184,13 +215,48 @@ limitations under the License. -->
|
|||||||
}
|
}
|
||||||
|
|
||||||
function changeTimeRange(val: Date[]) {
|
function changeTimeRange(val: Date[]) {
|
||||||
timeRange.value = val[1].getTime() - val[0].getTime() > 60 * 24 * 60 * 60 * 1000 ? 1 : 0;
|
showTimeRangeTips.value = val[1].getTime() - val[0].getTime() > 60 * 24 * 60 * 60 * 1000;
|
||||||
if (timeRange.value) {
|
if (showTimeRangeTips.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
appStore.setDuration(timeFormat(val));
|
appStore.setDuration(timeFormat(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setTTL() {
|
||||||
|
getMetricsTTL();
|
||||||
|
getRecordsTTL();
|
||||||
|
changeDataMode();
|
||||||
|
}
|
||||||
|
async function getRecordsTTL() {
|
||||||
|
const resp = await appStore.queryRecordsTTL();
|
||||||
|
if (resp.errors) {
|
||||||
|
ElMessage.error(resp.errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getMetricsTTL() {
|
||||||
|
const resp = await appStore.queryMetricsTTL();
|
||||||
|
if (resp.errors) {
|
||||||
|
ElMessage.error(resp.errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMetricsTTL({ minute, hour, day }: { minute: number; hour: number; day: number }) {
|
||||||
|
if (minute === -1 || hour === -1 || day === -1) {
|
||||||
|
return appStore.setMaxRange([]);
|
||||||
|
}
|
||||||
|
if (!day) {
|
||||||
|
return appStore.setMaxRange([]);
|
||||||
|
}
|
||||||
|
const gap = Math.max(day, hour, minute);
|
||||||
|
const dates: Date[] = [new Date(new Date().getTime() - dayToMS(gap + 1)), new Date()];
|
||||||
|
appStore.setMaxRange(dates);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dayToMS(day: number) {
|
||||||
|
return day * 24 * 60 * 60 * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
function getNavPaths() {
|
function getNavPaths() {
|
||||||
pathNames.value = [];
|
pathNames.value = [];
|
||||||
pageTitle.value = "";
|
pageTitle.value = "";
|
||||||
|
@ -21,11 +21,11 @@ import type { Duration, DurationTime } from "@/types/app";
|
|||||||
import getLocalTime from "@/utils/localtime";
|
import getLocalTime from "@/utils/localtime";
|
||||||
import dateFormatStep, { dateFormatTime } from "@/utils/dateFormat";
|
import dateFormatStep, { dateFormatTime } from "@/utils/dateFormat";
|
||||||
import { TimeType } from "@/constants/data";
|
import { TimeType } from "@/constants/data";
|
||||||
import type { MenuOptions, SubItem } from "@/types/app";
|
import type { MenuOptions, SubItem, MetricsTTL, RecordsTTL } from "@/types/app";
|
||||||
import { Themes } from "@/constants/data";
|
import { Themes } from "@/constants/data";
|
||||||
/*global Nullable*/
|
/*global Nullable*/
|
||||||
interface AppState {
|
interface AppState {
|
||||||
durationRow: Recordable;
|
durationRow: Duration;
|
||||||
utc: string;
|
utc: string;
|
||||||
utcHour: number;
|
utcHour: number;
|
||||||
utcMin: number;
|
utcMin: number;
|
||||||
@ -37,16 +37,22 @@ interface AppState {
|
|||||||
reloadTimer: Nullable<IntervalHandle>;
|
reloadTimer: Nullable<IntervalHandle>;
|
||||||
allMenus: MenuOptions[];
|
allMenus: MenuOptions[];
|
||||||
theme: string;
|
theme: string;
|
||||||
|
coldStageMode: boolean;
|
||||||
|
maxRange: Date[];
|
||||||
|
metricsTTL: Recordable<MetricsTTL>;
|
||||||
|
recordsTTL: Recordable<RecordsTTL>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const InitializationDurationRow = {
|
||||||
|
start: new Date(new Date().getTime() - 1800000),
|
||||||
|
end: new Date(),
|
||||||
|
step: TimeType.MINUTE_TIME,
|
||||||
|
};
|
||||||
|
|
||||||
export const appStore = defineStore({
|
export const appStore = defineStore({
|
||||||
id: "app",
|
id: "app",
|
||||||
state: (): AppState => ({
|
state: (): AppState => ({
|
||||||
durationRow: {
|
durationRow: InitializationDurationRow,
|
||||||
start: new Date(new Date().getTime() - 1800000),
|
|
||||||
end: new Date(),
|
|
||||||
step: TimeType.MINUTE_TIME,
|
|
||||||
},
|
|
||||||
utc: "",
|
utc: "",
|
||||||
utcHour: 0,
|
utcHour: 0,
|
||||||
utcMin: 0,
|
utcMin: 0,
|
||||||
@ -58,6 +64,10 @@ export const appStore = defineStore({
|
|||||||
reloadTimer: null,
|
reloadTimer: null,
|
||||||
allMenus: [],
|
allMenus: [],
|
||||||
theme: Themes.Dark,
|
theme: Themes.Dark,
|
||||||
|
coldStageMode: false,
|
||||||
|
maxRange: [],
|
||||||
|
metricsTTL: {},
|
||||||
|
recordsTTL: {},
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
duration(): Duration {
|
duration(): Duration {
|
||||||
@ -122,6 +132,9 @@ export const appStore = defineStore({
|
|||||||
updateDurationRow(data: Duration) {
|
updateDurationRow(data: Duration) {
|
||||||
this.durationRow = data;
|
this.durationRow = data;
|
||||||
},
|
},
|
||||||
|
setMaxRange(times: Date[]) {
|
||||||
|
this.maxRange = times;
|
||||||
|
},
|
||||||
setTheme(data: string) {
|
setTheme(data: string) {
|
||||||
this.theme = data;
|
this.theme = data;
|
||||||
},
|
},
|
||||||
@ -143,6 +156,9 @@ export const appStore = defineStore({
|
|||||||
setAutoRefresh(auto: boolean) {
|
setAutoRefresh(auto: boolean) {
|
||||||
this.autoRefresh = auto;
|
this.autoRefresh = auto;
|
||||||
},
|
},
|
||||||
|
setColdStageMode(mode: boolean) {
|
||||||
|
this.coldStageMode = mode;
|
||||||
|
},
|
||||||
runEventStack() {
|
runEventStack() {
|
||||||
if (this.timer) {
|
if (this.timer) {
|
||||||
clearTimeout(this.timer);
|
clearTimeout(this.timer);
|
||||||
@ -206,6 +222,22 @@ export const appStore = defineStore({
|
|||||||
|
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
|
async queryMetricsTTL() {
|
||||||
|
const res = await graphql.query("queryMetricsTTL").params({});
|
||||||
|
if (res.errors) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
this.metricsTTL = res.data.getMetricsTTL;
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
async queryRecordsTTL() {
|
||||||
|
const res = await graphql.query("queryRecordsTTL").params({});
|
||||||
|
if (res.errors) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
this.recordsTTL = res.data.getRecordsTTL;
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
setReloadTimer(timer: IntervalHandle) {
|
setReloadTimer(timer: IntervalHandle) {
|
||||||
this.reloadTimer = timer;
|
this.reloadTimer = timer;
|
||||||
},
|
},
|
||||||
|
@ -21,6 +21,7 @@ import graphql from "@/graphql";
|
|||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
import { useSelectorStore } from "@/store/modules/selectors";
|
import { useSelectorStore } from "@/store/modules/selectors";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
import { useDuration } from "@/hooks/useDuration";
|
||||||
import { EndpointsTopNDefault } from "../data";
|
import { EndpointsTopNDefault } from "../data";
|
||||||
|
|
||||||
interface LogState {
|
interface LogState {
|
||||||
@ -33,6 +34,7 @@ interface LogState {
|
|||||||
logs: Recordable[];
|
logs: Recordable[];
|
||||||
loadLogs: boolean;
|
loadLogs: boolean;
|
||||||
}
|
}
|
||||||
|
const { getDurationTime } = useDuration();
|
||||||
|
|
||||||
export const logStore = defineStore({
|
export const logStore = defineStore({
|
||||||
id: "log",
|
id: "log",
|
||||||
@ -41,7 +43,7 @@ export const logStore = defineStore({
|
|||||||
instances: [{ value: "0", label: "All" }],
|
instances: [{ value: "0", label: "All" }],
|
||||||
endpoints: [{ value: "0", label: "All" }],
|
endpoints: [{ value: "0", label: "All" }],
|
||||||
conditions: {
|
conditions: {
|
||||||
queryDuration: useAppStoreWithOut().durationTime,
|
queryDuration: getDurationTime(),
|
||||||
paging: { pageNum: 1, pageSize: 15 },
|
paging: { pageNum: 1, pageSize: 15 },
|
||||||
},
|
},
|
||||||
supportQueryLogsByKeywords: true,
|
supportQueryLogsByKeywords: true,
|
||||||
@ -56,7 +58,7 @@ export const logStore = defineStore({
|
|||||||
resetState() {
|
resetState() {
|
||||||
this.logs = [];
|
this.logs = [];
|
||||||
this.conditions = {
|
this.conditions = {
|
||||||
queryDuration: useAppStoreWithOut().durationTime,
|
queryDuration: getDurationTime(),
|
||||||
paging: { pageNum: 1, pageSize: 15 },
|
paging: { pageNum: 1, pageSize: 15 },
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -23,6 +23,7 @@ import { useAppStoreWithOut } from "@/store/modules/app";
|
|||||||
import { useSelectorStore } from "@/store/modules/selectors";
|
import { useSelectorStore } from "@/store/modules/selectors";
|
||||||
import { QueryOrders } from "@/views/dashboard/data";
|
import { QueryOrders } from "@/views/dashboard/data";
|
||||||
import { EndpointsTopNDefault } from "../data";
|
import { EndpointsTopNDefault } from "../data";
|
||||||
|
import { useDuration } from "@/hooks/useDuration";
|
||||||
interface TraceState {
|
interface TraceState {
|
||||||
services: Service[];
|
services: Service[];
|
||||||
instances: Instance[];
|
instances: Instance[];
|
||||||
@ -35,6 +36,7 @@ interface TraceState {
|
|||||||
selectorStore: Recordable;
|
selectorStore: Recordable;
|
||||||
selectedSpan: Recordable<Span>;
|
selectedSpan: Recordable<Span>;
|
||||||
}
|
}
|
||||||
|
const { getDurationTime } = useDuration();
|
||||||
|
|
||||||
export const traceStore = defineStore({
|
export const traceStore = defineStore({
|
||||||
id: "trace",
|
id: "trace",
|
||||||
@ -47,7 +49,7 @@ export const traceStore = defineStore({
|
|||||||
currentTrace: {},
|
currentTrace: {},
|
||||||
selectedSpan: {},
|
selectedSpan: {},
|
||||||
conditions: {
|
conditions: {
|
||||||
queryDuration: useAppStoreWithOut().durationTime,
|
queryDuration: getDurationTime(),
|
||||||
traceState: "ALL",
|
traceState: "ALL",
|
||||||
queryOrder: QueryOrders[0].value,
|
queryOrder: QueryOrders[0].value,
|
||||||
paging: { pageNum: 1, pageSize: 20 },
|
paging: { pageNum: 1, pageSize: 20 },
|
||||||
@ -73,7 +75,7 @@ export const traceStore = defineStore({
|
|||||||
this.traceList = [];
|
this.traceList = [];
|
||||||
this.currentTrace = {};
|
this.currentTrace = {};
|
||||||
this.conditions = {
|
this.conditions = {
|
||||||
queryDuration: useAppStoreWithOut().durationTime,
|
queryDuration: getDurationTime(),
|
||||||
paging: { pageNum: 1, pageSize: 20 },
|
paging: { pageNum: 1, pageSize: 20 },
|
||||||
traceState: "ALL",
|
traceState: "ALL",
|
||||||
queryOrder: QueryOrders[0].value,
|
queryOrder: QueryOrders[0].value,
|
||||||
@ -166,7 +168,15 @@ export const traceStore = defineStore({
|
|||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
async getTraceSpans(params: { traceId: string }) {
|
async getTraceSpans(params: { traceId: string }) {
|
||||||
const response = await graphql.query("queryTrace").params(params);
|
const appStore = useAppStoreWithOut();
|
||||||
|
let response;
|
||||||
|
if (appStore.coldStageMode) {
|
||||||
|
response = await graphql
|
||||||
|
.query("queryTraceSpansFromColdStage")
|
||||||
|
.params({ ...params, duration: this.conditions.queryDuration });
|
||||||
|
} else {
|
||||||
|
response = await graphql.query("querySpans").params(params);
|
||||||
|
}
|
||||||
if (response.errors) {
|
if (response.errors) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
16
src/types/app.d.ts
vendored
16
src/types/app.d.ts
vendored
@ -68,3 +68,19 @@ export interface SubItem {
|
|||||||
descKey: string;
|
descKey: string;
|
||||||
i18nKey: string;
|
i18nKey: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MetricsTTL {
|
||||||
|
minute: number;
|
||||||
|
hour: number;
|
||||||
|
day: number;
|
||||||
|
coldMinute: number;
|
||||||
|
coldHour: number;
|
||||||
|
coldDay: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RecordsTTL {
|
||||||
|
value: number;
|
||||||
|
superDataset: number;
|
||||||
|
coldValue: number;
|
||||||
|
coldSuperDataset: number;
|
||||||
|
}
|
||||||
|
5
src/types/dashboard.d.ts
vendored
5
src/types/dashboard.d.ts
vendored
@ -60,10 +60,7 @@ export type Filters = {
|
|||||||
dataIndex: number;
|
dataIndex: number;
|
||||||
sourceId: string;
|
sourceId: string;
|
||||||
isRange?: boolean;
|
isRange?: boolean;
|
||||||
duration?: {
|
duration?: DurationTime;
|
||||||
startTime: string;
|
|
||||||
endTime: string;
|
|
||||||
};
|
|
||||||
traceId?: string;
|
traceId?: string;
|
||||||
spanId?: string;
|
spanId?: string;
|
||||||
segmentId?: string;
|
segmentId?: string;
|
||||||
|
@ -30,6 +30,16 @@ limitations under the License. -->
|
|||||||
<span class="grey">{{ t("searchKeyword") }}: </span>
|
<span class="grey">{{ t("searchKeyword") }}: </span>
|
||||||
<el-input size="small" v-model="keyword" class="alarm-tool-input" @change="refreshAlarms({ pageNum: 1 })" />
|
<el-input size="small" v-model="keyword" class="alarm-tool-input" @change="refreshAlarms({ pageNum: 1 })" />
|
||||||
</div>
|
</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">
|
<div class="pagination">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-model="pageNum"
|
v-model="pageNum"
|
||||||
@ -51,31 +61,40 @@ limitations under the License. -->
|
|||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed, watch } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
import ConditionTags from "@/views/components/ConditionTags.vue";
|
import ConditionTags from "@/views/components/ConditionTags.vue";
|
||||||
import { AlarmOptions } from "./data";
|
import { AlarmOptions } from "./data";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut, InitializationDurationRow } from "@/store/modules/app";
|
||||||
import { useAlarmStore } from "@/store/modules/alarm";
|
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";
|
import { Themes } from "@/constants/data";
|
||||||
|
/*global Recordable */
|
||||||
const appStore = useAppStoreWithOut();
|
const appStore = useAppStoreWithOut();
|
||||||
const alarmStore = useAlarmStore();
|
const alarmStore = useAlarmStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const { setDurationRow, getDurationTime, getMaxRange } = useDuration();
|
||||||
const pageSize = 20;
|
const pageSize = 20;
|
||||||
const entity = ref<string>("");
|
const entity = ref<string>("");
|
||||||
const keyword = ref<string>("");
|
const keyword = ref<string>("");
|
||||||
const pageNum = ref<number>(1);
|
const pageNum = ref<number>(1);
|
||||||
|
const duration = ref<DurationTime>(getDurationTime());
|
||||||
|
const durationRow = ref<Duration>(InitializationDurationRow);
|
||||||
const total = computed(() =>
|
const total = computed(() =>
|
||||||
alarmStore.alarms.length === pageSize ? pageSize * pageNum.value + 1 : pageSize * pageNum.value,
|
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 });
|
refreshAlarms({ pageNum: 1 });
|
||||||
|
|
||||||
async function refreshAlarms(param: { pageNum: number; tagsMap?: any }) {
|
async function refreshAlarms(param: { pageNum: number; tagsMap?: Recordable }) {
|
||||||
const params: any = {
|
const params: Recordable = {
|
||||||
duration: appStore.durationTime,
|
duration: duration.value,
|
||||||
paging: {
|
paging: {
|
||||||
pageNum: param.pageNum,
|
pageNum: param.pageNum,
|
||||||
pageSize,
|
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;
|
entity.value = param[0].value;
|
||||||
refreshAlarms({ pageNum: 1 });
|
refreshAlarms({ pageNum: 1 });
|
||||||
}
|
}
|
||||||
@ -100,6 +126,16 @@ limitations under the License. -->
|
|||||||
pageNum.value = p;
|
pageNum.value = p;
|
||||||
refreshAlarms({ pageNum: p });
|
refreshAlarms({ pageNum: p });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => appStore.coldStageMode,
|
||||||
|
() => {
|
||||||
|
durationRow.value = InitializationDurationRow;
|
||||||
|
setDurationRow(durationRow.value);
|
||||||
|
duration.value = getDurationTime();
|
||||||
|
refreshAlarms({ pageNum: 1 });
|
||||||
|
},
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.alarm-tool {
|
.alarm-tool {
|
||||||
|
@ -56,6 +56,16 @@ limitations under the License. -->
|
|||||||
@change="changeField('category', $event)"
|
@change="changeField('category', $event)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</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">
|
<el-button class="search-btn" size="small" type="primary" @click="searchLogs">
|
||||||
{{ t("search") }}
|
{{ t("search") }}
|
||||||
</el-button>
|
</el-button>
|
||||||
@ -119,20 +129,21 @@ limitations under the License. -->
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<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 type { PropType } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import type { Option } from "@/types/app";
|
import { ElMessage } from "element-plus";
|
||||||
import { useLogStore } from "@/store/modules/log";
|
import { useLogStore } from "@/store/modules/log";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
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 { useSelectorStore } from "@/store/modules/selectors";
|
||||||
|
import { useDuration } from "@/hooks/useDuration";
|
||||||
import ConditionTags from "@/views/components/ConditionTags.vue";
|
import ConditionTags from "@/views/components/ConditionTags.vue";
|
||||||
import { ElMessage } from "element-plus";
|
import timeFormat from "@/utils/timeFormat";
|
||||||
import { EntityType } from "../../data";
|
import { EntityType } from "../../data";
|
||||||
import { ErrorCategory } from "./data";
|
import { ErrorCategory } from "./data";
|
||||||
import type { LayoutConfig } from "@/types/dashboard";
|
import type { LayoutConfig } from "@/types/dashboard";
|
||||||
import type { DurationTime } from "@/types/app";
|
import type { Option, DurationTime, Duration } from "@/types/app";
|
||||||
|
|
||||||
/*global defineProps, Recordable */
|
/*global defineProps, Recordable */
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -147,8 +158,9 @@ limitations under the License. -->
|
|||||||
const selectorStore = useSelectorStore();
|
const selectorStore = useSelectorStore();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
const logStore = useLogStore();
|
const logStore = useLogStore();
|
||||||
|
const { setDurationRow, getDurationTime, getMaxRange } = useDuration();
|
||||||
const traceId = ref<string>((props.data.filters && props.data.filters.traceId) || "");
|
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 keywordsOfContent = ref<string[]>([]);
|
||||||
const excludingKeywordsOfContent = ref<string[]>([]);
|
const excludingKeywordsOfContent = ref<string[]>([]);
|
||||||
const tagsList = ref<string[]>([]);
|
const tagsList = ref<string[]>([]);
|
||||||
@ -156,12 +168,16 @@ limitations under the License. -->
|
|||||||
const contentStr = ref<string>("");
|
const contentStr = ref<string>("");
|
||||||
const excludingContentStr = ref<string>("");
|
const excludingContentStr = ref<string>("");
|
||||||
const isBrowser = ref<boolean>(dashboardStore.layerId === "BROWSER");
|
const isBrowser = ref<boolean>(dashboardStore.layerId === "BROWSER");
|
||||||
|
const durationRow = ref<Duration>(InitializationDurationRow);
|
||||||
const state = reactive<Recordable>({
|
const state = reactive<Recordable>({
|
||||||
instance: { value: "0", label: "All" },
|
instance: { value: "0", label: "All" },
|
||||||
endpoint: { value: "0", label: "All" },
|
endpoint: { value: "0", label: "All" },
|
||||||
service: { value: "", label: "" },
|
service: { value: "", label: "" },
|
||||||
category: { value: "ALL", label: "All" },
|
category: { value: "ALL", label: "All" },
|
||||||
});
|
});
|
||||||
|
const maxRange = computed(() =>
|
||||||
|
getMaxRange(appStore.coldStageMode ? appStore.recordsTTL.coldSuperDataset : appStore.recordsTTL.superDataset),
|
||||||
|
);
|
||||||
if (props.needQuery) {
|
if (props.needQuery) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@ -275,6 +291,11 @@ limitations under the License. -->
|
|||||||
ElMessage.error(res.errors);
|
ElMessage.error(res.errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function changeDuration(val: Date[]) {
|
||||||
|
durationRow.value = timeFormat(val);
|
||||||
|
setDurationRow(durationRow.value);
|
||||||
|
duration.value = getDurationTime();
|
||||||
|
}
|
||||||
function changeField(type: string, opt: any) {
|
function changeField(type: string, opt: any) {
|
||||||
state[type] = opt[0];
|
state[type] = opt[0];
|
||||||
if (type === "service") {
|
if (type === "service") {
|
||||||
@ -352,12 +373,12 @@ limitations under the License. -->
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
watch(
|
watch(
|
||||||
() => appStore.durationTime,
|
() => appStore.coldStageMode,
|
||||||
() => {
|
() => {
|
||||||
duration.value = appStore.durationTime;
|
durationRow.value = InitializationDurationRow;
|
||||||
if (dashboardStore.entity === EntityType[1].value) {
|
setDurationRow(durationRow.value);
|
||||||
init();
|
duration.value = getDurationTime();
|
||||||
}
|
init();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
watch(
|
watch(
|
||||||
@ -368,7 +389,7 @@ limitations under the License. -->
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
traceId.value = props.data.filters.traceId || "";
|
traceId.value = props.data.filters.traceId || "";
|
||||||
duration.value = props.data.filters.duration || appStore.durationTime;
|
duration.value = props.data.filters.duration || getDurationTime();
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -71,24 +71,36 @@ limitations under the License. -->
|
|||||||
<span class="grey mr-5">-</span>
|
<span class="grey mr-5">-</span>
|
||||||
<el-input size="small" class="inputs" v-model="maxTraceDuration" type="number" />
|
<el-input size="small" class="inputs" v-model="maxTraceDuration" type="number" />
|
||||||
</div>
|
</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>
|
||||||
<div class="flex-h">
|
<div class="flex-h">
|
||||||
<ConditionTags :type="'TRACE'" @update="updateTags" />
|
<ConditionTags :type="'TRACE'" @update="updateTags" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<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 type { PropType } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
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 { useTraceStore } from "@/store/modules/trace";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
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 { useSelectorStore } from "@/store/modules/selectors";
|
||||||
|
import timeFormat from "@/utils/timeFormat";
|
||||||
import ConditionTags from "@/views/components/ConditionTags.vue";
|
import ConditionTags from "@/views/components/ConditionTags.vue";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { EntityType, QueryOrders, Status } from "../../data";
|
import { EntityType, QueryOrders, Status } from "../../data";
|
||||||
import type { LayoutConfig } from "@/types/dashboard";
|
import type { LayoutConfig } from "@/types/dashboard";
|
||||||
|
import { useDuration } from "@/hooks/useDuration";
|
||||||
|
|
||||||
/*global defineProps, defineEmits, Recordable */
|
/*global defineProps, defineEmits, Recordable */
|
||||||
const emits = defineEmits(["get", "search"]);
|
const emits = defineEmits(["get", "search"]);
|
||||||
@ -99,14 +111,15 @@ limitations under the License. -->
|
|||||||
default: () => ({ graph: {} }),
|
default: () => ({ graph: {} }),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const filters = reactive<Recordable>(props.data.filters || {});
|
|
||||||
const traceId = ref<string>(filters.traceId || "");
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const appStore = useAppStoreWithOut();
|
const appStore = useAppStoreWithOut();
|
||||||
const selectorStore = useSelectorStore();
|
const selectorStore = useSelectorStore();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
const traceStore = useTraceStore();
|
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 minTraceDuration = ref<number>();
|
||||||
const maxTraceDuration = ref<number>();
|
const maxTraceDuration = ref<number>();
|
||||||
const tagsList = ref<string[]>([]);
|
const tagsList = ref<string[]>([]);
|
||||||
@ -117,6 +130,10 @@ limitations under the License. -->
|
|||||||
endpoint: { value: "0", label: "All" },
|
endpoint: { value: "0", label: "All" },
|
||||||
service: { value: "", label: "" },
|
service: { value: "", label: "" },
|
||||||
});
|
});
|
||||||
|
const durationRow = ref<Duration>(InitializationDurationRow);
|
||||||
|
const maxRange = computed(() =>
|
||||||
|
getMaxRange(appStore.coldStageMode ? appStore.recordsTTL.coldSuperDataset : appStore.recordsTTL.superDataset),
|
||||||
|
);
|
||||||
if (filters.queryOrder) {
|
if (filters.queryOrder) {
|
||||||
traceStore.setTraceCondition({
|
traceStore.setTraceCondition({
|
||||||
queryOrder: filters.queryOrder,
|
queryOrder: filters.queryOrder,
|
||||||
@ -255,6 +272,11 @@ limitations under the License. -->
|
|||||||
ElMessage.error(resp.errors);
|
ElMessage.error(resp.errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function changeDuration(val: Date[]) {
|
||||||
|
durationRow.value = timeFormat(val);
|
||||||
|
setDurationRow(durationRow.value);
|
||||||
|
duration.value = getDurationTime();
|
||||||
|
}
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
traceStore.resetState();
|
traceStore.resetState();
|
||||||
const config = props.data;
|
const config = props.data;
|
||||||
@ -280,12 +302,12 @@ limitations under the License. -->
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
watch(
|
watch(
|
||||||
() => appStore.durationTime,
|
() => appStore.coldStageMode,
|
||||||
() => {
|
() => {
|
||||||
duration.value = appStore.durationTime;
|
durationRow.value = InitializationDurationRow;
|
||||||
if (dashboardStore.entity === EntityType[1].value) {
|
setDurationRow(durationRow.value);
|
||||||
init();
|
duration.value = getDurationTime();
|
||||||
}
|
init();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
// Event widget associate with trace widget
|
// Event widget associate with trace widget
|
||||||
@ -299,7 +321,7 @@ limitations under the License. -->
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
traceId.value = props.data.filters.traceId || "";
|
traceId.value = props.data.filters.traceId || "";
|
||||||
duration.value = props.data.filters.duration || appStore.durationTime;
|
duration.value = props.data.filters.duration || getDurationTime();
|
||||||
init();
|
init();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -31,6 +31,12 @@ limitations under the License. -->
|
|||||||
@change="changeLatency"
|
@change="changeLatency"
|
||||||
class="ml-10"
|
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">
|
<el-popover trigger="hover" width="250" placement="bottom">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<div class="cp conditions-popup">
|
<div class="cp conditions-popup">
|
||||||
@ -82,6 +88,7 @@ limitations under the License. -->
|
|||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
import { useSelectorStore } from "@/store/modules/selectors";
|
import { useSelectorStore } from "@/store/modules/selectors";
|
||||||
|
import timeFormat from "@/utils/timeFormat";
|
||||||
import ConditionTags from "@/views/components/ConditionTags.vue";
|
import ConditionTags from "@/views/components/ConditionTags.vue";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { EntityType, QueryOrders, Status } from "../../data";
|
import { EntityType, QueryOrders, Status } from "../../data";
|
||||||
@ -107,6 +114,7 @@ limitations under the License. -->
|
|||||||
const selectorStore = useSelectorStore();
|
const selectorStore = useSelectorStore();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
const traceStore = useTraceStore();
|
const traceStore = useTraceStore();
|
||||||
|
const timeRange = ref<number>(NaN);
|
||||||
const tagsList = ref<string[]>([]);
|
const tagsList = ref<string[]>([]);
|
||||||
const tagsMap = ref<Option[]>([]);
|
const tagsMap = ref<Option[]>([]);
|
||||||
const traceId = ref<string>(filters.refId || "");
|
const traceId = ref<string>(filters.refId || "");
|
||||||
@ -169,6 +177,15 @@ limitations under the License. -->
|
|||||||
}
|
}
|
||||||
await queryTraces();
|
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() {
|
function changeCondition() {
|
||||||
if (conditions.value === "latency") {
|
if (conditions.value === "latency") {
|
||||||
currentLatency.value = filters.latency ? filters.latency[0].data : [];
|
currentLatency.value = filters.latency ? filters.latency[0].data : [];
|
||||||
|
Loading…
Reference in New Issue
Block a user