fix: add loading to monitor statistic (#11)

Co-authored-by: yaojiping <yaojiping@infini.ltd>
This commit is contained in:
yaojp123 2024-12-07 14:04:42 +08:00 committed by GitHub
parent e5dbe3123a
commit 8b176ab8ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 89 additions and 82 deletions

View File

@ -202,7 +202,7 @@ const DatePicker = (props) => {
const [reloadLoading, setReloadLoading] = useState(false) const [reloadLoading, setReloadLoading] = useState(false)
const onRefreshClick = () => { const onRefreshClick = () => {
setReloadLoading(true) setReloadLoading(true)
onRefresh && onRefresh({ start, end }); onRefresh && onRefresh({ start, end, refresh: true });
setTimeout(()=>{ setTimeout(()=>{
setReloadLoading(false) setReloadLoading(false)
}, 1000) }, 1000)

View File

@ -24,6 +24,7 @@ export default (props) => {
queryParams={queryParams} queryParams={queryParams}
timeout={timeout} timeout={timeout}
className={styles.lineWrapper} className={styles.lineWrapper}
height={150}
formatMetric={(metric) => { formatMetric={(metric) => {
if (!metric) return metric; if (!metric) return metric;
let units = ""; let units = "";

View File

@ -1,5 +1,5 @@
import React, { useState, useMemo, useEffect, useCallback } from "react"; import React, { useState, useMemo, useEffect, useCallback } from "react";
import { Card, Tabs, Breadcrumb, Button, BackTop, Empty } from "antd"; import { Card, Tabs, Breadcrumb, Button, BackTop, Empty, Spin } from "antd";
import { calculateBounds } from "@/components/vendor/data/common/query/timefilter"; import { calculateBounds } from "@/components/vendor/data/common/query/timefilter";
import { formatter } from "@/utils/format"; import { formatter } from "@/utils/format";
import moment from "moment"; import moment from "moment";
@ -66,6 +66,7 @@ const Monitor = (props) => {
timeInterval: formatTimeInterval(param?.timeInterval), timeInterval: formatTimeInterval(param?.timeInterval),
timeout: formatTimeout(param?.timeout) || localStorage.getItem(TIMEOUT_CACHE_KEY) || '120s', timeout: formatTimeout(param?.timeout) || localStorage.getItem(TIMEOUT_CACHE_KEY) || '120s',
param: param, param: param,
refresh: true
}) })
); );
@ -76,7 +77,7 @@ const Monitor = (props) => {
setParam({ ...param, timeRange: state.timeRange, timeInterval: state.timeInterval, timeout: state.timeout }); setParam({ ...param, timeRange: state.timeRange, timeInterval: state.timeInterval, timeout: state.timeout });
}, [state.timeRange, state.timeInterval, state.timeout]); }, [state.timeRange, state.timeInterval, state.timeout]);
const handleTimeChange = useCallback(({ start, end, timeInterval, timeout }) => { const handleTimeChange = useCallback(({ start, end, timeInterval, timeout, refresh }) => {
const bounds = calculateBounds({ const bounds = calculateBounds({
from: start, from: start,
to: end, to: end,
@ -93,9 +94,9 @@ const Monitor = (props) => {
timeFormatter: formatter.dates(intDay), timeFormatter: formatter.dates(intDay),
}, },
timeInterval: timeInterval || state.timeInterval, timeInterval: timeInterval || state.timeInterval,
timeout: timeout || state.timeout timeout: timeout || state.timeout,
refresh
}); });
setSpinning(true);
}, [state]) }, [state])
const onInfoChange = (info) => { const onInfoChange = (info) => {
@ -112,6 +113,12 @@ const Monitor = (props) => {
return monitor_configs?.node_stats?.enabled === false && monitor_configs?.index_stats?.enabled === false return monitor_configs?.node_stats?.enabled === false && monitor_configs?.index_stats?.enabled === false
}, [JSON.stringify(selectedCluster?.monitor_configs)]) }, [JSON.stringify(selectedCluster?.monitor_configs)])
console.log("spinning")
console.log(spinning)
console.log("state.refresh")
console.log(state.refresh)
return ( return (
<div> <div>
<BreadcrumbList data={breadcrumbList} /> <BreadcrumbList data={breadcrumbList} />
@ -165,12 +172,14 @@ const Monitor = (props) => {
> >
{panes.map((pane) => ( {panes.map((pane) => (
<TabPane tab={pane.title} key={pane.key}> <TabPane tab={pane.title} key={pane.key}>
<Spin spinning={spinning && !!state.refresh}>
<StatisticBar <StatisticBar
setSpinning={setSpinning} setSpinning={setSpinning}
onInfoChange={onInfoChange} onInfoChange={onInfoChange}
{...state} {...state}
{...extraParams} {...extraParams}
/> />
</Spin>
<div style={{ marginTop: 15 }}> <div style={{ marginTop: 15 }}>
{checkPaneParams({ {checkPaneParams({
...state, ...state,

View File

@ -6,7 +6,7 @@ const DEFAULT_OPTIONS = {
}; };
export default function useFetch(url, options = {}, dependencies = [], runInInit = true) { export default function useFetch(url, options = {}, dependencies = [], runInInit = true) {
const { returnRawResponse, noticeable, ...rest } = options const { returnRawResponse, noticeable, ...rest } = options || {}
return useAsync(() => { return useAsync(() => {
return request(url, { ...DEFAULT_OPTIONS, ...rest }, returnRawResponse, noticeable); return request(url, { ...DEFAULT_OPTIONS, ...rest }, returnRawResponse, noticeable);
}, dependencies, runInInit); }, dependencies, runInInit);

View File

@ -8,17 +8,27 @@ import QueueMetric from "../../components/queue_metric";
import { ESPrefix } from "@/services/common"; import { ESPrefix } from "@/services/common";
import { SearchEngines } from "@/lib/search_engines"; import { SearchEngines } from "@/lib/search_engines";
const timezone = "local";
export default ({ export default ({
selectedCluster, selectedCluster,
clusterID, clusterID,
timeRange, timeRange,
handleTimeChange, handleTimeChange,
timezone,
bucketSize, bucketSize,
timeout, timeout,
refresh,
}) => { }) => {
const tabProps = {
clusterID,
timeRange,
handleTimeChange,
timezone,
bucketSize,
timeout,
refresh
}
const isVersionGTE6 = useMemo(() => { const isVersionGTE6 = useMemo(() => {
if ([SearchEngines.Easysearch, SearchEngines.Opensearch].includes(selectedCluster?.distribution)) return true; if ([SearchEngines.Easysearch, SearchEngines.Opensearch].includes(selectedCluster?.distribution)) return true;
const main = selectedCluster?.version?.split('.')[0] const main = selectedCluster?.version?.split('.')[0]
@ -56,12 +66,8 @@ export default ({
})} })}
> >
<ClusterMetric <ClusterMetric
timezone={timezone} {...tabProps}
timeRange={timeRange}
handleTimeChange={handleTimeChange}
fetchUrl={`${ESPrefix}/${clusterID}/cluster_metrics`} fetchUrl={`${ESPrefix}/${clusterID}/cluster_metrics`}
bucketSize={bucketSize}
timeout={timeout}
metrics={[ metrics={[
'cluster_health', 'cluster_health',
'index_throughput', 'index_throughput',
@ -84,14 +90,9 @@ export default ({
})} })}
> >
<NodeMetric <NodeMetric
clusterID={clusterID} {...tabProps}
timezone={timezone}
timeRange={timeRange}
handleTimeChange={handleTimeChange}
param={param} param={param}
setParam={setParam} setParam={setParam}
bucketSize={bucketSize}
timeout={timeout}
metrics={[ metrics={[
[ [
"operations", "operations",
@ -231,14 +232,9 @@ export default ({
})} })}
> >
<IndexMetric <IndexMetric
clusterID={clusterID} {...tabProps}
timezone={timezone}
timeRange={timeRange}
handleTimeChange={handleTimeChange}
param={param} param={param}
setParam={setParam} setParam={setParam}
bucketSize={bucketSize}
timeout={timeout}
metrics={[ metrics={[
[ [
"operations", "operations",
@ -314,14 +310,9 @@ export default ({
})} })}
> >
<QueueMetric <QueueMetric
clusterID={clusterID} {...tabProps}
timezone={timezone}
timeRange={timeRange}
handleTimeChange={handleTimeChange}
param={param} param={param}
setParam={setParam} setParam={setParam}
bucketSize={bucketSize}
timeout={timeout}
metrics={[ metrics={[
isVersionGTE6 ? [ isVersionGTE6 ? [
"thread_pool_write", "thread_pool_write",
@ -397,18 +388,6 @@ export default ({
].filter((item) => !!item)} ].filter((item) => !!item)}
/> />
</Tabs.TabPane> </Tabs.TabPane>
{/* <Tabs.TabPane
key="storage"
tab={formatMessage({
id: "cluster.monitor.queue.storage",
})}
>
<StorageMetric
clusterID={clusterID}
timezone={timezone}
timeRange={timeRange}
/>
</Tabs.TabPane> */}
</Tabs> </Tabs>
); );
} }

View File

@ -1,20 +1,21 @@
import ClusterMetric from "../../components/cluster_metric"; import ClusterMetric from "../../components/cluster_metric";
import { ESPrefix } from "@/services/common"; import { ESPrefix } from "@/services/common";
const timezone = "local";
export default ({ export default ({
clusterID, clusterID,
timeRange, timeRange,
handleTimeChange, handleTimeChange,
bucketSize, bucketSize,
timeout, timeout,
timezone,
refresh
}) => { }) => {
return ( return (
<ClusterMetric <ClusterMetric
timezone={timezone} timezone={timezone}
timeRange={timeRange} timeRange={timeRange}
timeout={timeout} timeout={timeout}
refresh={refresh}
handleTimeChange={handleTimeChange} handleTimeChange={handleTimeChange}
overview={1} overview={1}
fetchUrl={`${ESPrefix}/${clusterID}/cluster_metrics`} fetchUrl={`${ESPrefix}/${clusterID}/cluster_metrics`}

View File

@ -2,8 +2,6 @@ import { useState } from "react";
import StatisticBar from "./statistic_bar"; import StatisticBar from "./statistic_bar";
import IndexMetric from "../../components/index_metric"; import IndexMetric from "../../components/index_metric";
const timezone = "local";
export default ({ export default ({
clusterID, clusterID,
indexName, indexName,
@ -11,7 +9,9 @@ export default ({
handleTimeChange, handleTimeChange,
shardID, shardID,
bucketSize, bucketSize,
timeout timezone,
timeout,
refresh,
}) => { }) => {
const [param, setParam] = useState({ const [param, setParam] = useState({
show_top: false, show_top: false,
@ -28,6 +28,7 @@ export default ({
shardID={shardID} shardID={shardID}
bucketSize={bucketSize} bucketSize={bucketSize}
timeout={timeout} timeout={timeout}
refresh={refresh}
metrics={[ metrics={[
[ [
"operations", "operations",

View File

@ -2,8 +2,6 @@ import { ESPrefix } from "@/services/common";
import StatisticBar from "./statistic_bar"; import StatisticBar from "./statistic_bar";
import ClusterMetric from "../../components/cluster_metric"; import ClusterMetric from "../../components/cluster_metric";
const timezone = "local";
export default ({ export default ({
isAgent, isAgent,
clusterID, clusterID,
@ -12,7 +10,9 @@ export default ({
handleTimeChange, handleTimeChange,
shardID, shardID,
bucketSize, bucketSize,
timeout timezone,
timeout,
refresh
}) => { }) => {
let url = `${ESPrefix}/${clusterID}/index/${indexName}/metrics`; let url = `${ESPrefix}/${clusterID}/index/${indexName}/metrics`;
if(shardID){ if(shardID){
@ -27,6 +27,7 @@ export default ({
fetchUrl={url} fetchUrl={url}
bucketSize={bucketSize} bucketSize={bucketSize}
timeout={timeout} timeout={timeout}
refresh={refresh}
metrics={[ metrics={[
"index_health", "index_health",
"index_throughput", "index_throughput",

View File

@ -5,18 +5,28 @@ import QueueMetric from "../../components/queue_metric";
import { formatMessage } from "umi/locale"; import { formatMessage } from "umi/locale";
import { SearchEngines } from "@/lib/search_engines"; import { SearchEngines } from "@/lib/search_engines";
const timezone = "local";
export default ({ export default ({
selectedCluster, selectedCluster,
clusterID, clusterID,
nodeID, nodeID,
timeRange, timeRange,
handleTimeChange, handleTimeChange,
timezone,
bucketSize, bucketSize,
timeout, timeout,
refresh,
}) => { }) => {
const tabProps = {
clusterID,
timeRange,
handleTimeChange,
timezone,
bucketSize,
timeout,
refresh
}
const isVersionGTE6 = useMemo(() => { const isVersionGTE6 = useMemo(() => {
if ([SearchEngines.Easysearch, SearchEngines.Opensearch].includes(selectedCluster?.distribution)) return true; if ([SearchEngines.Easysearch, SearchEngines.Opensearch].includes(selectedCluster?.distribution)) return true;
const main = selectedCluster?.version?.split('.')[0] const main = selectedCluster?.version?.split('.')[0]
@ -59,14 +69,9 @@ export default ({
})} })}
> >
<NodeMetric <NodeMetric
clusterID={clusterID} {...tabProps}
timezone={timezone}
timeRange={timeRange}
handleTimeChange={handleTimeChange}
param={param} param={param}
setParam={setParam} setParam={setParam}
bucketSize={bucketSize}
timeout={timeout}
metrics={[ metrics={[
[ [
"operations", "operations",
@ -206,14 +211,9 @@ export default ({
})} })}
> >
<QueueMetric <QueueMetric
clusterID={clusterID} {...tabProps}
timezone={timezone}
timeRange={timeRange}
handleTimeChange={handleTimeChange}
param={param} param={param}
setParam={setParam} setParam={setParam}
bucketSize={bucketSize}
timeout={timeout}
metrics={[ metrics={[
isVersionGTE6 ? [ isVersionGTE6 ? [
"thread_pool_write", "thread_pool_write",

View File

@ -3,8 +3,6 @@ import StatisticBar from "./statistic_bar";
import ClusterMetric from "../../components/cluster_metric"; import ClusterMetric from "../../components/cluster_metric";
import { useMemo } from "react"; import { useMemo } from "react";
const timezone = "local";
export default ({ export default ({
isAgent, isAgent,
clusterID, clusterID,
@ -12,7 +10,9 @@ export default ({
timeRange, timeRange,
handleTimeChange, handleTimeChange,
bucketSize, bucketSize,
timezone,
timeout, timeout,
refresh
}) => { }) => {
return ( return (
@ -20,6 +20,7 @@ export default ({
timezone={timezone} timezone={timezone}
timeRange={timeRange} timeRange={timeRange}
timeout={timeout} timeout={timeout}
refresh={refresh}
handleTimeChange={handleTimeChange} handleTimeChange={handleTimeChange}
overview={1} overview={1}
fetchUrl={`${ESPrefix}/${clusterID}/node/${nodeID}/metrics`} fetchUrl={`${ESPrefix}/${clusterID}/node/${nodeID}/metrics`}

View File

@ -27,6 +27,7 @@ export default (props) => {
timezone, timezone,
timeRange, timeRange,
timeout, timeout,
refresh,
handleTimeChange, handleTimeChange,
fetchUrl, fetchUrl,
metricKey, metricKey,
@ -82,9 +83,9 @@ export default (props) => {
} }
useEffect(() => { useEffect(() => {
observerRef.current.deps = cloneDeep([queryParams, fetchUrl, metricKey]) observerRef.current.deps = cloneDeep([queryParams, fetchUrl, metricKey, refresh])
fetchData(queryParams, fetchUrl, metricKey) fetchData(queryParams, fetchUrl, metricKey, refresh)
}, [JSON.stringify(queryParams), fetchUrl, metricKey]) }, [JSON.stringify(queryParams), fetchUrl, metricKey, refresh])
useEffect(() => { useEffect(() => {
const observer = new IntersectionObserver( const observer = new IntersectionObserver(
@ -144,7 +145,6 @@ export default (props) => {
}; };
const renderChart = () => { const renderChart = () => {
if (loading) return <div style={{ height }}></div>
if (error) { if (error) {
return ( return (
<div style={{ height, padding: 10 }}> <div style={{ height, padding: 10 }}>
@ -155,7 +155,14 @@ export default (props) => {
const axis = metric?.axis || []; const axis = metric?.axis || [];
const lines = metric?.lines || []; const lines = metric?.lines || [];
if (lines.every((item) => !item.data || item.data.length === 0)) { if (lines.every((item) => !item.data || item.data.length === 0)) {
return <Empty style={{ height, margin: 0, paddingTop: 64 }} image={Empty.PRESENTED_IMAGE_SIMPLE} /> return (
<div style={{ height, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<Empty style={{ margin: 0}} image={Empty.PRESENTED_IMAGE_SIMPLE} />
</div>
)
}
if (customRenderChart) {
return customRenderChart(metric)
} }
return ( return (
<Chart <Chart
@ -314,7 +321,7 @@ export default (props) => {
</span> </span>
} }
</div> </div>
{customRenderChart ? customRenderChart(metric) : renderChart()} {renderChart()}
</Spin> </Spin>
</div> </div>
); );

View File

@ -8,7 +8,7 @@ import { formatTimeRange } from "@/lib/elasticsearch/util";
export default (props) => { export default (props) => {
const { fetchUrl, overview, metrics = [], renderExtra, timeRange, timeout, timezone, bucketSize, handleTimeChange } = props const { fetchUrl, overview, metrics = [], renderExtra, timeRange, timeout, timezone, refresh, bucketSize, handleTimeChange } = props
if (!fetchUrl || metrics.length === 0) { if (!fetchUrl || metrics.length === 0) {
return null; return null;
@ -36,6 +36,7 @@ export default (props) => {
timezone={timezone} timezone={timezone}
timeRange={timeRange} timeRange={timeRange}
timeout={timeout} timeout={timeout}
refresh={refresh}
handleTimeChange={handleTimeChange} handleTimeChange={handleTimeChange}
fetchUrl={fetchUrl} fetchUrl={fetchUrl}
metricKey={metricKey} metricKey={metricKey}

View File

@ -23,7 +23,8 @@ export default (props) => {
shardID, shardID,
bucketSize, bucketSize,
metrics = [], metrics = [],
timeout timeout,
refresh,
} = props } = props
if (!clusterID || metrics.length == 0) { if (!clusterID || metrics.length == 0) {
@ -130,6 +131,7 @@ export default (props) => {
queryParams={queryParams} queryParams={queryParams}
className={"metric-item"} className={"metric-item"}
timeout={timeout} timeout={timeout}
refresh={refresh}
/> />
)) ))
} }

View File

@ -21,6 +21,7 @@ export default (props) => {
setParam, setParam,
bucketSize, bucketSize,
timeout, timeout,
refresh,
metrics = [] metrics = []
} = props } = props
@ -153,6 +154,7 @@ export default (props) => {
queryParams={queryParams} queryParams={queryParams}
className={"metric-item"} className={"metric-item"}
timeout={timeout} timeout={timeout}
refresh={refresh}
/> />
)) ))
} }

View File

@ -21,7 +21,8 @@ export default (props) => {
setParam, setParam,
bucketSize, bucketSize,
metrics = [], metrics = [],
timeout timeout,
refresh
} = props } = props
if (!clusterID || metrics.length == 0) { if (!clusterID || metrics.length == 0) {
@ -153,6 +154,7 @@ export default (props) => {
queryParams={queryParams} queryParams={queryParams}
className={"metric-item"} className={"metric-item"}
timeout={timeout} timeout={timeout}
refresh={refresh}
/> />
)) ))
} }