Browse Source

(*)网关状态指标; 网关操作等

master
wuqun 2 years ago
parent
commit
a9142c5582
  1. 39
      code/web/client/src/sections/edition/actions/index.js
  2. 55
      code/web/client/src/sections/edition/containers/gateway.jsx
  3. 106
      code/web/client/src/sections/edition/containers/gatewayStatusModal.jsx
  4. 6
      code/web/client/src/utils/webapi.js

39
code/web/client/src/sections/edition/actions/index.js

@ -36,8 +36,45 @@ export function ableGateway(id, data) {
});
}
export function gatewaySsh(id) {
return dispatch => basicAction({
type: 'post',
data: null,
dispatch: dispatch,
actionType: 'GATEWAY_SSH',
url: ApiTable.gatewaySsh.replace('{id}', id),
msg: { option: '启动并获取远程SSH-web地址' },
});
}
//重启网关reboot
export function rebootGateway(id) {
return dispatch => basicAction({
type: 'post',
data: null,
dispatch: dispatch,
actionType: 'REBOOT_GATEWAY',
url: ApiTable.rebootGateway.replace('{id}', id),
msg: { option: '重启网关' },
});
}
//重启网关服务restart
export function restartGateway(id) {
return dispatch => basicAction({
type: 'post',
data: null,
dispatch: dispatch,
actionType: 'RESTART_GATEWAY',
url: ApiTable.restartGateway.replace('{id}', id),
msg: { option: '重启网关服务' },
});
}
export default {
getGateways,
getGatewayStatus,
ableGateway
ableGateway,
gatewaySsh,
rebootGateway,
restartGateway
};

55
code/web/client/src/sections/edition/containers/gateway.jsx

