189 lines
5.9 KiB
PHP
Raw Normal View History

2024-08-31 01:03:37 +08:00
<?php
class msgWarningTaskIndex extends Controller {
public function __construct() {
parent::__construct();
$this->pluginName = 'msgWarningPlugin';
}
public function getConfig() {
if (!$this->appConfig) {
$this->appConfig = Action($this->pluginName)->getConfig();
}
return $this->appConfig;
}
// 更新同步计划任务
public function updateTask($status){
// 任务不存在状态为0返回否则新增
if(!$task = $this->getTask()) {
return $this->addTask($status);
}
// 任务已存在:更新
$data = array(
'name' => $task['name'],
'enable' => $status
);
Model('SystemTask')->update($task['id'], $data);
}
private function addTask($status){
$data = array (
'name' => LNG('msgWarning.main.taskTitle'),
'type' => 'method',
'event' => $this->pluginName.'.warning',
'time' => '{"type":"minute","month":"1","week":"1","day":"08:00","minute":"1"}',
'desc' => LNG('msgWarning.main.taskDesc'),
'enable' => $status,
'system' => 1,
);
return Model('SystemTask')->add($data);
}
// 获取计划任务通过id查找有问题卸载时可能没有删除导致无法查找也无法新增
public function getTask(){
$event = $this->pluginName.'.warning';
return Model('SystemTask')->findByKey('event', $event);
}
// 删除计划任务
public function delTask(){
if(!$task = $this->getTask()) return;
Model('SystemTask')->remove($task['id'], true);
}
/**
* 获取异常信息并发送
* @return void
*/
public function warning() {
$config = $this->getConfig();
// 1.是否开启了消息预警
if($config['enable'] != '1') return;
// 2.获取发送目标
$target = array_filter(explode(',', $config['target']));
if (empty($target)) return;
// 3.获取cpu、内存等使用信息并写入记录
// 读取mem、cpu的值存入日志删除指定时长之前的日志取剩余日志量比如时长为20分钟理论上会存20条日志只要达到80%——16条就发送提醒占用很高时99%)直接发送(废弃)
$server = new ServerInfo();
$warnType = explode(',', $config['warnType']);
$data = array();
// 3.1 内存
$type = 'mem';
if (in_array($type, $warnType)) {
$memUsage = $server->memUsage(); // [total=>1024,used=>24]
$memValue = $memUsage['total'] > 0 ? round($memUsage['used']/$memUsage['total'], 3) : 0;
if($memValue && $memValue > floatval($config['useRatio'] / 100)) {
$rest = $this->warnUsage($type, array('value' => $memValue, 'data' => $memUsage));
if (!$rest) $data[$type] = $memValue;
}
}
// 3.2 cpu
$type = 'cpu';
if (in_array($type, $warnType)) {
$cpuUsage = $server->cpuUsage(); // 0.23
if($cpuUsage && $cpuUsage > floatval($config['useRatio'] / 100)) {
$rest = $this->warnUsage($type, array('value' => $cpuUsage));
if (!$rest) $data[$type] = $cpuUsage;
}
}
// 内容不为空,获取系统消息
if (empty($data)) return;
// 4.拼接消息
$text = LNG('msgWarning.main.msgSysErr');
$base = array();
if (isset($data['mem'])) {
$ratio = ($data['mem']*100).'%';
$base[] = sprintf($text, $config['useTime'], LNG('msgWarning.main.memory'), $config['useRatio'].'%', $ratio);
}
if (isset($data['cpu'])) {
$ratio = ($data['cpu']*100).'%';
$base[] = sprintf($text, $config['useTime'], 'CPU', $config['useRatio'].'%', $ratio);
}
// 获取系统消息,合并,发送
$msg = Action($this->pluginName)->message(true);
if (!$msg) $msg = array();
$msg['base'] = $base;
// 返回执行结果写入计划任务日志。可在前端tools/table.log加入详情展示结果暂不处理
$result = Action($this->pluginName . '.msg.index')->send($msg, $target);
$result['user'] = $target;
return $result;
}
/**
* 记录cpu、内存异常信息
* @param [type] $type
* @param [type] $data
* @return void true:不发送false:发送
*/
private function warnUsage($type, $data) {
Model('SystemWarn')->init($type);
$config = $this->getConfig();
// 1.写入一条记录——超过99%的不写,且删除已有数据,直接发送(废弃)
// if ($data['value'] > 0.99) {
// $useTime = 0;
// } else {
$insert = array(
'value' => $data['value'],
'content' => !empty($data['data']) ? $data['data'] : ''
);
$data = Model('SystemWarn')->add($insert);
$useTime = intval($config['useTime']);
// }
// 2.获取记录列表,删除指定时长之前的数据
$list = Model('SystemWarn')->listData();
$time = time() - 60 * $useTime;
foreach($list as $k => $item) {
$crtTime = intval($item['createTime']);
if(!$useTime || $crtTime < $time) {
Model('SystemWarn')->remove($item['id']);
unset($list[$k]);
}
}
// 3.判断是否符合发送提醒条件——持续的n分钟里如20分钟理论上有20条记录只要达到80%>=16条就发送提醒
if (!$useTime) return false;
$cnt = $useTime * 0.8;
if(count($list) >= $cnt) {
// 时间间隔需满足20分钟避免每次都有数据写入时提前16分钟触发
$max = reset($list);
$min = end($list);
$time = ceil(($max['createTime'] - $min['createTime'])/60);
if ($time < $useTime) return true;
// 每发送一次,删除此前的全部记录。持续时长=发送频率
foreach($list as $k => $item) {
Model('SystemWarn')->remove($item['id']);
}
return false;
}
return true;
}
}
/**
* mem、cpu记录
*/
class SystemWarnModel extends ModelBaseLight{
public $optionType = '';
public $modelType = "SystemOption";
public $field = array('value','content'); //数据字段
public function init($type){
$this->optionType = 'System.'.$type.'WarnList'; // cpu、mem
}
//默认正序
public function listData($id=false,$sort='modifyTime',$sortDesc=true){
return parent::listData($id,$sort,$sortDesc);
}
public function remove($id){
return parent::remove($id);
}
public function add($data){
return parent::insert($data);
}
}