diff --git a/src/assets/icons/spam.svg b/src/assets/icons/spam.svg new file mode 100755 index 00000000..b17f6b8a --- /dev/null +++ b/src/assets/icons/spam.svg @@ -0,0 +1,16 @@ + + + \ No newline at end of file diff --git a/src/graphql/fragments/alarm.ts b/src/graphql/fragments/alarm.ts new file mode 100644 index 00000000..bf4421e8 --- /dev/null +++ b/src/graphql/fragments/alarm.ts @@ -0,0 +1,50 @@ +/** + * 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 Alarm = { + variable: + "$keyword: String, $scope: Scope, $duration:Duration!, $tags:[AlarmTag], $paging: Pagination!", + query: ` + getAlarm(keyword: $keyword, scope: $scope, duration: $duration, paging: $paging, tags: $tags) { + items: msgs { + key: id + message + startTime + scope + tags { + key + value + } + events { + uuid + source { + service serviceInstance endpoint + } + name + type + message + parameters { + key + value + } + startTime + endTime + } + } + total + }`, +}; diff --git a/src/graphql/index.ts b/src/graphql/index.ts index c735dc4f..45cdd59b 100644 --- a/src/graphql/index.ts +++ b/src/graphql/index.ts @@ -23,6 +23,7 @@ import * as topology from "./query/topology"; import * as trace from "./query/trace"; import * as log from "./query/log"; import * as profile from "./query/profile"; +import * as alarm from "./query/alarm"; const query: { [key: string]: string } = { ...app, @@ -32,6 +33,7 @@ const query: { [key: string]: string } = { ...trace, ...log, ...profile, + ...alarm, }; class Graphql { private queryData = ""; diff --git a/src/graphql/query/alarm.ts b/src/graphql/query/alarm.ts new file mode 100644 index 00000000..a7becb54 --- /dev/null +++ b/src/graphql/query/alarm.ts @@ -0,0 +1,20 @@ +/** + * 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 { Alarm } from "../fragments/alarm"; + +export const queryAlarms = `query queryAlarms(${Alarm.variable}) {${Alarm.query}}`; diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts index ac45f3e6..1fdb5bf9 100644 --- a/src/locales/lang/en.ts +++ b/src/locales/lang/en.ts @@ -187,7 +187,7 @@ const msg = { list: "List", tree: "Tree", filterScope: "Filter Scope", - searchKeyword: "Search Keyword", + searchKeyword: "Keyword", quarterHourCutTip: "Last 15 mins", halfHourCutTip: "Last 30 mins", hourCutTip: "Last 1 hour", @@ -223,7 +223,7 @@ const msg = { view: "View", timeTips: "Time interval cannot exceed 60 days", standardAPM: "Standard", - entityType: "Entity type", + entityType: "Entity Type", maxItemNum: "Max number of Item", independentSelector: "Selectors", unknownMetrics: "Unknown Metrics", diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts index 0b605780..cd2c99e0 100644 --- a/src/locales/lang/zh.ts +++ b/src/locales/lang/zh.ts @@ -189,7 +189,7 @@ const msg = { list: "列表", tree: "树结构", filterScope: "过滤范围", - searchKeyword: "关键字搜索", + searchKeyword: "关键字", quarterHourCutTip: "最近15分钟", halfHourCutTip: "最近30分钟", hourCutTip: "最近1小时", diff --git a/src/router/alarm.ts b/src/router/alarm.ts index d5e341e8..42adc95a 100644 --- a/src/router/alarm.ts +++ b/src/router/alarm.ts @@ -33,10 +33,9 @@ export const routesAlarm: Array = [ path: "/alarm", name: "Alarm", meta: { - title: "alarmList", exact: false, }, - component: () => import("@/views/Log.vue"), + component: () => import("@/views/Alarm.vue"), }, ], }, diff --git a/src/router/index.ts b/src/router/index.ts index aa6e470d..0efc1fe2 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -21,7 +21,6 @@ import { routesMesh } from "./serviceMesh"; import { routesDatabase } from "./database"; import { routesInfra } from "./infrastructure"; import { routesDashboard } from "./dashboard"; -// import { routesLog } from "./log"; import { routesEvent } from "./event"; import { routesSetting } from "./setting"; import { routesAlarm } from "./alarm"; @@ -32,9 +31,9 @@ const routes: Array = [ ...routesDatabase, ...routesInfra, ...routesDashboard, + ...routesAlarm, ...routesEvent, ...routesSetting, - ...routesAlarm, ]; const router = createRouter({ diff --git a/src/store/modules/alarm.ts b/src/store/modules/alarm.ts new file mode 100644 index 00000000..fbf18aaa --- /dev/null +++ b/src/store/modules/alarm.ts @@ -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 { defineStore } from "pinia"; +import { store } from "@/store"; +import graphql from "@/graphql"; +import { AxiosResponse } from "axios"; +import { Alarm } from "@/types/alarm"; + +interface AlarmState { + loading: boolean; + alarms: Alarm[]; + total: number; +} + +export const alarmStore = defineStore({ + id: "alarm", + state: (): AlarmState => ({ + loading: false, + alarms: [], + total: 0, + }), + actions: { + async getAlarms(params: any) { + const res: AxiosResponse = await graphql + .query("queryAlarms") + .params(params); + if (res.data.errors) { + return res.data; + } + if (res.data.data.getAlarm.items) { + this.alarms = res.data.data.getAlarm.items; + this.total = res.data.data.getAlarm.total; + } + return res.data; + }, + }, +}); + +export function useAlarmStore(): any { + return alarmStore(store); +} diff --git a/src/styles/lib.scss b/src/styles/lib.scss index a589ae10..34083a5b 100644 --- a/src/styles/lib.scss +++ b/src/styles/lib.scss @@ -146,6 +146,12 @@ .mr-20 { margin-right: 20px; } + +.clear::after { + display: table; + content: ""; + clear: both; +} @keyframes loading { 0% { transform: rotate(0deg); diff --git a/src/types/alarm.d.ts b/src/types/alarm.d.ts new file mode 100644 index 00000000..06c09958 --- /dev/null +++ b/src/types/alarm.d.ts @@ -0,0 +1,46 @@ +/** + * 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 interface AlarmParams { + paging: number; + type: string; +} + +export interface Alarm { + message: string; + key: string; + startTime: string; + scope: string; + tags: Array<{ key: string; value: string }>; + events: Event[]; +} + +export interface Event { + endTime: number; + startTime: number; + type: string; + name: string; + message: string; + uuid: string; + source: Source; +} + +export interface Source { + service?: string; + endpoint?: string; + serviceInstance?: string; +} diff --git a/src/views/Alarm.vue b/src/views/Alarm.vue new file mode 100644 index 00000000..87a33ef5 --- /dev/null +++ b/src/views/Alarm.vue @@ -0,0 +1,35 @@ + + + + diff --git a/src/views/alarm/Content.vue b/src/views/alarm/Content.vue new file mode 100644 index 00000000..22c0112a --- /dev/null +++ b/src/views/alarm/Content.vue @@ -0,0 +1,190 @@ + + + + diff --git a/src/views/alarm/Header.vue b/src/views/alarm/Header.vue new file mode 100644 index 00000000..c1f2dd4d --- /dev/null +++ b/src/views/alarm/Header.vue @@ -0,0 +1,126 @@ + + + + diff --git a/src/views/alarm/data.ts b/src/views/alarm/data.ts new file mode 100644 index 00000000..d78f7ea8 --- /dev/null +++ b/src/views/alarm/data.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. + */ +export const AlarmOptions = [ + { label: "All", value: "" }, + { label: "Service", value: "Service" }, + { label: "ServiceInstance", value: "ServiceInstance" }, + { label: "Endpoint", value: "Endpoint" }, + { label: "ServiceRelation", value: "ServiceRelation" }, + { label: "ServiceInstanceRelation", value: "ServiceInstanceRelation" }, + { label: "EndpointRelation", value: "EndpointRelation" }, +]; +export const EventsDetailHeaders = [ + { text: "eventID", class: "uuid" }, + { text: "eventName", class: "name" }, + { text: "eventsType", class: "type" }, + { text: "startTime", class: "startTime" }, + { text: "endTime", class: "endTime" }, +]; + +export const AlarmDetailCol = [ + { + label: "scope", + value: "scope", + }, + { + label: "startTime", + value: "startTime", + }, + { + label: "tags", + value: "tags", + }, + { + label: "message", + value: "message", + }, + { + label: "events", + value: "eventDetail", + }, +]; + +export const EventsDetailKeys = [ + { text: "eventID", class: "uuid" }, + { text: "eventName", class: "name" }, + { text: "eventsType", class: "type" }, + { text: "startTime", class: "startTime" }, + { text: "endTime", class: "endTime" }, + { text: "eventsMessage", class: "message" }, + { text: "eventSource", class: "source" }, +]; diff --git a/src/views/alarm/index.scss b/src/views/alarm/index.scss new file mode 100644 index 00000000..bfdb5017 --- /dev/null +++ b/src/views/alarm/index.scss @@ -0,0 +1,115 @@ +/** + * 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. + */ + +.timeline-table { + padding: 30px 20px 20px 40px; + flex-grow: 1; + overflow: auto; + height: 100%; +} + +.time-line { + padding: 14px 30px; + min-height: 63px; + max-width: 132px; +} + +.timeline-table-i { + padding: 10px 15px; + border-left: 4px solid #eee; + position: relative; + + &::after { + content: ""; + display: inline-block; + position: absolute; + width: 7px; + height: 7px; + left: -23px; + top: 25px; + border-radius: 4px; + background-color: #448dfe; + } + + &::before { + content: ""; + display: inline-block; + position: absolute; + width: 1px; + height: calc(100% + 11px); + top: 0; + left: -20px; + border-radius: 5px; + background-color: #448dfe99; + } +} + +.timeline-table-i-scope { + display: inline-block; + padding: 0 8px; + border: 1px solid; + margin-top: -1px; + border-radius: 4px; +} + +.timeline-item { + cursor: pointer; + margin-bottom: 9px; +} + +.alarm-detail { + max-height: 600px; + overflow: auto; + + ul { + min-height: 100px; + overflow: auto; + margin-bottom: 20px; + } + + li { + cursor: pointer; + + > span { + width: 160px; + height: 20px; + line-height: 20px; + text-align: center; + display: inline-block; + border-bottom: 1px solid #ccc; + overflow: hidden; + } + } +} + +.keys { + font-weight: bold; + display: inline-block; + width: 120px; +} + +.source > span { + display: inline-block; +} + +.source > div { + padding-left: 120px; +} + +.uuid { + width: 280px; +} diff --git a/src/views/dashboard/related/components/ConditionTags.vue b/src/views/components/ConditionTags.vue similarity index 97% rename from src/views/dashboard/related/components/ConditionTags.vue rename to src/views/components/ConditionTags.vue index f755910d..4fb39719 100644 --- a/src/views/dashboard/related/components/ConditionTags.vue +++ b/src/views/components/ConditionTags.vue @@ -43,7 +43,7 @@ limitations under the License. --> - {{ t("noticeTag") }} + {{ t("noticeTag") }} @@ -59,7 +59,6 @@ defineProps({ }); const { t } = useI18n(); const theme = ref("dark"); -const type = ref(""); const tags = ref(""); const tagsList = ref([]); diff --git a/src/views/dashboard/related/log/Header.vue b/src/views/dashboard/related/log/Header.vue index 42a7e632..3b6c6d4e 100644 --- a/src/views/dashboard/related/log/Header.vue +++ b/src/views/dashboard/related/log/Header.vue @@ -123,7 +123,7 @@ import { useLogStore } from "@/store/modules/log"; import { useDashboardStore } from "@/store/modules/dashboard"; import { useAppStoreWithOut } from "@/store/modules/app"; import { useSelectorStore } from "@/store/modules/selectors"; -import ConditionTags from "@/views/dashboard/related/components/ConditionTags.vue"; +import ConditionTags from "@/views/components/ConditionTags.vue"; import { ElMessage } from "element-plus"; import { EntityType } from "../../data"; diff --git a/src/views/dashboard/related/trace/Filter.vue b/src/views/dashboard/related/trace/Filter.vue index 342a225b..7c72741e 100644 --- a/src/views/dashboard/related/trace/Filter.vue +++ b/src/views/dashboard/related/trace/Filter.vue @@ -95,7 +95,7 @@ import { useTraceStore } from "@/store/modules/trace"; import { useDashboardStore } from "@/store/modules/dashboard"; import { useAppStoreWithOut } from "@/store/modules/app"; import { useSelectorStore } from "@/store/modules/selectors"; -import ConditionTags from "@/views/dashboard/related/components/ConditionTags.vue"; +import ConditionTags from "@/views/components/ConditionTags.vue"; import { ElMessage } from "element-plus"; import { EntityType } from "../../data";