@ -2,8 +2,7 @@
import React, { useEffect, useState, useRef } from 'react';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import { Popconfirm, Button, Toast, Skeleton, Table, Tag } from '@douyinfe/semi-ui';
import { IconChevronDown } from '@douyinfe/semi-icons';
import { Popconfirm, Button, Popover, Skeleton, Table, Tag } from '@douyinfe/semi-ui';
import { SkeletonScreen } from "$components";
import GatewayStatusModal from './gatewayStatusModal'
import GatewayEditModal from './gatewayEditModal'
@ -78,7 +77,7 @@ const GatewayManage = props => {
key: "enabled",
render: (text, record) => <span>{text ? '是' : '否'}</span>
}, {
title: "状态详情",
title: "状态指标",
dataIndex: "detail",
key: "detail",
render: (text, record) => <a style={aStyle} onClick={() => {
@ -107,13 +106,57 @@ const GatewayManage = props => {
<a style={{ ...aStyle, marginLeft: 15 }} onClick={() => {
}}>删除</a>
<span style={{ ...aStyle, marginLeft: 15 }} onClick={() => {
}}>更多<IconChevronDown /></span>
<Popover key={Math.random()} content={renderPopover(record)} trigger='click' position='right'>
<a style={{ ...aStyle, marginLeft: 15 }}>更多...</a>
</Popover>
</div>
}
}
];
const renderPopover = (record) => {
return (<div style={{ padding: 12 }}>
<div style={{ ...aStyle, marginBottom: 10 }} onClick={() => {
dispatch(edition.gatewaySsh(record.id)).then(r => {
if (r.success) {
let url = r.payload.data.redirectUrl
//window.open('http://www.baidu.com', '_blank')
}
})
}}>远程控制</div>
<div style={{ ...aStyle, marginBottom: 10 }} onClick={() => {
window.open(`http://${record.serialNo}.edge.yinweiwen.cn`, '_blank')
}}>远程主机</div>
<Popconfirm
title="提示"
content={`确认重启网关系统?`}
onConfirm={() => {
dispatch(edition.rebootGateway(record.id)).then(r => {
if (r.success) {
getTableData(query)
}
})
}}>
<div style={{ ...aStyle, marginBottom: 10 }}>重启系统</div>
</Popconfirm>
<Popconfirm
title="提示"
content={`确认重启网关服务?`}
onConfirm={() => {
dispatch(edition.restartGateway(record.id)).then(r => {
if (r.success) {
getTableData(query)
}
})
}}>
<div style={{ ...aStyle }}>重启应用</div>
</Popconfirm>
</div>)
}
return (
<div style={{}}>
<Skeleton

106
code/web/client/src/sections/edition/containers/gatewayStatusModal.jsx

@ -1,42 +1,104 @@
import React, { useEffect, useRef, useState } from 'react';
import { connect } from "react-redux";
import { Select, Modal, Form, Button } from "@douyinfe/semi-ui";
import { Tag, Modal, Table, Button } from "@douyinfe/semi-ui";
const statusKeys = {
status: '状态',
streamIn: '流入',
streamOut: '流出',
memUsedPercent: '内存使用',
diskPercent: '磁盘使用',
timeDiff: '时间偏差(最新心跳 服务器时间-设备时间)',
uptime: '本次在线时长',
sys: '系统',//+
programVersion: '软件信息',//
devConfVersion: '配置版本',
acqConfVersion: '采集参数版本',
pluginVersion: '插件版本',
load1: 'Load1',
load5: 'Load5',
load15: 'Load15',
}
const GatewayStatusModal = (props) => {
const { dispatch, actions, user, onCancel, dataToModal } = props;
const { edition } = actions;
const [listData, setListData] = useState(null);
const [listData, setListData] = useState([]);
//
useEffect(() => {
dispatch(edition.getGatewayStatus(dataToModal.id)).then(res => {//
if (res.success) {
setListData(res.payload.data)
//let a = formatDuring(172890)
let tableData = Object.keys(statusKeys).map(k => {
let value = k == 'sys' ? res.payload.data.platform + '-拼接-' + res.payload.data.sysVersion : res.payload.data[k]
return { label: statusKeys[k], value }
})
setListData(tableData)
}
})
}, []);
const statusKeys = {
status: '状态',
streamIn: '流入',
streamOut: '流出',
memUsedPercent: '内存使用',
diskPercent: '磁盘使用',
timeDiff: '时间偏差(最新心跳 服务器时间-设备时间)',
uptime: '本次在线时常',//???
sysVersion: '系统',
status: '软件信息',//???
status: '配置版本',//???
acqConfVersion: '采集参数版本',//???
pluginVersion: '插件版本',
load1: 'Load1',
load5: 'Load5',
load15: 'Load15',
const getFileSize = (size) => {
if (!size && parseInt(size) != 0)
return "0K";
var num = 1024.00; //byte
if (size < num)
return size + "B";
if (size < Math.pow(num, 2))
return (size / num).toFixed(2) + "KB"; //kb
if (size < Math.pow(num, 3))
return (size / Math.pow(num, 2)).toFixed(2) + "M"; //M
if (size < Math.pow(num, 4))
return (size / Math.pow(num, 3)).toFixed(2) + "G"; //G
return (size / Math.pow(num, 4)).toFixed(2) + "T"; //T
}
const formatDuring = (mss) => {
var days = parseInt(mss / (60 * 60 * 24));
var hours = parseInt((mss % (60 * 60 * 24)) / (60 * 60));
var minutes = parseInt((mss % (60 * 60)) / (60));
var seconds = ((mss % 60)).toFixed(0);
return days + " 天 " + hours + " 小时 " + minutes + " 分钟 " + seconds + " 秒 ";
}
const columns = [{
title: '属性',
dataIndex: 'label',
key: 'label',
width: '60%'
}, {
title: '状态值',
dataIndex: 'value',
key: 'value',
width: '40%',
render: (text, record) => {
if (record.label == '状态') {
return text ? <Tag color='green'>在线</Tag> : <Tag color='grey'>离线</Tag>
} else if (['流入', '流出'].indexOf(record.label) != -1) {
return <span>{getFileSize(text)}</span>
} else if (record.label.indexOf('使用') != -1) {
return <span>{`${text}%`}</span>
} else if (record.label.indexOf('时间偏差') != -1) {
return <span>{`${text}ms`}</span>
} else if (record.label.indexOf('时长') != -1) {
return <span>{formatDuring(text)}</span>
} else {
return text
}
}
return (
<Modal title={dataToModal.name}
}]
return (<Modal title={'状态指标详情'} width={600} closable={true}
visible={true} destroyOnClose onCancel={onCancel}
footer={[<Button onClick={onCancel}>关闭</Button>]}>
<div></div>
<div style={{ fontSize: 15, fontWeight: 'bold', marginBottom: 20 }}>{`序号:${dataToModal.serialNo}`}&nbsp;&nbsp;&nbsp;&nbsp;{`名称:${dataToModal.name}`}</div>
<Table
size='small'
columns={columns}
dataSource={listData}
bordered={false}
empty="暂无数据"
pagination={false}
/>
</Modal>
)
}

6
code/web/client/src/utils/webapi.js

@ -7,7 +7,11 @@ export const ApiTable = {
crossCheck: 'cross_token/check',
getGateways: 'v1/edges',
ableGateway: 'v1/edge/{id}/enable',
getGatewayStatus: 'v1/edge/{id}/metrics'
getGatewayStatus: 'v1/edge/{id}/metrics',
gatewaySsh: 'v1/edge/{id}/ssh',
rebootGateway: 'v1/edge/{id}/reboot',
restartGateway: 'v1/edge/{id}/restart',
};
export const RouteTable = {

Loading…
Cancel
Save