You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2025/05/30 04:53:27 UTC
(skywalking-booster-ui) branch main updated: feat: implement the Status API on Settings page (#470)
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-booster-ui.git
The following commit(s) were added to refs/heads/main by this push:
new 7dcc67f4 feat: implement the Status API on Settings page (#470)
7dcc67f4 is described below
commit 7dcc67f455e3b85e373ee7cd28d774b41e8cfb98
Author: Fine0830 <fa...@gmail.com>
AuthorDate: Fri May 30 12:53:22 2025 +0800
feat: implement the Status API on Settings page (#470)
---
src/graphql/base.ts | 10 +-
src/graphql/{fetch.ts => custom-query.ts} | 8 +-
src/graphql/fragments/app.ts | 14 +-
src/graphql/{fetch.ts => http/index.ts} | 13 +-
.../infrastructure.d.ts => graphql/http/url.ts} | 19 +--
src/graphql/index.ts | 4 +-
src/layout/components/NavBar.vue | 7 +-
src/locales/lang/en.ts | 4 +
src/locales/lang/es.ts | 4 +
src/locales/lang/zh.ts | 4 +
src/store/modules/app.ts | 10 +-
src/store/modules/dashboard.ts | 4 +-
src/store/modules/settings.ts | 65 ++++++++
src/store/modules/topology.ts | 6 +-
src/types/{alarm.d.ts => alarm.ts} | 0
src/types/{app.d.ts => app.ts} | 18 ++-
src/types/components.d.ts | 2 +
...inous-profiling.d.ts => continous-profiling.ts} | 2 +-
src/types/{dashboard.d.ts => dashboard.ts} | 0
src/types/{ebpf.d.ts => ebpf.ts} | 8 +-
src/types/{events.d.ts => events.ts} | 10 +-
src/types/{monaco-editor.ts => monaco-editor.d.ts} | 0
src/types/{profile.d.ts => profile.ts} | 0
src/types/{selector.d.ts => selector.ts} | 10 --
src/types/{monaco-editor.ts => settings.ts} | 15 +-
src/types/{topology.d.ts => topology.ts} | 0
src/types/{trace.d.ts => trace.ts} | 3 +-
src/views/Settings.vue | 168 +--------------------
src/views/alarm/Header.vue | 2 +-
src/views/dashboard/related/log/Header.vue | 10 +-
src/views/dashboard/related/trace/Filter.vue | 2 +-
src/views/settings/Index.vue | 47 ++++++
src/views/settings/components/ClusterNodes.vue | 71 +++++++++
.../settings/components/DebuggingConfigDump.vue | 70 +++++++++
.../components/General.vue} | 19 +--
src/views/settings/components/TTL.vue | 64 ++++++++
src/views/settings/data.ts | 120 +++++++++++++++
vite.config.ts | 5 +
38 files changed, 562 insertions(+), 256 deletions(-)
diff --git a/src/graphql/base.ts b/src/graphql/base.ts
index 2ad064e4..7a2d33dc 100644
--- a/src/graphql/base.ts
+++ b/src/graphql/base.ts
@@ -34,23 +34,23 @@ class HTTPError extends Error {
}
}
-const BasePath = `/graphql`;
+export const BasePath = `/graphql`;
export async function httpQuery({
- path = "",
+ url = "",
method = "GET",
json,
headers = {},
}: {
- path?: string;
method: string;
json: unknown;
- headers: Recordable;
+ headers?: Recordable;
+ url: string;
}) {
const timeoutId = setTimeout(() => {
abortRequestsAndUpdate();
}, Timeout);
- const url = `${BasePath}${path}`;
+
const response: Response = await fetch(url, {
method,
headers: {
diff --git a/src/graphql/fetch.ts b/src/graphql/custom-query.ts
similarity index 85%
copy from src/graphql/fetch.ts
copy to src/graphql/custom-query.ts
index f475c6a4..376dcf6d 100644
--- a/src/graphql/fetch.ts
+++ b/src/graphql/custom-query.ts
@@ -14,13 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { httpQuery } from "./base";
+import { httpQuery, BasePath } from "./base";
-async function fetchQuery(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
+async function customQuery(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
const response = await httpQuery({
+ url: BasePath,
method: "post",
json: { query: param.queryStr, variables: { ...param.conditions } },
- headers: {},
});
if (response.errors) {
response.errors = response.errors.map((e: { message: string }) => e.message).join(" ");
@@ -28,4 +28,4 @@ async function fetchQuery(param: { queryStr: string; conditions: { [key: string]
return response;
}
-export default fetchQuery;
+export default customQuery;
diff --git a/src/graphql/fragments/app.ts b/src/graphql/fragments/app.ts
index a91f07e6..e3f7551b 100644
--- a/src/graphql/fragments/app.ts
+++ b/src/graphql/fragments/app.ts
@@ -52,10 +52,16 @@ export const MenuItems = {
export const RecordsTTL = {
query: `getRecordsTTL {
- value
- superDataset
- coldValue
- coldSuperDataset
+ normal
+ trace
+ zipkinTrace
+ log
+ browserErrorLog
+ coldNormal
+ coldTrace
+ coldZipkinTrace
+ coldLog
+ coldBrowserErrorLog
}`,
};
export const MetricsTTL = {
diff --git a/src/graphql/fetch.ts b/src/graphql/http/index.ts
similarity index 78%
rename from src/graphql/fetch.ts
rename to src/graphql/http/index.ts
index f475c6a4..d9825404 100644
--- a/src/graphql/fetch.ts
+++ b/src/graphql/http/index.ts
@@ -14,18 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { httpQuery } from "./base";
+import { httpQuery } from "../base";
+import { HttpURL } from "./url";
-async function fetchQuery(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
+export default async function fetchQuery({ method, json, path }: { method: string; json?: unknown; path: string }) {
const response = await httpQuery({
- method: "post",
- json: { query: param.queryStr, variables: { ...param.conditions } },
- headers: {},
+ method,
+ json,
+ url: (HttpURL as { [key: string]: string })[path],
});
if (response.errors) {
response.errors = response.errors.map((e: { message: string }) => e.message).join(" ");
}
return response;
}
-
-export default fetchQuery;
diff --git a/src/types/infrastructure.d.ts b/src/graphql/http/url.ts
similarity index 73%
rename from src/types/infrastructure.d.ts
rename to src/graphql/http/url.ts
index 788f0102..695f1acd 100644
--- a/src/types/infrastructure.d.ts
+++ b/src/graphql/http/url.ts
@@ -14,18 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-export interface HexagonCreateParams {
- hexagonParam: number[];
- count: number;
- radius: number;
- origin?: number[];
- getShader?: any;
-}
-export interface HexagonGeo {
- vertices: number[];
- normals: number[];
- insCenters: number[];
- indices: number[];
- origins: number[];
-}
+export const HttpURL = {
+ ClusterNodes: `/api/status/cluster/nodes`,
+ ConfigTTL: `/api/status/config/ttl`,
+ DebuggingConfigDump: `/api/debugging/config/dump`,
+};
diff --git a/src/graphql/index.ts b/src/graphql/index.ts
index 435118d6..9c72887c 100644
--- a/src/graphql/index.ts
+++ b/src/graphql/index.ts
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { httpQuery } from "./base";
+import { httpQuery, BasePath } from "./base";
import * as app from "./query/app";
import * as selector from "./query/selector";
import * as dashboard from "./query/dashboard";
@@ -50,8 +50,8 @@ class Graphql {
}
async params(variables: unknown) {
const response = await httpQuery({
+ url: BasePath,
method: "post",
- headers: {},
json: {
query: query[this.queryData],
variables,
diff --git a/src/layout/components/NavBar.vue b/src/layout/components/NavBar.vue
index ba7626da..274f3912 100644
--- a/src/layout/components/NavBar.vue
+++ b/src/layout/components/NavBar.vue
@@ -222,9 +222,9 @@ limitations under the License. -->
appStore.setDuration(timeFormat(val));
}
- function setTTL() {
- getMetricsTTL();
- getRecordsTTL();
+ async function setTTL() {
+ await getMetricsTTL();
+ await getRecordsTTL();
changeDataMode();
}
async function getRecordsTTL() {
@@ -250,6 +250,7 @@ limitations under the License. -->
}
const gap = Math.max(day, hour, minute);
const dates: Date[] = [new Date(new Date().getTime() - dayToMS(gap + 1)), new Date()];
+
appStore.setMaxRange(dates);
}
diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts
index 75597f1e..12de6d03 100644
--- a/src/locales/lang/en.ts
+++ b/src/locales/lang/en.ts
@@ -397,5 +397,9 @@ const msg = {
instances: "Instances",
snapshot: "Snapshot",
expression: "Expression",
+ metricsTTL: "Metrics TTL",
+ recordsTTL: "Records TTL",
+ clusterNodes: "Cluster Nodes",
+ debuggingConfigDump: "Dump Effective Configurations",
};
export default msg;
diff --git a/src/locales/lang/es.ts b/src/locales/lang/es.ts
index 1e714278..3a8dc0b2 100644
--- a/src/locales/lang/es.ts
+++ b/src/locales/lang/es.ts
@@ -397,5 +397,9 @@ const msg = {
snapshot: "Snapshot",
expression: "Expression",
asSelector: "As Selector",
+ metricsTTL: "Metrics TTL",
+ recordsTTL: "Records TTL",
+ clusterNodes: "Cluster Nodes",
+ debuggingConfigDump: "Dump Effective Configurations",
};
export default msg;
diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts
index b6c1fbb8..72b548cf 100644
--- a/src/locales/lang/zh.ts
+++ b/src/locales/lang/zh.ts
@@ -395,5 +395,9 @@ const msg = {
instances: "实例",
snapshot: "快照",
expression: "表达式",
+ metricsTTL: "Metrics TTL",
+ recordsTTL: "Records TTL",
+ clusterNodes: "集群节点",
+ debuggingConfigDump: "转储有效配置",
};
export default msg;
diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts
index 5cfc40af..58a1d4bf 100644
--- a/src/store/modules/app.ts
+++ b/src/store/modules/app.ts
@@ -223,12 +223,12 @@ export const appStore = defineStore({
return res.data;
},
async queryMetricsTTL() {
- const res = await graphql.query("queryMetricsTTL").params({});
- if (res.errors) {
- return res;
+ const response = await graphql.query("queryMetricsTTL").params({});
+ if (response.errors) {
+ return response;
}
- this.metricsTTL = res.data.getMetricsTTL;
- return res.data;
+ this.metricsTTL = response.data.getMetricsTTL;
+ return response.data;
},
async queryRecordsTTL() {
const res = await graphql.query("queryRecordsTTL").params({});
diff --git a/src/store/modules/dashboard.ts b/src/store/modules/dashboard.ts
index 1eb35f71..57ee704d 100644
--- a/src/store/modules/dashboard.ts
+++ b/src/store/modules/dashboard.ts
@@ -18,7 +18,7 @@ import { defineStore } from "pinia";
import { store } from "@/store";
import type { LayoutConfig } from "@/types/dashboard";
import graphql from "@/graphql";
-import fetchQuery from "@/graphql/fetch";
+import customQuery from "@/graphql/custom-query";
import type { DashboardItem } from "@/types/dashboard";
import { useSelectorStore } from "@/store/modules/selectors";
import { NewControl, TextConfig, TimeRangeConfig, ControlsTypes } from "../data";
@@ -299,7 +299,7 @@ export const dashboardStore = defineStore({
}
},
async fetchMetricValue(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
- return await fetchQuery(param);
+ return await customQuery(param);
},
async fetchTemplates() {
const res = await graphql.query("getTemplates").params({});
diff --git a/src/store/modules/settings.ts b/src/store/modules/settings.ts
new file mode 100644
index 00000000..e9dd3708
--- /dev/null
+++ b/src/store/modules/settings.ts
@@ -0,0 +1,65 @@
+/**
+ * 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 { defineStore } from "pinia";
+import { store } from "@/store";
+import fetchQuery from "@/graphql/http";
+import type { ClusterNode, ConfigTTL } from "@/types/settings";
+
+interface SettingsState {
+ clusterNodes: ClusterNode[];
+ debuggingConfig: Indexable<string>;
+ configTTL: Recordable<ConfigTTL>;
+}
+
+export const settingsStore = defineStore({
+ id: "settings",
+ state: (): SettingsState => ({
+ clusterNodes: [],
+ debuggingConfig: {},
+ configTTL: {},
+ }),
+ actions: {
+ async getClusterNodes() {
+ const response = await fetchQuery({
+ method: "get",
+ path: "ClusterNodes",
+ });
+ this.clusterNodes = response.nodes;
+ return response;
+ },
+ async getConfigTTL() {
+ const response = await fetchQuery({
+ method: "get",
+ path: "ConfigTTL",
+ });
+ this.configTTL = response;
+ return response;
+ },
+ async getDebuggingConfigDump() {
+ const response = await fetchQuery({
+ method: "get",
+ path: "DebuggingConfigDump",
+ });
+ this.debuggingConfig = response;
+ return response;
+ },
+ },
+});
+
+export function useSettingsStore(): Recordable {
+ return settingsStore(store);
+}
diff --git a/src/store/modules/topology.ts b/src/store/modules/topology.ts
index b16d7611..081aa4be 100644
--- a/src/store/modules/topology.ts
+++ b/src/store/modules/topology.ts
@@ -21,7 +21,7 @@ import graphql from "@/graphql";
import { useSelectorStore } from "@/store/modules/selectors";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app";
-import fetchQuery from "@/graphql/fetch";
+import customQuery from "@/graphql/custom-query";
import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor";
interface MetricVal {
@@ -431,7 +431,7 @@ export const topologyStore = defineStore({
});
const queryStr = `query queryData(${variables}) {${fragment}}`;
const conditions = { duration };
- const res = await fetchQuery({ queryStr, conditions });
+ const res = await customQuery({ queryStr, conditions });
if (res.errors) {
return res;
@@ -448,7 +448,7 @@ export const topologyStore = defineStore({
return { calls, nodes };
},
async getTopologyExpressionValue(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
- const res = await fetchQuery(param);
+ const res = await customQuery(param);
if (res.errors) {
return res;
diff --git a/src/types/alarm.d.ts b/src/types/alarm.ts
similarity index 100%
rename from src/types/alarm.d.ts
rename to src/types/alarm.ts
diff --git a/src/types/app.d.ts b/src/types/app.ts
similarity index 88%
rename from src/types/app.d.ts
rename to src/types/app.ts
index 36958b54..b7fa8150 100644
--- a/src/types/app.d.ts
+++ b/src/types/app.ts
@@ -39,14 +39,12 @@ export type EventParams = {
seriesIndex: number;
seriesName: string;
name: string;
- dataIndex: number;
data: unknown;
dataType: string;
value: number | any[];
color: string;
- event: Record<string, T>;
+ event: Recordable;
dataIndex: number;
- event: any;
};
export interface MenuOptions extends SubItem {
@@ -79,8 +77,14 @@ export interface MetricsTTL {
}
export interface RecordsTTL {
- value: number;
- superDataset: number;
- coldValue: number;
- coldSuperDataset: number;
+ normal: number;
+ trace: number;
+ zipkinTrace: number;
+ log: number;
+ browserErrorLog: number;
+ coldNormal: number;
+ coldTrace: number;
+ coldZipkinTrace: number;
+ coldLog: number;
+ coldBrowserErrorLog: number;
}
diff --git a/src/types/components.d.ts b/src/types/components.d.ts
index 64e8c17e..56f60832 100644
--- a/src/types/components.d.ts
+++ b/src/types/components.d.ts
@@ -42,6 +42,8 @@ declare module 'vue' {
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
+ ElTabPane: typeof import('element-plus/es')['ElTabPane']
+ ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
Graph: typeof import('./../components/Graph/Graph.vue')['default']
diff --git a/src/types/continous-profiling.d.ts b/src/types/continous-profiling.ts
similarity index 97%
rename from src/types/continous-profiling.d.ts
rename to src/types/continous-profiling.ts
index 98c5b121..50dce59b 100644
--- a/src/types/continous-profiling.d.ts
+++ b/src/types/continous-profiling.ts
@@ -35,7 +35,7 @@ export interface MonitorInstance {
lastTriggerTimestamp: number;
processes: MonitorProcess[];
}
-interface MonitorProcess {
+export interface MonitorProcess {
id: string;
name: string;
detectType: string;
diff --git a/src/types/dashboard.d.ts b/src/types/dashboard.ts
similarity index 100%
rename from src/types/dashboard.d.ts
rename to src/types/dashboard.ts
diff --git a/src/types/ebpf.d.ts b/src/types/ebpf.ts
similarity index 95%
rename from src/types/ebpf.d.ts
rename to src/types/ebpf.ts
index 53badf56..53f84d32 100644
--- a/src/types/ebpf.d.ts
+++ b/src/types/ebpf.ts
@@ -15,7 +15,8 @@
* limitations under the License.
*/
-import type { Process } from "./selector";
+import type { Process as selectorProcess } from "./selector";
+
export interface EBPFTaskCreationRequest {
serviceId: string;
processLabels: string[];
@@ -58,12 +59,12 @@ interface ProfilingCause {
export interface EBPFProfilingSchedule {
scheduleId: string;
taskId: string;
- process: Process;
+ process: selectorProcess;
endTime: number;
startTime: number;
}
-export type Process = Process;
+export type Process = selectorProcess;
export type StackElement = {
id: string;
originId: string;
@@ -106,7 +107,6 @@ export type ProcessNode = {
serviceName: string;
serviceInstanceId: string;
serviceInstanceName: string;
- name: string;
isReal: boolean;
x?: number;
y?: number;
diff --git a/src/types/events.d.ts b/src/types/events.ts
similarity index 90%
rename from src/types/events.d.ts
rename to src/types/events.ts
index e4684134..5c1dc7a7 100644
--- a/src/types/events.d.ts
+++ b/src/types/events.ts
@@ -14,11 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import type { Duration } from "./app";
+
+const enum EventType {
+ ALL = "",
+ NORMAL = "Normal",
+ ERROR = "Error",
+}
+
export type Event = {
uuid: string;
source: SourceInput;
name: string;
- type: string;
+ type: EventType;
message: string;
parameters: { key: string; value: string }[];
startTime: number | string;
diff --git a/src/types/monaco-editor.ts b/src/types/monaco-editor.d.ts
similarity index 100%
copy from src/types/monaco-editor.ts
copy to src/types/monaco-editor.d.ts
diff --git a/src/types/profile.d.ts b/src/types/profile.ts
similarity index 100%
rename from src/types/profile.d.ts
rename to src/types/profile.ts
diff --git a/src/types/selector.d.ts b/src/types/selector.ts
similarity index 90%
rename from src/types/selector.d.ts
rename to src/types/selector.ts
index cf8b07d5..928e1244 100644
--- a/src/types/selector.d.ts
+++ b/src/types/selector.ts
@@ -42,16 +42,6 @@ export type Endpoint = {
merge?: string;
};
-export type Service = {
- id: string;
- value: string;
- label: string;
- group: string;
- normal: boolean;
- layers: string[];
- shortName: string;
-};
-
export type Process = {
id: string;
name: string;
diff --git a/src/types/monaco-editor.ts b/src/types/settings.ts
similarity index 78%
rename from src/types/monaco-editor.ts
rename to src/types/settings.ts
index ebf98eaf..5a345107 100644
--- a/src/types/monaco-editor.ts
+++ b/src/types/settings.ts
@@ -14,5 +14,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-declare module "monaco-editor";
-export {};
+
+import type { MetricsTTL, RecordsTTL } from "@/types/app";
+
+export type ClusterNode = {
+ host: string;
+ port: number;
+ self: boolean;
+};
+
+export type ConfigTTL = {
+ metrics: MetricsTTL;
+ records: RecordsTTL;
+};
diff --git a/src/types/topology.d.ts b/src/types/topology.ts
similarity index 100%
rename from src/types/topology.d.ts
rename to src/types/topology.ts
diff --git a/src/types/trace.d.ts b/src/types/trace.ts
similarity index 98%
rename from src/types/trace.d.ts
rename to src/types/trace.ts
index 8d8d4457..a78db87e 100644
--- a/src/types/trace.d.ts
+++ b/src/types/trace.ts
@@ -47,7 +47,6 @@ export interface Span {
tags?: Array<Map<string, string>>;
logs?: log[];
parentSegmentId?: string;
- refs?: Ref[];
key?: string;
}
export type Ref = {
@@ -75,7 +74,7 @@ export interface StatisticsGroupRef {
type: string;
}
-export class TraceTreeRef {
+export interface TraceTreeRef {
segmentMap: Map<string, Span>;
segmentIdGroup: string[];
}
diff --git a/src/views/Settings.vue b/src/views/Settings.vue
index 12e139e6..e2530337 100644
--- a/src/views/Settings.vue
+++ b/src/views/Settings.vue
@@ -13,172 +13,8 @@ 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="settings">
- <div class="flex-h item">
- <span class="label">{{ t("language") }}</span>
- <Selector
- v-model="lang"
- :options="Languages"
- placeholder="Select a language"
- @change="setLang"
- size="small"
- style="font-size: 14px; width: 180px"
- />
- </div>
- <div class="flex-h item">
- <span class="label">{{ t("serverZone") }}</span>
- <div>
- <span>UTC</span>
- <span class="ml-5 mr-5">{{ utcHour >= 0 ? "+" : "" }}</span>
- <input type="number" v-model="utcHour" min="-12" max="14" class="utc-input" @change="setUTCHour" />
- <span class="ml-5 mr-5">:</span>
- <span class="utc-min">{{ utcMin > 9 || utcMin === 0 ? null : 0 }}</span>
- <input type="number" v-model="utcMin" min="0" max="59" class="utc-input" @change="setUTCMin" />
- </div>
- </div>
- <div class="flex-h item">
- <span class="label">{{ t("auto") }}</span>
- <el-switch v-model="auto" @change="handleAuto" style="height: 25px" />
- <div class="auto-time ml-5">
- <span class="auto-select">
- <input type="number" v-model="autoTime" @change="changeAutoTime" min="1" />
- </span>
- {{ t("second") }}
- <i class="ml-10">{{ t("timeReload") }}</i>
- </div>
- </div>
- </div>
+ <Content />
</template>
<script lang="ts" setup>
- import { ref } from "vue";
- import { useI18n } from "vue-i18n";
- import { useAppStoreWithOut } from "@/store/modules/app";
- import timeFormat from "@/utils/timeFormat";
- import { Languages } from "@/constants/data";
- import Selector from "@/components/Selector.vue";
- import getLocalTime from "@/utils/localtime";
-
- const { t, locale } = useI18n();
- const appStore = useAppStoreWithOut();
- const lang = ref<string>(locale.value || "en");
- const autoTime = ref<number>(6);
- const auto = ref<boolean>(appStore.autoRefresh || false);
- const utcHour = ref<number>(appStore.utcHour);
- const utcMin = ref<number>(appStore.utcMin);
-
- const handleReload = () => {
- const gap = appStore.duration.end.getTime() - appStore.duration.start.getTime();
- const dates: Date[] = [
- getLocalTime(appStore.utc, new Date(new Date().getTime() - gap)),
- getLocalTime(appStore.utc, new Date()),
- ];
- appStore.setDuration(timeFormat(dates));
- };
- const handleAuto = () => {
- if (autoTime.value < 1) {
- return;
- }
- appStore.setAutoRefresh(auto.value);
- if (auto.value) {
- handleReload();
- appStore.setReloadTimer(setInterval(handleReload, autoTime.value * 1000));
- } else {
- if (appStore.reloadTimer) {
- clearInterval(appStore.reloadTimer);
- }
- }
- };
- const changeAutoTime = () => {
- if (autoTime.value < 1) {
- return;
- }
- if (appStore.reloadTimer) {
- clearInterval(appStore.reloadTimer);
- }
- if (auto.value) {
- handleReload();
- appStore.setReloadTimer(setInterval(handleReload, autoTime.value * 1000));
- }
- };
- const setLang = (): void => {
- locale.value = lang.value;
- window.localStorage.setItem("language", lang.value);
- };
- const setUTCHour = () => {
- if (utcHour.value < -12) {
- utcHour.value = -12;
- }
- if (utcHour.value > 14) {
- utcHour.value = 14;
- }
- if (isNaN(utcHour.value)) {
- utcHour.value = 0;
- }
- appStore.setUTC(utcHour.value, utcMin.value);
- };
- const setUTCMin = () => {
- if (utcMin.value < 0) {
- utcMin.value = 0;
- }
- if (utcMin.value > 59) {
- utcMin.value = 59;
- }
- if (isNaN(utcMin.value)) {
- utcMin.value = 0;
- }
- appStore.setUTC(utcHour.value, utcMin.value);
- };
+ import Content from "./settings/Index.vue";
</script>
-<style lang="scss" scoped>
- .utc-input {
- color: inherit;
- background: 0;
- border: 0;
- outline: none;
- padding-bottom: 0;
- }
-
- .utc-min {
- display: inline-block;
- padding-top: 2px;
- }
-
- .auto-select {
- border-radius: 3px;
- background-color: $theme-background;
- padding: 1px;
-
- input {
- width: 38px;
- border-style: unset;
- outline: 0;
- }
- }
-
- .settings {
- color: var(--sw-setting-color);
- font-size: 13px;
- padding: 20px;
-
- .item {
- margin-top: 10px;
- }
-
- input {
- outline: 0;
- width: 50px;
- border-radius: 3px;
- border: 1px solid $disabled-color;
- text-align: center;
- height: 25px;
- }
-
- .label {
- width: 180px;
- display: inline-block;
- font-weight: 500;
- color: $font-color;
- line-height: 25px;
- }
- }
-</style>
diff --git a/src/views/alarm/Header.vue b/src/views/alarm/Header.vue
index 869743d9..5d01988f 100644
--- a/src/views/alarm/Header.vue
+++ b/src/views/alarm/Header.vue
@@ -87,7 +87,7 @@ limitations under the License. -->
alarmStore.alarms.length === pageSize ? pageSize * pageNum.value + 1 : pageSize * pageNum.value,
);
const maxRange = computed(() =>
- getMaxRange(appStore.coldStageMode ? appStore.recordsTTL.coldValue : appStore.recordsTTL.value),
+ getMaxRange(appStore.coldStageMode ? appStore.recordsTTL.coldNormal : appStore.recordsTTL.normal),
);
refreshAlarms({ pageNum: 1 });
diff --git a/src/views/dashboard/related/log/Header.vue b/src/views/dashboard/related/log/Header.vue
index 856b366b..04a94b22 100644
--- a/src/views/dashboard/related/log/Header.vue
+++ b/src/views/dashboard/related/log/Header.vue
@@ -176,7 +176,15 @@ limitations under the License. -->
category: { value: "ALL", label: "All" },
});
const maxRange = computed(() =>
- getMaxRange(appStore.coldStageMode ? appStore.recordsTTL.coldSuperDataset : appStore.recordsTTL.superDataset),
+ getMaxRange(
+ appStore.coldStageMode
+ ? isBrowser.value
+ ? appStore.recordsTTL.coldBrowserErrorLog
+ : appStore.recordsTTL.coldLog
+ : isBrowser.value
+ ? appStore.recordsTTL.browserErrorLog
+ : appStore.recordsTTL.log,
+ ),
);
if (props.needQuery) {
init();
diff --git a/src/views/dashboard/related/trace/Filter.vue b/src/views/dashboard/related/trace/Filter.vue
index 9652b44c..95e39aca 100644
--- a/src/views/dashboard/related/trace/Filter.vue
+++ b/src/views/dashboard/related/trace/Filter.vue
@@ -132,7 +132,7 @@ limitations under the License. -->
});
const durationRow = ref<Duration>(InitializationDurationRow);
const maxRange = computed(() =>
- getMaxRange(appStore.coldStageMode ? appStore.recordsTTL.coldSuperDataset : appStore.recordsTTL.superDataset),
+ getMaxRange(appStore.coldStageMode ? appStore.recordsTTL.coldTrace : appStore.recordsTTL.trace),
);
if (filters.queryOrder) {
traceStore.setTraceCondition({
diff --git a/src/views/settings/Index.vue b/src/views/settings/Index.vue
new file mode 100644
index 00000000..604bc72f
--- /dev/null
+++ b/src/views/settings/Index.vue
@@ -0,0 +1,47 @@
+<!-- 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. -->
+<template>
+ <el-tabs v-model="activeName" class="settings-tabs">
+ <el-tab-pane v-for="tab in SettingsTabs" :label="tab.label" :name="tab.value" :key="tab.value">
+ <component :is="TabPanes[tab.value]" />
+ </el-tab-pane>
+ </el-tabs>
+</template>
+<script lang="ts" setup>
+ import { ref } from "vue";
+ import { SettingsTabs } from "./data";
+ import ClusterNodes from "./components/ClusterNodes.vue";
+ import General from "./components/General.vue";
+ import TTL from "./components/TTL.vue";
+ import DebuggingConfigDump from "./components/DebuggingConfigDump.vue";
+ /*global Indexable*/
+ const TabPanes: Indexable = {
+ general: General,
+ ttl: TTL,
+ clusterNodes: ClusterNodes,
+ dumpEffectiveConfigurations: DebuggingConfigDump,
+ };
+ const activeName = ref(SettingsTabs[0].value);
+</script>
+<style lang="scss" scoped>
+ .settings-tabs {
+ padding: 10px 20px;
+ }
+
+ .settings-tabs > .el-tabs__content {
+ color: var(--sw-setting-color);
+ padding-top: 10px;
+ }
+</style>
diff --git a/src/views/settings/components/ClusterNodes.vue b/src/views/settings/components/ClusterNodes.vue
new file mode 100644
index 00000000..8407baeb
--- /dev/null
+++ b/src/views/settings/components/ClusterNodes.vue
@@ -0,0 +1,71 @@
+<!-- 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. -->
+<template>
+ <div class="cluster-nodes">
+ <el-table
+ :data="settingsStore.clusterNodes"
+ class="mb-5"
+ :row-style="{ backgroundColor: 'var(--layout-background)' }"
+ >
+ <el-table-column
+ v-for="item in ClusterNodeRow"
+ :prop="item.value"
+ :label="item.label"
+ :key="item.value"
+ :width="item.width"
+ />
+ </el-table>
+ <el-pagination
+ class="pagination"
+ layout="prev, pager, next"
+ :page-size="pageSize"
+ :total="settingsStore.clusterNodes.length"
+ v-model="currentPage"
+ @current-change="changePage"
+ @prev-click="changePage"
+ @next-click="changePage"
+ />
+ </div>
+</template>
+<script lang="ts" setup>
+ import { ref, onMounted } from "vue";
+ import { useSettingsStore } from "@/store/modules/settings";
+ import { ClusterNodeRow } from "../data";
+
+ const settingsStore = useSettingsStore();
+ const pageSize = 16;
+ const currentPage = ref<number>(1);
+
+ onMounted(() => {
+ settingsStore.getClusterNodes();
+ });
+
+ const changePage = (pageIndex: number) => {
+ currentPage.value = pageIndex;
+ };
+</script>
+<style lang="scss" scoped>
+ .cluster-nodes {
+ font-size: 13px;
+ width: 100%;
+ }
+
+ .label {
+ width: 200px;
+ display: inline-block;
+ font-weight: 500;
+ color: $font-color;
+ }
+</style>
diff --git a/src/views/settings/components/DebuggingConfigDump.vue b/src/views/settings/components/DebuggingConfigDump.vue
new file mode 100644
index 00000000..6a8bd983
--- /dev/null
+++ b/src/views/settings/components/DebuggingConfigDump.vue
@@ -0,0 +1,70 @@
+<!-- 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. -->
+<template>
+ <div class="debugging-config-dump">
+ <div class="config-dump-content">
+ <div
+ class="mb-10 flex-h"
+ v-for="(item, index) of Object.keys(settingsStore.debuggingConfig)"
+ :key="`${item}${index}`"
+ >
+ <div class="config-key">{{ item }}: </div>
+ <div>{{ settingsStore.debuggingConfig[item] }}</div>
+ </div>
+ <div v-if="!Object.keys(settingsStore.debuggingConfig).length" class="tips">No Data</div>
+ </div>
+ </div>
+</template>
+<script lang="ts" setup>
+ import { onMounted } from "vue";
+ import { useSettingsStore } from "@/store/modules/settings";
+
+ const settingsStore = useSettingsStore();
+
+ onMounted(() => {
+ settingsStore.getDebuggingConfigDump();
+ });
+</script>
+<style lang="scss" scoped>
+ .config-dump-content {
+ border: 1px solid var(--el-color-info-light-8);
+ overflow: auto;
+ padding: 5px;
+ border-radius: 5px 3px;
+ height: 700px;
+ }
+
+ .tips {
+ text-align: center;
+ width: 100%;
+ color: var(--el-text-color-secondary);
+ }
+
+ .config-key {
+ width: 30%;
+ }
+
+ .debugging-config-dump {
+ color: var(--sw-setting-color);
+ font-size: 13px;
+ }
+
+ .label {
+ width: 200px;
+ display: inline-block;
+ font-weight: 500;
+ color: $font-color;
+ }
+</style>
diff --git a/src/views/Settings.vue b/src/views/settings/components/General.vue
similarity index 93%
copy from src/views/Settings.vue
copy to src/views/settings/components/General.vue
index 12e139e6..40d16049 100644
--- a/src/views/Settings.vue
+++ b/src/views/settings/components/General.vue
@@ -13,9 +13,9 @@ 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="settings">
+ <div class="general-settings">
<div class="flex-h item">
- <span class="label">{{ t("language") }}</span>
+ <div class="label">{{ t("language") }}</div>
<Selector
v-model="lang"
:options="Languages"
@@ -26,7 +26,7 @@ limitations under the License. -->
/>
</div>
<div class="flex-h item">
- <span class="label">{{ t("serverZone") }}</span>
+ <div class="label">{{ t("serverZone") }}</div>
<div>
<span>UTC</span>
<span class="ml-5 mr-5">{{ utcHour >= 0 ? "+" : "" }}</span>
@@ -37,7 +37,7 @@ limitations under the License. -->
</div>
</div>
<div class="flex-h item">
- <span class="label">{{ t("auto") }}</span>
+ <div class="label">{{ t("auto") }}</div>
<el-switch v-model="auto" @change="handleAuto" style="height: 25px" />
<div class="auto-time ml-5">
<span class="auto-select">
@@ -155,13 +155,11 @@ limitations under the License. -->
}
}
- .settings {
- color: var(--sw-setting-color);
+ .general-settings {
font-size: 13px;
- padding: 20px;
.item {
- margin-top: 10px;
+ margin-top: 15px;
}
input {
@@ -174,11 +172,10 @@ limitations under the License. -->
}
.label {
- width: 180px;
+ width: 200px;
display: inline-block;
- font-weight: 500;
color: $font-color;
- line-height: 25px;
+ font-weight: 500;
}
}
</style>
diff --git a/src/views/settings/components/TTL.vue b/src/views/settings/components/TTL.vue
new file mode 100644
index 00000000..4e0ba92e
--- /dev/null
+++ b/src/views/settings/components/TTL.vue
@@ -0,0 +1,64 @@
+<!-- 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. -->
+<template>
+ <div class="ttl">
+ <div class="label">{{ t("metricsTTL") }}</div>
+ <el-table
+ :data="[settingsStore.configTTL.metrics]"
+ class="mb-5"
+ :row-style="{ backgroundColor: 'var(--layout-background)' }"
+ >
+ <el-table-column v-for="item in MetricsTTLRow" :prop="item.value" :label="item.label" :key="item.value">
+ <template #default="scope">{{ scope.row[item.value] < 0 ? "N/A" : scope.row[item.value] }}</template>
+ </el-table-column>
+ </el-table>
+ <div class="label">{{ t("recordsTTL") }}</div>
+ <el-table
+ :data="[settingsStore.configTTL.records]"
+ class="mb-5"
+ :row-style="{ backgroundColor: 'var(--layout-background)' }"
+ >
+ <el-table-column v-for="item in RecordsTTLRow" :prop="item.value" :label="item.label" :key="item.value">
+ <template #default="scope">{{ scope.row[item.value] < 0 ? "N/A" : scope.row[item.value] }}</template>
+ </el-table-column>
+ </el-table>
+ </div>
+</template>
+<script lang="ts" setup>
+ import { onMounted } from "vue";
+ import { useI18n } from "vue-i18n";
+ import { useSettingsStore } from "@/store/modules/settings";
+ import { MetricsTTLRow, RecordsTTLRow } from "../data";
+
+ const { t } = useI18n();
+ const settingsStore = useSettingsStore();
+
+ onMounted(() => {
+ settingsStore.getConfigTTL();
+ });
+</script>
+<style lang="scss" scoped>
+ .ttl {
+ color: var(--sw-setting-color);
+ font-size: 13px;
+
+ .label {
+ margin: 15px 0;
+ display: inline-block;
+ font-weight: 600;
+ color: $font-color;
+ }
+ }
+</style>
diff --git a/src/views/settings/data.ts b/src/views/settings/data.ts
new file mode 100644
index 00000000..83adaea8
--- /dev/null
+++ b/src/views/settings/data.ts
@@ -0,0 +1,120 @@
+/**
+ * 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.
+ */
+export const ClusterNodeRow = [
+ {
+ label: "Host",
+ value: "host",
+ },
+ {
+ label: "Port",
+ value: "port",
+ width: 180,
+ },
+ {
+ label: "Self",
+ value: "self",
+ width: 180,
+ },
+];
+
+export const SettingsTabs = [
+ {
+ label: "General",
+ value: "general",
+ },
+ {
+ label: "TTL",
+ value: "ttl",
+ },
+ {
+ label: "Cluster Nodes",
+ value: "clusterNodes",
+ },
+ {
+ label: "Dump Effective Configurations",
+ value: "dumpEffectiveConfigurations",
+ },
+];
+export const MetricsTTLRow = [
+ {
+ label: "Day",
+ value: "day",
+ },
+ {
+ label: "Hour",
+ value: "hour",
+ },
+ {
+ label: "Minute",
+ value: "minute",
+ },
+ {
+ label: "Cold Day",
+ value: "coldDay",
+ },
+ {
+ label: "Cold Hour",
+ value: "coldHour",
+ },
+ {
+ label: "Cold Minute",
+ value: "coldMinute",
+ },
+];
+
+export const RecordsTTLRow = [
+ {
+ label: "Normal",
+ value: "normal",
+ },
+ {
+ label: "Trace",
+ value: "trace",
+ },
+ {
+ label: "Log",
+ value: "log",
+ },
+ {
+ label: "Zipkin Trace",
+ value: "zipkinTrace",
+ },
+ {
+ label: "Browser Error Log",
+ value: "browserErrorLog",
+ },
+ {
+ label: "Cold Normal",
+ value: "coldNormal",
+ },
+ {
+ label: "Cold Trace",
+ value: "coldTrace",
+ },
+ {
+ label: "Cold Zipkin Trace",
+ value: "coldZipkinTrace",
+ },
+ {
+ label: "Cold Log",
+ value: "coldLog",
+ },
+ {
+ label: "Cold Browser Error Log",
+ value: "coldBrowserErrorLog",
+ },
+];
diff --git a/vite.config.ts b/vite.config.ts
index 0928bd3b..ebd5ce9e 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -75,6 +75,11 @@ export default ({ mode }: ConfigEnv): UserConfig => {
target: `${VITE_SW_PROXY_TARGET || "http://127.0.0.1:12800"}`,
changeOrigin: true,
},
+ "/api": {
+ target: `${VITE_SW_PROXY_TARGET || "http://127.0.0.1:12800"}`,
+ changeOrigin: true,
+ rewrite: (path) => path.replace(/^\/api/, ""),
+ },
},
},
build: {