diff --git a/src/graphql/fragments/event.ts b/src/graphql/fragments/event.ts new file mode 100644 index 00000000..00d5bb09 --- /dev/null +++ b/src/graphql/fragments/event.ts @@ -0,0 +1,40 @@ +/** + * 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 FetchEvents = { + variable: ["$condition: EventQueryCondition"], + query: ` + fetchEvents: queryEvents(condition: $condition) { + 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 45cdd59b..ab6fd319 100644 --- a/src/graphql/index.ts +++ b/src/graphql/index.ts @@ -24,6 +24,7 @@ import * as trace from "./query/trace"; import * as log from "./query/log"; import * as profile from "./query/profile"; import * as alarm from "./query/alarm"; +import * as event from "./query/event"; const query: { [key: string]: string } = { ...app, @@ -34,6 +35,7 @@ const query: { [key: string]: string } = { ...log, ...profile, ...alarm, + ...event, }; class Graphql { private queryData = ""; diff --git a/src/graphql/query/event.ts b/src/graphql/query/event.ts new file mode 100644 index 00000000..f27be946 --- /dev/null +++ b/src/graphql/query/event.ts @@ -0,0 +1,19 @@ +/** + * 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 { FetchEvents } from "../fragments/event"; + +export const queryEvents = `query queryData(${FetchEvents.variable}) {${FetchEvents.query}}`; diff --git a/src/router/event.ts b/src/router/event.ts index 4f8c8274..0b587dc1 100644 --- a/src/router/event.ts +++ b/src/router/event.ts @@ -33,10 +33,9 @@ export const routesEvent: Array = [ path: "/events", name: "Events", meta: { - title: "eventList", exact: false, }, - component: () => import("@/views/Log.vue"), + component: () => import("@/views/Event.vue"), }, ], }, diff --git a/src/store/modules/event.ts b/src/store/modules/event.ts new file mode 100644 index 00000000..e993a4ee --- /dev/null +++ b/src/store/modules/event.ts @@ -0,0 +1,123 @@ +/** + * 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 { Event, QueryEventCondition } from "@/types/events"; +import { Instance, Endpoint, Service } from "@/types/selector"; +import { useAppStoreWithOut } from "@/store/modules/app"; + +interface eventState { + loading: boolean; + events: Event[]; + total: number; + services: Service[]; + instances: Instance[]; + endpoints: Endpoint[]; + condition: QueryEventCondition | any; +} + +export const eventStore = defineStore({ + id: "event", + state: (): eventState => ({ + loading: false, + events: [], + total: 0, + services: [{ value: "", label: "" }], + instances: [{ value: "", label: "All" }], + endpoints: [{ value: "", label: "All" }], + condition: { + time: useAppStoreWithOut().durationTime, + paging: { pageNum: 1, pageSize: 15, needTotal: true }, + }, + }), + actions: { + setEventCondition(data: any) { + this.condition = { ...this.condition, ...data }; + }, + async getServices(layer: string) { + const res: AxiosResponse = await graphql.query("queryServices").params({ + layer, + }); + if (res.data.errors) { + return res.data; + } + this.services = res.data.data.services; + return res.data; + }, + async getInstances(serviceId: string) { + const res: AxiosResponse = await graphql.query("queryInstances").params({ + serviceId, + duration: useAppStoreWithOut().durationTime, + }); + + if (res.data.errors) { + return res.data; + } + this.instances = [{ value: "", label: "All" }, ...res.data.data.pods] || [ + { value: "", label: "All" }, + ]; + return res.data; + }, + async getEndpoints(serviceId: string) { + const res: AxiosResponse = await graphql.query("queryEndpoints").params({ + serviceId, + duration: useAppStoreWithOut().durationTime, + keyword: "", + }); + if (res.data.errors) { + return res.data; + } + this.endpoints = [{ value: "", label: "All" }, ...res.data.data.pods] || [ + { value: "", label: "All" }, + ]; + return res.data; + }, + async getEvents() { + this.loading = true; + const res: AxiosResponse = await graphql + .query("queryEvents") + .params({ condition: this.condition }); + this.loading = false; + if (res.data.errors) { + return res.data; + } + if (res.data.data.fetchEvents) { + this.events = (res.data.data.fetchEvents.events || []).map( + (item: Event) => { + let scope = "Service"; + if (item.source.serviceInstance) { + scope = "ServiceInstance"; + } + if (item.source.endpoint) { + scope = "Endpoint"; + } + item.scope = scope; + return item; + } + ); + this.total = res.data.data.fetchEvents.total; + } + return res.data; + }, + }, +}); + +export function useEventStore(): any { + return eventStore(store); +} diff --git a/src/types/events.d.ts b/src/types/events.d.ts index e36c037c..e4684134 100644 --- a/src/types/events.d.ts +++ b/src/types/events.d.ts @@ -27,3 +27,19 @@ export type Event = { checked?: boolean; scope?: string; }; + +export interface QueryEventCondition { + uuid: string; + source: SourceInput; + name: string; + type: EventType; + time: Duration; + order: string; + paging: { pageNum: number; pageSize: number; needTotal: boolean }; +} + +type SourceInput = { + service: string; + serviceInstance: string; + endpoint: string; +}; diff --git a/src/views/Event.vue b/src/views/Event.vue new file mode 100644 index 00000000..b308ce8c --- /dev/null +++ b/src/views/Event.vue @@ -0,0 +1,36 @@ + + + + diff --git a/src/views/Log.vue b/src/views/Log.vue index 9b188c71..af188897 100644 --- a/src/views/Log.vue +++ b/src/views/Log.vue @@ -4,9 +4,7 @@ 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. @@ -17,7 +15,6 @@ limitations under the License. --> diff --git a/src/views/event/Content.vue b/src/views/event/Content.vue new file mode 100644 index 00000000..b01b9854 --- /dev/null +++ b/src/views/event/Content.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/src/views/event/Header.vue b/src/views/event/Header.vue new file mode 100644 index 00000000..e70cf819 --- /dev/null +++ b/src/views/event/Header.vue @@ -0,0 +1,247 @@ + + + + diff --git a/src/router/log.ts b/src/views/event/data.ts similarity index 52% rename from src/router/log.ts rename to src/views/event/data.ts index d1f5541c..e5c7d5da 100644 --- a/src/router/log.ts +++ b/src/views/event/data.ts @@ -14,34 +14,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { RouteRecordRaw } from "vue-router"; -import Layout from "@/layout/Index.vue"; - -export const routesLog: Array = [ - { - path: "", - name: "Logs", - meta: { - title: "logs", - icon: "assignment", - hasGroup: false, - exact: false, - }, - component: Layout, - children: [ - { - path: "/log", - name: "Logs", - meta: { - title: "log", - exact: false, - }, - // route level code-splitting - // this generates a separate chunk (about.[hash].js) for this route - // which is lazy-loaded when the route is visited. - component: () => - import(/* webpackChunkName: "about" */ "@/views/Log.vue"), - }, - ], - }, +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" }, +]; +export const EventTypes = [ + { label: "All", value: "" }, + { label: "Normal", value: "Normal" }, + { label: "Error", value: "Error" }, ];