mirror of https://github.com/openspug/spug
A 监控中心 增加分组
parent
8bf264bcd2
commit
d11ee1258d
|
@ -21,6 +21,7 @@ class Detection(models.Model, ModelMixin):
|
|||
)
|
||||
name = models.CharField(max_length=50)
|
||||
type = models.CharField(max_length=2, choices=TYPES)
|
||||
group = models.CharField(max_length=255, null=True)
|
||||
addr = models.CharField(max_length=255)
|
||||
extra = models.TextField(null=True)
|
||||
desc = models.CharField(max_length=255, null=True)
|
||||
|
|
|
@ -13,12 +13,14 @@ import json
|
|||
class DetectionView(View):
|
||||
def get(self, request):
|
||||
detections = Detection.objects.all()
|
||||
return json_response(detections)
|
||||
groups = [x['group'] for x in detections.order_by('group').values('group').distinct()]
|
||||
return json_response({'groups': groups, 'detections': [x.to_dict() for x in detections]})
|
||||
|
||||
def post(self, request):
|
||||
form, error = JsonParser(
|
||||
Argument('id', type=int, required=False),
|
||||
Argument('name', help='请输入任务名称'),
|
||||
Argument('group', help='请选择任务分组'),
|
||||
Argument('addr', help='请输入监控地址'),
|
||||
Argument('type', filter=lambda x: x in dict(Detection.TYPES), help='请选择监控类型'),
|
||||
Argument('extra', required=False),
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
/.idea/
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons';
|
||||
import { Modal, Form, Input, Select, Button } from 'antd';
|
||||
import TemplateSelector from '../exec/task/TemplateSelector';
|
||||
import { LinkButton, ACEditor } from 'components';
|
||||
|
@ -22,7 +23,7 @@ export default observer(function () {
|
|||
const [showTmp, setShowTmp] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const {type, addr} = store.record;
|
||||
const { type, addr } = store.record;
|
||||
if (type === '1' && addr) {
|
||||
store.record.sitePrefix = addr.startsWith('http://') ? 'http://' : 'https://';
|
||||
store.record.domain = store.record.addr.replace(store.record.sitePrefix, '')
|
||||
|
@ -31,14 +32,14 @@ export default observer(function () {
|
|||
|
||||
function handleTest() {
|
||||
setLoading(true)
|
||||
const {type, sitePrefix, domain} = store.record;
|
||||
const { type, sitePrefix, domain } = store.record;
|
||||
if (type === '1') store.record.addr = sitePrefix + domain;
|
||||
http.post('/api/monitor/test/', store.record, {timeout: 120000})
|
||||
http.post('/api/monitor/test/', store.record, { timeout: 120000 })
|
||||
.then(res => {
|
||||
if (res.is_success) {
|
||||
Modal.success({content: res.message})
|
||||
Modal.success({ content: res.message })
|
||||
} else {
|
||||
Modal.warning({content: res.message})
|
||||
Modal.warning({ content: res.message })
|
||||
}
|
||||
})
|
||||
.finally(() => setLoading(false))
|
||||
|
@ -48,39 +49,59 @@ export default observer(function () {
|
|||
store.record.type = v;
|
||||
store.record.addr = undefined;
|
||||
store.record.extra = undefined;
|
||||
};
|
||||
|
||||
function handleAddGroup() {
|
||||
Modal.confirm({
|
||||
icon: <ExclamationCircleOutlined />,
|
||||
title: '添加监控分组',
|
||||
content: (
|
||||
<Form layout="vertical" style={{ marginTop: 24 }}>
|
||||
<Form.Item required label="监控分组">
|
||||
<Input onChange={e => store.record.group = e.target.value} />
|
||||
|
||||
</Form.Item>
|
||||
</Form>
|
||||
),
|
||||
onOk: () => {
|
||||
if (store.record.group) {
|
||||
store.groups.push(store.record.group);
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const SiteBefore = (
|
||||
<Select style={{width: 90}} value={store.record.sitePrefix} onChange={v => store.record.sitePrefix = v}>
|
||||
<Select style={{ width: 90 }} value={store.record.sitePrefix} onChange={v => store.record.sitePrefix = v}>
|
||||
<Select.Option value="http://">http://</Select.Option>
|
||||
<Select.Option value="https://">https://</Select.Option>
|
||||
</Select>
|
||||
)
|
||||
|
||||
function canNext() {
|
||||
const {type, addr, extra, domain} = store.record;
|
||||
const { type, addr, extra, domain, group } = store.record;
|
||||
if (type === '1') {
|
||||
return name && domain
|
||||
return name && domain && group
|
||||
} else if (type === '5') {
|
||||
return name && addr
|
||||
return name && addr && group
|
||||
} else {
|
||||
return name && addr && extra
|
||||
return name && addr && extra && group
|
||||
}
|
||||
}
|
||||
|
||||
function toNext() {
|
||||
store.page += 1;
|
||||
const {type, sitePrefix, domain} = store.record;
|
||||
const { type, sitePrefix, domain } = store.record;
|
||||
if (type === '1') store.record.addr = sitePrefix + domain;
|
||||
}
|
||||
|
||||
function getStyle(t) {
|
||||
return t.includes(store.record.type) ? {display: 'flex'} : {display: 'none'}
|
||||
return t.includes(store.record.type) ? { display: 'flex' } : { display: 'none' }
|
||||
}
|
||||
|
||||
const {name, desc, type, addr, extra, domain} = store.record;
|
||||
const { name, desc, type, addr, extra, domain, group } = store.record;
|
||||
return (
|
||||
<Form labelCol={{span: 6}} wrapperCol={{span: 14}}>
|
||||
<Form labelCol={{ span: 6 }} wrapperCol={{ span: 14 }}>
|
||||
<Form.Item label="监控类型" help={helpMap[type]}>
|
||||
<Select placeholder="请选择监控类型" value={type} onChange={handleChangeType}>
|
||||
<Select.Option value="1">站点检测</Select.Option>
|
||||
|
@ -90,18 +111,30 @@ export default observer(function () {
|
|||
<Select.Option value="4">自定义脚本</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item required label="任务名称">
|
||||
<Input value={name} onChange={e => store.record.name = e.target.value} placeholder="请输入任务名称"/>
|
||||
<Form.Item required label="监控分组" style={{ marginBottom: 0 }}>
|
||||
<Form.Item style={{ display: 'inline-block', width: 'calc(75%)', marginRight: 8 }}>
|
||||
<Select value={group} placeholder="请选择监控分组" onChange={v => store.record.group = v}>
|
||||
{store.groups.map(item => (
|
||||
<Select.Option value={item} key={item}>{item}</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item style={{ display: 'inline-block', width: 'calc(25%-8px)' }}>
|
||||
<Button type="link" onClick={handleAddGroup}>添加分组</Button>
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
<Form.Item required label="监控名称">
|
||||
<Input value={name} onChange={e => store.record.name = e.target.value} placeholder="请输入监控名称" />
|
||||
</Form.Item>
|
||||
<Form.Item required label="监控地址" style={getStyle(['1'])}>
|
||||
<Input
|
||||
value={domain}
|
||||
addonBefore={SiteBefore}
|
||||
placeholder="请输入监控地址"
|
||||
onChange={e => store.record.domain = e.target.value}/>
|
||||
onChange={e => store.record.domain = e.target.value} />
|
||||
</Form.Item>
|
||||
<Form.Item required label="监控地址" style={getStyle(['2', '5'])}>
|
||||
<Input value={addr} placeholder="请输入监控地址(IP/域名)" onChange={e => store.record.addr = e.target.value}/>
|
||||
<Input value={addr} placeholder="请输入监控地址(IP/域名)" onChange={e => store.record.addr = e.target.value} />
|
||||
</Form.Item>
|
||||
<Form.Item required label="监控主机" style={getStyle(['3', '4'])}>
|
||||
<Select
|
||||
|
@ -119,10 +152,10 @@ export default observer(function () {
|
|||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item required label="检测端口" style={getStyle(['2'])}>
|
||||
<Input value={extra} placeholder="请输入端口号" onChange={e => store.record.extra = e.target.value}/>
|
||||
<Input value={extra} placeholder="请输入端口号" onChange={e => store.record.extra = e.target.value} />
|
||||
</Form.Item>
|
||||
<Form.Item required label="进程名称" help="执行 ps -ef 看到的进程名称。" style={getStyle(['3'])}>
|
||||
<Input value={extra} placeholder="请输入进程名称" onChange={e => store.record.extra = e.target.value}/>
|
||||
<Input value={extra} placeholder="请输入进程名称" onChange={e => store.record.extra = e.target.value} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
required
|
||||
|
@ -134,17 +167,17 @@ export default observer(function () {
|
|||
value={extra || ''}
|
||||
width="100%"
|
||||
height="200px"
|
||||
onChange={e => store.record.extra = cleanCommand(e)}/>
|
||||
onChange={e => store.record.extra = cleanCommand(e)} />
|
||||
</Form.Item>
|
||||
<Form.Item label="备注信息">
|
||||
<Input.TextArea value={desc} onChange={e => store.record.desc = e.target.value} placeholder="请输入备注信息"/>
|
||||
<Input.TextArea value={desc} onChange={e => store.record.desc = e.target.value} placeholder="请输入备注信息" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item wrapperCol={{span: 14, offset: 6}} style={{marginTop: 12}}>
|
||||
<Form.Item wrapperCol={{ span: 14, offset: 6 }} style={{ marginTop: 12 }}>
|
||||
<Button disabled={!canNext()} type="primary" onClick={toNext}>下一步</Button>
|
||||
<Button disabled={false} type="link" loading={loading} onClick={handleTest}>执行测试</Button>
|
||||
</Form.Item>
|
||||
{showTmp && <TemplateSelector onOk={v => store.record.extra += v} onCancel={() => setShowTmp(false)}/>}
|
||||
{showTmp && <TemplateSelector onOk={v => store.record.extra += v} onCancel={() => setShowTmp(false)} />}
|
||||
</Form>
|
||||
)
|
||||
})
|
|
@ -34,7 +34,7 @@ export default observer(function () {
|
|||
function handleSubmit() {
|
||||
setLoading(true)
|
||||
const formData = form.getFieldsValue();
|
||||
Object.assign(formData, lds.pick(store.record, ['id', 'name', 'desc', 'addr', 'extra', 'type']))
|
||||
Object.assign(formData, lds.pick(store.record, ['id', 'name', 'desc', 'addr', 'extra', 'type', 'group']))
|
||||
formData['id'] = store.record.id;
|
||||
http.post('/api/monitor/', formData)
|
||||
.then(() => {
|
||||
|
|
|
@ -96,7 +96,8 @@ class ComTable extends React.Component {
|
|||
showTotal: total => `共 ${total} 条`,
|
||||
pageSizeOptions: ['10', '20', '50', '100']
|
||||
}}>
|
||||
<Table.Column title="任务名称" dataIndex="name"/>
|
||||
<Table.Column title="监控分组" dataIndex="group" />
|
||||
<Table.Column title="监控名称" dataIndex="name"/>
|
||||
<Table.Column title="类型" dataIndex="type_alias"/>
|
||||
<Table.Column ellipsis title="地址" render={info => {
|
||||
if ('34'.includes(info.type)) {
|
||||
|
|
|
@ -19,7 +19,14 @@ export default observer(function () {
|
|||
<Breadcrumb.Item>监控中心</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
<SearchForm>
|
||||
<SearchForm.Item span={7} title="任务名称">
|
||||
<SearchForm.Item span={7} title="监控分组">
|
||||
<Select allowClear value={store.f_group} onChange={v => store.f_group = v} placeholder="请选择">
|
||||
{store.groups.map(item => (
|
||||
<Select.Option value={item} key={item}>{item}</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
</SearchForm.Item>
|
||||
<SearchForm.Item span={7} title="监控名称">
|
||||
<Input allowClear value={store.f_name} onChange={e => store.f_name = e.target.value} placeholder="请输入"/>
|
||||
</SearchForm.Item>
|
||||
<SearchForm.Item span={7} title="检测类型">
|
||||
|
|
|
@ -12,6 +12,7 @@ class Store {
|
|||
@observable records = [];
|
||||
@observable record = {};
|
||||
@observable types = [];
|
||||
@observable groups = [];
|
||||
@observable page = 0;
|
||||
@observable isFetching = false;
|
||||
@observable formVisible = false;
|
||||
|
@ -20,12 +21,14 @@ class Store {
|
|||
@observable f_type;
|
||||
@observable f_status;
|
||||
@observable f_active = '';
|
||||
@observable f_group;
|
||||
|
||||
@computed get dataSource() {
|
||||
let records = this.records;
|
||||
if (this.f_active) records = records.filter(x => x.is_active === (this.f_active === '1'));
|
||||
if (this.f_name) records = records.filter(x => x.name.toLowerCase().includes(this.f_name.toLowerCase()));
|
||||
if (this.f_type) records = records.filter(x => x.type_alias === this.f_type);
|
||||
if (this.f_group) records = records.filter(x => x.group === this.f_group);
|
||||
if (this.f_status !== undefined) {
|
||||
if (this.f_status === -1) {
|
||||
records = records.filter(x => x.is_active && !x.latest_status_alias);
|
||||
|
@ -39,16 +42,17 @@ class Store {
|
|||
fetchRecords = () => {
|
||||
this.isFetching = true;
|
||||
http.get('/api/monitor/')
|
||||
.then(res => {
|
||||
.then(({groups, detections}) => {
|
||||
const tmp = new Set();
|
||||
res.map(item => {
|
||||
detections.map(item => {
|
||||
tmp.add(item['type_alias']);
|
||||
const value = item['latest_run_time'];
|
||||
item['latest_run_time_alias'] = value ? moment(value).fromNow() : null;
|
||||
return null
|
||||
});
|
||||
this.types = Array.from(tmp);
|
||||
this.records = res
|
||||
this.records = detections;
|
||||
this.groups = groups;
|
||||
})
|
||||
.finally(() => this.isFetching = false)
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue