diff --git a/src/graphql/fragments/alarm.ts b/src/graphql/fragments/alarm.ts index a2e9ba0c..76ed4672 100644 --- a/src/graphql/fragments/alarm.ts +++ b/src/graphql/fragments/alarm.ts @@ -24,6 +24,7 @@ export const Alarm = { message startTime scope + name tags { key value @@ -43,6 +44,35 @@ export const Alarm = { startTime endTime } + snapshot { + expression + metrics { + name + results { + metric { + labels { + key + value + } + } + values { + id + owner { + scope + serviceID + serviceName + normal + serviceInstanceID + serviceInstanceName + endpointID + endpointName + } + value + traceID + } + } + } + } } }`, }; diff --git a/src/hooks/useSnapshot.ts b/src/hooks/useSnapshot.ts new file mode 100644 index 00000000..2ddfc9b7 --- /dev/null +++ b/src/hooks/useSnapshot.ts @@ -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. + */ +import type { MetricsResults } from "@/types/dashboard"; + +export function useSnapshot(metrics: { name: string; results: MetricsResults[] }[]) { + function processResults() { + const sources = metrics.map((metric: { name: string; results: MetricsResults[] }) => { + const values = metric.results.map( + (r: { values: { value: string }[]; metric: { labels: { key: string; value: string }[] } }) => { + const arr = r.values.map((v: { value: string }) => Number(v.value)); + if (!r.metric.labels.length) { + return { values: arr }; + } + const name = r.metric.labels + .map( + (label: { key: string; value: string }) => + `${metric.name}${label ? "{" : ""}${label.key}=${label.value}${label ? "}" : ""}`, + ) + .join(","); + return { name, values: arr }; + }, + ); + + return { name: metric.name, values }; + }); + + return sources; + } + + return { + processResults, + }; +} diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts index 5640a21d..98764453 100644 --- a/src/locales/lang/en.ts +++ b/src/locales/lang/en.ts @@ -395,5 +395,7 @@ const msg = { profilingEvents: "Async Profiling Events", execArgs: "Exec Args", instances: "Instances", + snapshot: "Snapshot", + expression: "Expression", }; export default msg; diff --git a/src/locales/lang/es.ts b/src/locales/lang/es.ts index 4496b367..bc030873 100644 --- a/src/locales/lang/es.ts +++ b/src/locales/lang/es.ts @@ -395,5 +395,7 @@ const msg = { profilingEvents: "Async Profiling Events", execArgs: "Exec Args", instances: "Instances", + snapshot: "Snapshot", + expression: "Expression", }; export default msg; diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts index 800d8c78..359ebb97 100644 --- a/src/locales/lang/zh.ts +++ b/src/locales/lang/zh.ts @@ -393,5 +393,7 @@ const msg = { profilingEvents: "异步分析事件", execArgs: "String任务扩展", instances: "实例", + snapshot: "快照", + expression: "表达式", }; export default msg; diff --git a/src/types/alarm.d.ts b/src/types/alarm.d.ts index 06c09958..df791ca2 100644 --- a/src/types/alarm.d.ts +++ b/src/types/alarm.d.ts @@ -27,6 +27,7 @@ export interface Alarm { scope: string; tags: Array<{ key: string; value: string }>; events: Event[]; + snapshot: Indexable; } export interface Event { diff --git a/src/types/dashboard.d.ts b/src/types/dashboard.d.ts index fa72ce4a..d021e48d 100644 --- a/src/types/dashboard.d.ts +++ b/src/types/dashboard.d.ts @@ -111,6 +111,8 @@ export interface LineConfig extends AreaConfig { showYAxis?: boolean; smallTips?: boolean; showlabels?: boolean; + noTooltips?: boolean; + showLegend?: boolean; } export interface AreaConfig { @@ -197,3 +199,17 @@ export type LegendOptions = { toTheRight: boolean; width: number; }; +export type MetricsResults = { + metric: { labels: MetricLabel[] }; + values: MetricValue[]; +}; +type MetricLabel = { + key: string; + value: string; +}; +type MetricValue = { + name: string; + value: string; + owner: null | string; + refId: null | string; +}; diff --git a/src/views/alarm/Content.vue b/src/views/alarm/Content.vue index 0a8988ae..aee06071 100644 --- a/src/views/alarm/Content.vue +++ b/src/views/alarm/Content.vue @@ -22,15 +22,17 @@ limitations under the License. -->
{{ i.message }}
-
- {{ t(i.scope.toLowerCase()) }} +
+
+ {{ t(i.scope.toLowerCase()) }} +
{{ dateFormat(parseInt(i.startTime)) }} @@ -46,7 +48,7 @@ limitations under the License. --> :destroy-on-close="true" @closed="isShowDetails = false" > -
+
{{ t(item.value) }}: {{ dateFormat(currentDetail[item.label]) }} @@ -54,7 +56,7 @@ limitations under the License. -->
{{ d }}
- +
  • @@ -75,6 +77,12 @@ limitations under the License. -->
+ + {{ currentDetail.snapshot.expression }} + + + + {{ currentDetail[item.label] }}
@@ -85,7 +93,7 @@ limitations under the License. --> :destroy-on-close="true" @closed="showEventDetails = false" > -
+
{{ t(eventKey.text) }} @@ -117,6 +125,7 @@ limitations under the License. --> import { useAlarmStore } from "@/store/modules/alarm"; import { EventsDetailHeaders, AlarmDetailCol, EventsDetailKeys } from "./data"; import { dateFormat } from "@/utils/dateFormat"; + import Snapshot from "./components/Snapshot.vue"; const { t } = useI18n(); const alarmStore = useAlarmStore(); @@ -186,11 +195,10 @@ limitations under the License. --> } .timeline-table-i-scope { - display: inline-block; - padding: 0 8px; + padding: 0 5px; border: 1px solid; - margin-top: -1px; - border-radius: 4px; + border-radius: 3px; + display: inline-block; } .timeline-item { @@ -224,9 +232,6 @@ limitations under the License. --> } .alarm-detail { - max-height: 600px; - overflow: auto; - ul { min-height: 100px; overflow: auto; @@ -247,4 +252,9 @@ limitations under the License. --> } } } + + .mini-chart { + height: 20px; + width: 400px; + } diff --git a/src/views/alarm/components/Line.vue b/src/views/alarm/components/Line.vue new file mode 100644 index 00000000..da8be69f --- /dev/null +++ b/src/views/alarm/components/Line.vue @@ -0,0 +1,141 @@ + + + + diff --git a/src/views/alarm/components/Snapshot.vue b/src/views/alarm/components/Snapshot.vue new file mode 100644 index 00000000..5b7fad33 --- /dev/null +++ b/src/views/alarm/components/Snapshot.vue @@ -0,0 +1,35 @@ + + + diff --git a/src/views/alarm/data.ts b/src/views/alarm/data.ts index d78f7ea8..22701308 100644 --- a/src/views/alarm/data.ts +++ b/src/views/alarm/data.ts @@ -52,6 +52,14 @@ export const AlarmDetailCol = [ label: "events", value: "eventDetail", }, + { + label: "expression", + value: "expression", + }, + { + label: "snapshot", + value: "snapshot", + }, ]; export const EventsDetailKeys = [ diff --git a/src/views/dashboard/graphs/Line.vue b/src/views/dashboard/graphs/Line.vue index 11d23515..d91b31c2 100644 --- a/src/views/dashboard/graphs/Line.vue +++ b/src/views/dashboard/graphs/Line.vue @@ -60,6 +60,8 @@ limitations under the License. --> showYAxis: true, smallTips: false, showlabels: true, + noTooltips: false, + showLegend: true, }), }, }); @@ -69,10 +71,12 @@ limitations under the License. --> function getOption() { const { showEchartsLegend, isRight, chartColors } = useLegendProcess(props.config.legend); setRight.value = isRight; - const keys = Object.keys(props.data || {}).filter((i: any) => Array.isArray(props.data[i]) && props.data[i].length); - const temp = keys.map((i: any) => { + const keys = Object.keys(props.data || {}).filter( + (i: string) => Array.isArray(props.data[i]) && props.data[i].length, + ); + const temp = keys.map((i: string) => { const serie: any = { - data: props.data[i].map((item: any, itemIndex: number) => [props.intervalTime[itemIndex], item]), + data: props.data[i].map((item: number, itemIndex: number) => [props.intervalTime[itemIndex], item]), name: i, type: "line", symbol: "circle", @@ -95,6 +99,7 @@ limitations under the License. --> const color: string[] = chartColors(); const tooltip = { trigger: "axis", + show: !props.config.noTooltips, backgroundColor: appStore.theme === Themes.Dark ? "#333" : "#fff", borderColor: appStore.theme === Themes.Dark ? "#333" : "#fff", textStyle: { @@ -106,10 +111,10 @@ limitations under the License. --> extraCssText: "max-height:85%; overflow: auto;", }; const tips = { + show: !props.config.noTooltips, formatter(params: any) { return `${params[0].value[1]}`; }, - confine: true, extraCssText: `height: 20px; padding:0 2px;`, trigger: "axis", backgroundColor: appStore.theme === Themes.Dark ? "#666" : "#eee", @@ -125,7 +130,7 @@ limitations under the License. --> tooltip: props.config.smallTips ? tips : tooltip, legend: { type: "scroll", - show: showEchartsLegend(keys), + show: props.config.showLegend ? showEchartsLegend(keys) : false, icon: "circle", top: 0, left: 0,