From 62386f98d81f8e212bc439268d075efb4406810d Mon Sep 17 00:00:00 2001 From: vapao Date: Sun, 13 Sep 2020 08:44:05 +0800 Subject: [PATCH] =?UTF-8?q?A=20=E7=9B=91=E6=8E=A7=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E6=96=B0=E5=A2=9EPing=E6=A3=80=E6=B5=8B=20#195?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spug_api/apps/monitor/executors.py | 20 ++++ spug_api/apps/monitor/models.py | 1 + spug_api/apps/monitor/scheduler.py | 6 +- spug_api/apps/schedule/scheduler.py | 2 +- spug_web/src/pages/monitor/Form.js | 163 +++++++++++++++++----------- spug_web/src/pages/monitor/Table.js | 5 - 6 files changed, 123 insertions(+), 74 deletions(-) diff --git a/spug_api/apps/monitor/executors.py b/spug_api/apps/monitor/executors.py index 14f2eea..f526973 100644 --- a/spug_api/apps/monitor/executors.py +++ b/spug_api/apps/monitor/executors.py @@ -3,6 +3,8 @@ # Released under the AGPL-3.0 License. from apps.host.models import Host from socket import socket +import subprocess +import platform import requests import logging @@ -22,11 +24,27 @@ def port_check(addr, port): sock = socket() sock.settimeout(5) sock.connect((addr, int(port))) + sock.close() return True, '端口状态检测正常' except Exception as e: return False, f'异常信息:{e}' +def ping_check(addr): + try: + if platform.system().lower() == 'windows': + command = f'ping -n 1 -w 3000 {addr}' + else: + command = f'ping -c 1 -t 3 {addr}' + task = subprocess.run(command, shell=True, stdout=subprocess.PIPE) + if task.returncode == 0: + return True, 'Ping检测正常' + else: + return False, 'Ping检测失败' + except Exception as e: + return False, f'异常信息:{e}' + + def host_executor(host, command): try: cli = host.get_ssh() @@ -44,6 +62,8 @@ def dispatch(tp, addr, extra): return site_check(addr) elif tp == '2': return port_check(addr, extra) + elif tp == '5': + return ping_check(addr) elif tp == '3': command = f'ps -ef|grep -v grep|grep {extra!r}' elif tp == '4': diff --git a/spug_api/apps/monitor/models.py b/spug_api/apps/monitor/models.py index ecfc9fe..97f8824 100644 --- a/spug_api/apps/monitor/models.py +++ b/spug_api/apps/monitor/models.py @@ -13,6 +13,7 @@ class Detection(models.Model, ModelMixin): ('2', '端口检测'), ('3', '进程检测'), ('4', '自定义脚本'), + ('5', 'Ping检测'), ) STATUS = ( (0, '成功'), diff --git a/spug_api/apps/monitor/scheduler.py b/spug_api/apps/monitor/scheduler.py index 99a29c2..64606b7 100644 --- a/spug_api/apps/monitor/scheduler.py +++ b/spug_api/apps/monitor/scheduler.py @@ -27,7 +27,7 @@ class Scheduler: timezone = settings.TIME_ZONE def __init__(self): - self.scheduler = BackgroundScheduler(timezone=self.timezone, executors={'default': ThreadPoolExecutor(20)}) + self.scheduler = BackgroundScheduler(timezone=self.timezone, executors={'default': ThreadPoolExecutor(30)}) self.scheduler.add_listener( self._handle_event, EVENT_SCHEDULER_SHUTDOWN | EVENT_JOB_ERROR | EVENT_JOB_MAX_INSTANCES | EVENT_JOB_EXECUTED) @@ -61,7 +61,7 @@ class Scheduler: if obj.latest_status == 0: if is_notified: self._record_alarm(obj, '2') - logger.info(f'{human_datetime()} recover job_id: {obj.id}') + logger.info(f'{human_datetime()} recover job_id: {obj.id}, job_name: {obj.name}') self._do_notify('2', obj, out) else: if obj.fault_times >= obj.threshold: @@ -69,7 +69,7 @@ class Scheduler: obj.latest_notify_time = int(time.time()) obj.save() self._record_alarm(obj, '1') - logger.info(f'{human_datetime()} notify job_id: {obj.id}') + logger.info(f'{human_datetime()} notify job_id: {obj.id}, job_name: {obj.name}') self._do_notify('1', obj, out) def _handle_event(self, event): diff --git a/spug_api/apps/schedule/scheduler.py b/spug_api/apps/schedule/scheduler.py index 96f6cdb..319792c 100644 --- a/spug_api/apps/schedule/scheduler.py +++ b/spug_api/apps/schedule/scheduler.py @@ -39,7 +39,7 @@ class Scheduler: } def __init__(self): - self.scheduler = BackgroundScheduler(timezone=self.timezone, executors={'default': ThreadPoolExecutor(20)}) + self.scheduler = BackgroundScheduler(timezone=self.timezone, executors={'default': ThreadPoolExecutor(30)}) self.scheduler.add_listener( self._handle_event, EVENT_SCHEDULER_SHUTDOWN | EVENT_JOB_ERROR | EVENT_JOB_MAX_INSTANCES | EVENT_JOB_EXECUTED) diff --git a/spug_web/src/pages/monitor/Form.js b/spug_web/src/pages/monitor/Form.js index 2561a31..f091b69 100644 --- a/spug_web/src/pages/monitor/Form.js +++ b/spug_web/src/pages/monitor/Form.js @@ -13,56 +13,98 @@ import store from './store'; import hostStore from '../host/store'; import groupStore from '../alarm/group/store'; import styles from './index.module.css'; +import lds from 'lodash'; @observer class ComForm extends React.Component { constructor(props) { super(props); + this.fieldMap = { + '1': ['domain'], + '2': ['addr', 'port'], + '3': ['host', 'process'], + '4': ['host', 'command'], + '5': ['addr'], + } + this.modeOptions = [ + {label: '微信', 'value': '1'}, + {label: '短信', 'value': '2', disabled: true}, + {label: '钉钉', 'value': '3'}, + {label: '邮件', 'value': '4'}, + {label: '企业微信', 'value': '5'}, + ] + this.helpMap = { + '1': '返回HTTP状态码200-399则判定为正常,其他为异常。', + '4': '脚本执行退出状态码为 0 则判定为正常,其他为异常。' + } this.state = { loading: false, sitePrefix: 'http://', - extra: {[store.record.type]: store.record.extra}, - addr: {}, + domain: undefined, + addr: undefined, + port: undefined, + host: undefined, + process: undefined, + command: undefined, showTmp: false, page: 0, - modeOptions: [ - {label: '微信', 'value': '1'}, - {label: '短信', 'value': '2', disabled: true}, - {label: '钉钉', 'value': '3'}, - {label: '邮件', 'value': '4'}, - {label: '企业微信', 'value': '5'}, - ], - helpMap: { - '1': '返回HTTP状态码200-399则判定为正常,其他为异常。', - '4': '脚本执行退出状态码为 0 则判定为正常,其他为异常。' - } } } componentDidMount() { - let [sitePrefix, value] = ['http://', '']; - if (store.record.type === '1') { - if (store.record.addr.includes('http://')) { - value = store.record.addr.replace('http://', '') - } else { - sitePrefix = 'https://'; - value = store.record.addr.replace('https://', '') - } - this.setState({sitePrefix, addr: {'1': value}}) - } else if ('34'.includes(store.record.type)) { - this.setState({addr: {'3': store.record.addr, '4': store.record.addr}}) - } else { - this.setState({addr: {[store.record.type]: store.record.addr}}) + const {type, addr, extra} = store.record; + switch (type) { + case '1': + if (addr.startsWith('http://')) { + this.setState({sitePrefix: 'http://', domain: addr.replace('http://', '')}) + } else { + this.setState({sitePrefix: 'https://', domain: addr.replace('https://', '')}) + } + break; + case '2': + this.setState({addr, port: extra}); + break; + case '3': + this.setState({host: addr, process: extra}); + break; + case '4': + this.setState({host: addr, command: extra}); + break; + case '5': + this.setState({addr}); + break; + default: } } handleSubmit = () => { this.setState({loading: true}); + const {sitePrefix, domain, addr, host, port, command, process} = this.state; const formData = this.props.form.getFieldsValue(); const type = formData['type']; formData['id'] = store.record.id; - formData['extra'] = this.state.extra[type]; - formData['addr'] = type === '1' ? this.state.sitePrefix + this.state.addr[type] : this.state.addr[type]; + switch (type) { + case '1': + formData['addr'] = sitePrefix + domain; + break; + case '2': + formData['addr'] = addr; + formData['extra'] = port; + break; + case '3': + formData['addr'] = host; + formData['extra'] = process + break; + case '4': + formData['addr'] = host; + formData['extra'] = command; + break; + case '5': + formData['addr'] = addr; + break; + default: + throw Error('unknown type') + } http.post('/api/monitor/', formData) .then(() => { message.success('操作成功'); @@ -73,21 +115,12 @@ class ComForm extends React.Component { getStyle = (t) => { const type = this.props.form.getFieldValue('type'); - return t.indexOf(type) !== -1 ? {display: 'block'} : {display: 'none'} + return this.fieldMap[type].includes(t) ? {display: 'block'} : {display: 'none'} }; - handleExtra = (t, e) => { - const value = t === '4' ? e : e.target.value; - this.setState({extra: Object.assign({}, this.state.extra, {[t]: value})}) - }; - - handleAddr = (t, e) => { - if (t === '3') { - this.setState({addr: Object.assign({}, this.state.addr, {'3': e, '4': e})}) - } else { - this.setState({addr: Object.assign({}, this.state.addr, {[t]: e.target.value})}) - } - }; + handleInput = (key, value) => { + this.setState({[key]: value}) + } siteBefore = () => ( 站点检测 端口检测 + Ping检测 进程检测 自定义脚本 @@ -141,45 +173,46 @@ class ComForm extends React.Component { )} - - this.handleAddr('1', e)}/> + + this.handleInput('domain', e.target.value)}/> - - this.handleAddr('2', e)}/> + + this.handleInput('addr', e.target.value)}/> - + - - this.handleExtra('2', e)}/> + + this.handleInput('port', e.target.value)}/> - - this.handleExtra('3', e)}/> + + this.handleInput('process', e.target.value)}/> this.setState({showTmp: true})}>从模板添加}> this.handleExtra('4', cleanCommand(e))}/> + onChange={e => this.handleInput('command', cleanCommand(e))}/> {getFieldDecorator('desc', {initialValue: info['desc']})( @@ -223,7 +256,7 @@ class ComForm extends React.Component { {getFieldDecorator('notify_mode', {initialValue: info['notify_mode']})( - + )} @@ -252,7 +285,7 @@ class ComForm extends React.Component { {showTmp && this.handleExtra('4', extra['4'] + v)} + onOk={v => this.handleInput('command', command + v)} onCancel={() => this.setState({showTmp: false})}/>} ) diff --git a/spug_web/src/pages/monitor/Table.js b/spug_web/src/pages/monitor/Table.js index 9c69de4..76162af 100644 --- a/spug_web/src/pages/monitor/Table.js +++ b/spug_web/src/pages/monitor/Table.js @@ -42,11 +42,6 @@ class ComTable extends React.Component { }; columns = [{ - title: '序号', - key: 'series', - render: (_, __, index) => index + 1, - width: 80 - }, { title: '任务名称', dataIndex: 'name', }, {