This commit is contained in:
liugq 2021-11-22 17:09:50 +08:00
parent e99cac3164
commit 40fc099219
5 changed files with 172 additions and 130 deletions

5
package.json Normal file
View File

@ -0,0 +1,5 @@
{
"dependencies": {
"react-ga": "^3.3.0"
}
}

View File

@ -1,27 +1,31 @@
import { queryNotices } from '@/services/api'; import { queryNotices } from "@/services/api";
import {message} from "antd"; import { message } from "antd";
import {searchClusterConfig, getClusterStatus} from "@/services/cluster"; import { searchClusterConfig, getClusterStatus } from "@/services/cluster";
import {formatESSearchResult, extractClusterIDFromURL} from '@/lib/elasticsearch/util'; import {
import {Modal} from 'antd'; formatESSearchResult,
extractClusterIDFromURL,
} from "@/lib/elasticsearch/util";
import { Modal } from "antd";
import router from "umi/router"; import router from "umi/router";
import _ from 'lodash'; import _ from "lodash";
import ReactGA from "react-ga";
ReactGA.initialize("G-L0XH1C4CVP");
const MENU_COLLAPSED_KEY = "search-center:menu:collapsed"; const MENU_COLLAPSED_KEY = "search-center:menu:collapsed";
export default { export default {
namespace: 'global', namespace: "global",
state: { state: {
collapsed: localStorage.getItem(MENU_COLLAPSED_KEY) === 'true', collapsed: localStorage.getItem(MENU_COLLAPSED_KEY) === "true",
isInitCollapsed:false, isInitCollapsed: false,
notices: [], notices: [],
clusterVisible: true, clusterVisible: true,
clusterList: [], clusterList: [],
selectedCluster: {name:"Select cluster", id: ""}, selectedCluster: { name: "Select cluster", id: "" },
selectedClusterID: "", selectedClusterID: "",
search:{ search: {
cluster: { cluster: {},
}
}, },
}, },
@ -29,150 +33,156 @@ export default {
*fetchNotices(_, { call, put }) { *fetchNotices(_, { call, put }) {
const data = yield call(queryNotices); const data = yield call(queryNotices);
yield put({ yield put({
type: 'saveNotices', type: "saveNotices",
payload: data, payload: data,
}); });
yield put({ yield put({
type: 'user/changeNotifyCount', type: "user/changeNotifyCount",
payload: data.length, payload: data.length,
}); });
}, },
*clearNotices({ payload }, { put, select }) { *clearNotices({ payload }, { put, select }) {
yield put({ yield put({
type: 'saveClearedNotices', type: "saveClearedNotices",
payload, payload,
}); });
const count = yield select(state => state.global.notices.length); const count = yield select((state) => state.global.notices.length);
yield put({ yield put({
type: 'user/changeNotifyCount', type: "user/changeNotifyCount",
payload: count, payload: count,
}); });
}, },
*fetchClusterList({payload}, {call, put, select}){ *fetchClusterList({ payload }, { call, put, select }) {
let res = yield call(searchClusterConfig, payload); let res = yield call(searchClusterConfig, payload);
if(res.error){ if (res.error) {
message.error(res.error) message.error(res.error);
return false; return false;
} }
res = formatESSearchResult(res) res = formatESSearchResult(res);
let {clusterList, search} = yield select(state => state.global); let { clusterList, search } = yield select((state) => state.global);
let data = res.data.filter(item=>item.enabled).map((item)=>{ let data = res.data
return { .filter((item) => item.enabled)
name: item.name, .map((item) => {
id: item.id, return {
endpoint: item.endpoint, name: item.name,
host: item.host, id: item.id,
version: item.version, endpoint: item.endpoint,
}; host: item.host,
}) version: item.version,
};
});
if(clusterList.length === 0 && !payload.name){ if (clusterList.length === 0 && !payload.name) {
if(data.length === 0 ){ if (data.length === 0) {
Modal.info({ Modal.info({
title: '系统提示', title: "系统提示",
content: '当前没有可用集群,点击确定将自动跳转到 系统设置=>集群设置', content:
okText: '确定', "当前没有可用集群,点击确定将自动跳转到 系统设置=>集群设置",
okText: "确定",
onOk() { onOk() {
router.push('/system/cluster') router.push("/system/cluster");
}, },
}); });
}else{ } else {
const targetID = extractClusterIDFromURL(); const targetID = extractClusterIDFromURL();
let idx = data.findIndex((item)=>{ let idx = data.findIndex((item) => {
return item.id == targetID; return item.id == targetID;
}); });
idx = idx > -1 ? idx : 0; idx = idx > -1 ? idx : 0;
yield put({ yield put({
type: 'saveData', type: "saveData",
payload:{ payload: {
selectedCluster: data[idx], selectedCluster: data[idx],
selectedClusterID: (data[idx] || {}).id selectedClusterID: (data[idx] || {}).id,
} },
}); });
} }
} }
let newClusterList = []; let newClusterList = [];
if(search.name != payload.name){ if (search.name != payload.name) {
newClusterList = data; newClusterList = data;
}else{ } else {
newClusterList = clusterList.concat(data); newClusterList = clusterList.concat(data);
} }
yield put({ yield put({
type: 'saveData', type: "saveData",
payload: { payload: {
clusterList: newClusterList, clusterList: newClusterList,
clusterTotal: res.total, clusterTotal: res.total,
search: { search: {
...search, ...search,
cluster: payload, cluster: payload,
} },
} },
}) });
return data; return data;
}, },
*reloadClusterList({payload}, {call, put, select}){ *reloadClusterList({ payload }, { call, put, select }) {
yield put({ yield put({
type: 'saveData', type: "saveData",
payload: { payload: {
clusterList: [], clusterList: [],
} },
}); });
yield put({ yield put({
type: 'fetchClusterList', type: "fetchClusterList",
payload: payload payload: payload,
}) });
}, },
*changeClusterState({payload}, {put}){ *changeClusterState({ payload }, { put }) {
yield put({ yield put({
type: 'saveData', type: "saveData",
payload:{ payload: {
...payload, ...payload,
} },
}); });
}, },
*rewriteURL({payload}, {select, put}){ *rewriteURL({ payload }, { select, put }) {
const {pathname, history, search, isChangedState} = payload; const { pathname, history, search, isChangedState } = payload;
const global = yield select(state=>state.global); const global = yield select((state) => state.global);
if(pathname && global.selectedClusterID){ if (pathname && global.selectedClusterID) {
const newPart = `/elasticsearch/${global.selectedClusterID}/`; const newPart = `/elasticsearch/${global.selectedClusterID}/`;
if(!pathname.includes('elasticsearch')){ if (!pathname.includes("elasticsearch")) {
history.replace(pathname+newPart+ (search || '')) history.replace(pathname + newPart + (search || ""));
}else{ } else {
const ms = pathname.match(/\/elasticsearch\/(\w+)\/?/); const ms = pathname.match(/\/elasticsearch\/(\w+)\/?/);
if(ms && ms.length>1 && ms[1] != global.selectedClusterID){ if (ms && ms.length > 1 && ms[1] != global.selectedClusterID) {
if(isChangedState){ if (isChangedState) {
const newPath = pathname.replace(/\/elasticsearch\/(\w+)\/?/, newPart); const newPath = pathname.replace(
history.replace(newPath+(search || '')) /\/elasticsearch\/(\w+)\/?/,
return newPart
);
history.replace(newPath + (search || ""));
return;
} }
yield put({ yield put({
type: 'changeClusterById', type: "changeClusterById",
payload:{ payload: {
id: ms[1] id: ms[1],
} },
}); });
} }
} }
} }
}, },
*fetchClusterStatus({payload}, {call, put, select}){ *fetchClusterStatus({ payload }, { call, put, select }) {
let res = yield call(getClusterStatus, payload); let res = yield call(getClusterStatus, payload);
if(!res){ if (!res) {
return false
}
const {clusterStatus} = yield select(state=>state.global);
if(res.error){
console.log(res.error)
return false; return false;
} }
if(!_.isEqual(res, clusterStatus)){ const { clusterStatus } = yield select((state) => state.global);
if (res.error) {
console.log(res.error);
return false;
}
if (!_.isEqual(res, clusterStatus)) {
yield put({ yield put({
type: 'saveData', type: "saveData",
payload: { payload: {
clusterStatus: res clusterStatus: res,
} },
}); });
} }
return res; return res;
}, },
}, },
@ -180,7 +190,7 @@ export default {
reducers: { reducers: {
changeLayoutCollapsed(state, { payload }) { changeLayoutCollapsed(state, { payload }) {
//layout sider init(false) bug //layout sider init(false) bug
if(!state.isInitCollapsed && state.collapsed){ if (!state.isInitCollapsed && state.collapsed) {
return { return {
...state, ...state,
isInitCollapsed: true, isInitCollapsed: true,
@ -202,53 +212,53 @@ export default {
saveClearedNotices(state, { payload }) { saveClearedNotices(state, { payload }) {
return { return {
...state, ...state,
notices: state.notices.filter(item => item.type !== payload), notices: state.notices.filter((item) => item.type !== payload),
}; };
}, },
saveData(state, {payload}){ saveData(state, { payload }) {
return { return {
...state, ...state,
...payload, ...payload,
} };
}, },
removeCluster(state, {payload}){ removeCluster(state, { payload }) {
let newState = { let newState = {
...state, ...state,
clusterList: state.clusterList.filter(item => item.id !== payload.id) clusterList: state.clusterList.filter((item) => item.id !== payload.id),
} };
if(state.selectedCluster?.id === payload.id){ if (state.selectedCluster?.id === payload.id) {
if(newState.clusterList.length > 0){ if (newState.clusterList.length > 0) {
newState.selectedCluster = newState.clusterList[0]; newState.selectedCluster = newState.clusterList[0];
newState.selectedClusterID = newState.selectedCluster.id; newState.selectedClusterID = newState.selectedCluster.id;
} }
} }
return newState; return newState;
}, },
addCluster(state, {payload}){ addCluster(state, { payload }) {
if(state.clusterList.length === 0){ if (state.clusterList.length === 0) {
state.selectedCluster = payload; state.selectedCluster = payload;
state.selectedClusterID = payload.id; state.selectedClusterID = payload.id;
} }
state.clusterList.push(payload) state.clusterList.push(payload);
return state; return state;
}, },
updateCluster(state, {payload}){ updateCluster(state, { payload }) {
let idx = state.clusterList.findIndex(item => item.id === payload.id); let idx = state.clusterList.findIndex((item) => item.id === payload.id);
idx > -1 && (state.clusterList[idx].name = payload.name); idx > -1 && (state.clusterList[idx].name = payload.name);
return state; return state;
}, },
changeClusterById(state,{payload}){ changeClusterById(state, { payload }) {
let idx = state.clusterList.findIndex(item => item.id === payload.id); let idx = state.clusterList.findIndex((item) => item.id === payload.id);
if(idx > -1){ if (idx > -1) {
return { return {
...state, ...state,
selectedCluster: state.clusterList[idx], selectedCluster: state.clusterList[idx],
selectedClusterID: state.clusterList[idx].id, selectedClusterID: state.clusterList[idx].id,
} };
} }
return state; return state;
} },
}, },
subscriptions: { subscriptions: {
@ -256,40 +266,48 @@ export default {
// Subscribe history(url) change, trigger `load` action if pathname is `/` // Subscribe history(url) change, trigger `load` action if pathname is `/`
return history.listen(({ pathname, search }) => { return history.listen(({ pathname, search }) => {
let clusterVisible = true; let clusterVisible = true;
const clusterHiddenPath = ["/system", "/cluster/overview", "/alerting/overview", "/alerting/monitor/monitors/", "/alerting/destination", '/dev_tool']; const clusterHiddenPath = [
if(clusterHiddenPath.some(p=>pathname.startsWith(p))){ "/system",
"/cluster/overview",
"/alerting/overview",
"/alerting/monitor/monitors/",
"/alerting/destination",
"/dev_tool",
];
if (clusterHiddenPath.some((p) => pathname.startsWith(p))) {
clusterVisible = false; clusterVisible = false;
if(pathname.includes("elasticsearch")){ if (pathname.includes("elasticsearch")) {
dispatch({ dispatch({
type: 'rewriteURL', type: "rewriteURL",
payload: { payload: {
pathname, pathname,
history, history,
search, search,
} },
}); });
} }
}else{ } else {
if(!pathname.startsWith("/exception") && pathname !="/alerting/monitor"){ if (
dispatch({ !pathname.startsWith("/exception") &&
type: 'rewriteURL', pathname != "/alerting/monitor"
payload: { ) {
pathname, dispatch({
history, type: "rewriteURL",
search, payload: {
} pathname,
}) history,
search,
},
});
} }
} }
dispatch({ dispatch({
type: 'saveData', type: "saveData",
payload: { payload: {
clusterVisible, clusterVisible,
} },
}) });
if (typeof window.ga !== 'undefined') { ReactGA.pageview(pathname + search);
window.ga('send', 'pageview', pathname + search);
}
}); });
}, },
}, },

View File

@ -30,6 +30,7 @@
justify-content: center; justify-content: center;
color: red; color: red;
font-size: 20px; font-size: 20px;
z-index: 1;
} }
.metricMask { .metricMask {
filter: blur(4px); filter: blur(4px);

View File

@ -22,6 +22,7 @@ import { formatMessage } from "umi/locale";
import MetricContainer from "./metric_container"; import MetricContainer from "./metric_container";
import _ from "lodash"; import _ from "lodash";
const gorupOrder = ["storage", "operations", "latency", "memory", "cache"];
export default ({ clusterID, timezone, timeRange, handleTimeChange }) => { export default ({ clusterID, timezone, timeRange, handleTimeChange }) => {
const [filter, setFilter] = React.useState({ const [filter, setFilter] = React.useState({
top: "5", top: "5",
@ -108,6 +109,9 @@ export default ({ clusterID, timezone, timeRange, handleTimeChange }) => {
} }
}; };
let refIdx = 0; let refIdx = 0;
if (Object.keys(metrics).length == 0) {
return null;
}
return ( return (
<div id="node-metric"> <div id="node-metric">
@ -140,7 +144,7 @@ export default ({ clusterID, timezone, timeRange, handleTimeChange }) => {
</div> </div>
<div className="px"> <div className="px">
<Skeleton active loading={!value} paragraph={{ rows: 20 }}> <Skeleton active loading={!value} paragraph={{ rows: 20 }}>
{Object.keys(metrics).map((e, i) => { {gorupOrder.map((e, i) => {
return ( return (
<div style={{ margin: "8px 0" }}> <div style={{ margin: "8px 0" }}>
<MetricContainer <MetricContainer

View File

@ -22,6 +22,16 @@ import { formatMessage } from "umi/locale";
import MetricContainer from "./metric_container"; import MetricContainer from "./metric_container";
import _ from "lodash"; import _ from "lodash";
const gorupOrder = [
"system",
"operations",
"latency",
"storage",
"http",
"memory",
"cache",
];
export default ({ clusterID, timezone, timeRange, handleTimeChange }) => { export default ({ clusterID, timezone, timeRange, handleTimeChange }) => {
const [filter, setFilter] = React.useState({ const [filter, setFilter] = React.useState({
top: "5", top: "5",
@ -107,6 +117,9 @@ export default ({ clusterID, timezone, timeRange, handleTimeChange }) => {
}; };
let refIdx = 0; let refIdx = 0;
if (Object.keys(metrics).length == 0) {
return null;
}
return ( return (
<div id="node-metric"> <div id="node-metric">
<div className="px"> <div className="px">
@ -138,7 +151,8 @@ export default ({ clusterID, timezone, timeRange, handleTimeChange }) => {
</div> </div>
<div className="px"> <div className="px">
<Skeleton active loading={!value} paragraph={{ rows: 20 }}> <Skeleton active loading={!value} paragraph={{ rows: 20 }}>
{Object.keys(metrics).map((e, i) => { {//Object.keys(metrics)
gorupOrder.map((e, i) => {
return ( return (
<div style={{ margin: "8px 0" }}> <div style={{ margin: "8px 0" }}>
<MetricContainer <MetricContainer