401,"msg"=>"未登录,请前往登录页面"], JSON_UNESCAPED_UNICODE); exit; } // 统一数据库配置 $dbHost = "10.150.117.190"; $dbUser = "root"; $dbPass = "hp93000"; $dbName = "alert_mail_stat"; // 统一数据库连接函数 function getDbConn() { global $dbHost, $dbUser, $dbPass, $dbName; $conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName); mysqli_set_charset($conn, "utf8mb4"); return $conn; } // CSV导出接口(独立流式下载,不输出JSON头) if ($act === "export_csv") { $conn = getDbConn(); if (!$conn) { header("Content-Type:text/html;charset=utf-8"); echo "数据库连接失败:" . mysqli_connect_error(); exit; } $today = date("Y-m-d"); $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,receive_time FROM alert_log WHERE DATE(receive_time) = '$today' ORDER BY receive_time DESC"; $res = mysqli_query($conn, $sql); ob_clean(); header("Content-Type: text/csv; charset=utf-8"); header("Content-Disposition: attachment; filename=告警报表_" . $today . ".csv"); echo "\xEF\xBB\xBF"; $header = ["告警状态", "告警名称", "实例", "级别", "故障开始时间", "接收时间"]; echo implode(",", $header) . "\r\n"; while ($row = mysqli_fetch_assoc($res)) { $status = $row['alert_type'] == 1 ? "触发" : "恢复"; $line = [ $status, $row['alert_name'], $row['instance'], $row['severity'], $row['starts_at'], $row['receive_time'] ]; foreach ($line as &$v) { $v = '"' . str_replace('"', '""', $v) . '"'; } echo implode(",", $line) . "\r\n"; } mysqli_close($conn); exit; } // 所有JSON接口统一返回头 header("Content-Type:application/json;charset=utf-8"); $conn = getDbConn(); if (!$conn) { echo json_encode(["code" => 500, "msg" => "数据库连接失败:" . mysqli_connect_error()], JSON_UNESCAPED_UNICODE); exit; } $today = date("Y-m-d"); // 调试代码:打印GET入参,测试完成后删除此段 // $getAct = $_GET['act'] ?? ''; //echo json_encode([ // "debug_act" => $getAct, // "debug_rule" => $_GET['rule_name'] ?? '', // "debug_instance" => $_GET['instance'] ?? '' //], JSON_UNESCAPED_UNICODE); //exit; // 接口1:下线整条监控规则(该规则下所有实例一并清理) if($act === "clear_offline_rule"){ $rule = $_GET['rule_name'] ?? ''; if(empty($rule)){ echo json_encode(["code"=>400,"msg"=>"缺少rule_name参数"],JSON_UNESCAPED_UNICODE); exit; } $ruleEsc = mysqli_real_escape_string($conn, $rule); // 标记该规则下全部实例为下线 $updateSql = "UPDATE monitor_rule SET status=0, update_at=NOW() WHERE rule_name='$ruleEsc'"; mysqli_query($conn, $updateSql); // 批量插入恢复记录,消除页面残留告警 $insertSql = " INSERT INTO alert_log (alert_type,alert_name,instance,severity,starts_at,receive_time) SELECT DISTINCT 2,alert_name,instance,severity,NOW(),NOW() FROM alert_log WHERE alert_name='$ruleEsc' AND (alert_name,instance) NOT IN ( SELECT alert_name,instance FROM alert_log WHERE alert_type=2 ) "; mysqli_query($conn, $insertSql); echo json_encode(["code"=>0,"msg"=>"整条规则下线完成,所有实例告警已清除"],JSON_UNESCAPED_UNICODE); exit; } // 接口2:单独下线单台实例(仅隐藏指定机器,同规则其他主机不受影响) if($act === "clear_single_instance"){ $rule = $_GET['rule_name'] ?? ''; $inst = $_GET['instance'] ?? ''; if(empty($rule) || empty($inst)){ echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); exit; } $ruleEsc = mysqli_real_escape_string($conn, $rule); $instEsc = mysqli_real_escape_string($conn, $inst); // 第一步:删除当前实例旧的恢复记录,避免重复拦截 $delSql = "DELETE FROM alert_log WHERE alert_type=2 AND alert_name='$ruleEsc' AND instance='$instEsc'"; mysqli_query($conn, $delSql); // 第二步:插入最新恢复记录,移除NOT IN限制,强制生成 $insertSql = " INSERT INTO alert_log (alert_type,alert_name,instance,severity,starts_at,receive_time) SELECT DISTINCT 2,alert_name,instance,severity,NOW(),NOW() FROM alert_log WHERE alert_name='$ruleEsc' AND instance='$instEsc' "; mysqli_query($conn, $insertSql); $affected = mysqli_affected_rows($conn); echo json_encode([ "code"=>0, "msg"=>"单实例告警清理完成", "insert_rows" => $affected ],JSON_UNESCAPED_UNICODE); exit; } // 接口3:恢复整条已下线规则(status改为1,重新展示所有实例告警) if($act === "restore_rule"){ $rule = $_GET['rule_name'] ?? ''; if(empty($rule)){ echo json_encode(["code"=>400,"msg"=>"缺少rule_name参数"],JSON_UNESCAPED_UNICODE); exit; } $ruleEsc = mysqli_real_escape_string($conn, $rule); $updateSql = "UPDATE monitor_rule SET status=1, update_at=NOW() WHERE rule_name='$ruleEsc'"; mysqli_query($conn, $updateSql); echo json_encode(["code"=>0,"msg"=>"监控规则已恢复,新故障会正常展示"],JSON_UNESCAPED_UNICODE); exit; } // 接口4:恢复单台实例(仅把指定rule+instance置为启用) if($act === "restore_single_instance"){ $rule = $_GET['rule_name'] ?? ''; $inst = $_GET['instance'] ?? ''; if(empty($rule) || empty($inst)){ echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); exit; } $ruleEsc = mysqli_real_escape_string($conn, $rule); $instEsc = mysqli_real_escape_string($conn, $inst); $updateSql = "UPDATE monitor_rule SET status=1, update_at=NOW() WHERE rule_name='$ruleEsc' AND instance='$instEsc'"; mysqli_query($conn, $updateSql); echo json_encode(["code"=>0,"msg"=>"单实例已恢复"],JSON_UNESCAPED_UNICODE); exit; } // 接口5:删除单实例全部告警日志 if($act === "delete_single_instance_log"){ $rule = $_GET['rule_name'] ?? ''; $inst = $_GET['instance'] ?? ''; if(empty($rule) || empty($inst)){ echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); exit; } $ruleEsc = mysqli_real_escape_string($conn, $rule); $instEsc = mysqli_real_escape_string($conn, $inst); $delSql = "DELETE FROM alert_log WHERE alert_name='$ruleEsc' AND instance='$instEsc'"; mysqli_query($conn, $delSql); $aff = mysqli_affected_rows($conn); echo json_encode(["code"=>0,"msg"=>"单实例告警日志已删除","affected_rows"=>$aff],JSON_UNESCAPED_UNICODE); exit; } // 接口:永久屏蔽单台实例(monitor_rule 该条实例status=0,不手动恢复永远不告警) if($act === "offline_single_instance"){ $rule = $_GET['rule_name'] ?? ''; $inst = $_GET['instance'] ?? ''; if(empty($rule) || empty($inst)){ echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); exit; } $ruleEsc = mysqli_real_escape_string($conn, $rule); $instEsc = mysqli_real_escape_string($conn, $inst); // 把这条【规则+实例】状态改为0,永久屏蔽 $updateSql = "UPDATE monitor_rule SET status=0, update_at=NOW() WHERE rule_name='$ruleEsc' AND instance='$instEsc'"; mysqli_query($conn, $updateSql); $aff = mysqli_affected_rows($conn); // 同步生成恢复日志,界面立刻消失旧告警 $delOld = "DELETE FROM alert_log WHERE alert_type=2 AND alert_name='$ruleEsc' AND instance='$instEsc'"; mysqli_query($conn, $delOld); $insertSql = " INSERT INTO alert_log (alert_type,alert_name,instance,severity,starts_at,receive_time) SELECT DISTINCT 2,alert_name,instance,severity,NOW(),NOW() FROM alert_log WHERE alert_name='$ruleEsc' AND instance='$instEsc' "; mysqli_query($conn, $insertSql); echo json_encode([ "code"=>0, "msg"=>"单实例已永久屏蔽,需调用restore_single_instance恢复", "update_rows"=>$aff ],JSON_UNESCAPED_UNICODE); exit; } // 新增:同步Prometheus实时告警,自动清理残留恢复记录 if($act === "sync_prom_alerts"){ $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; $resp = @file_get_contents($promUrl); if($resp === false){ echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); exit; } $promData = json_decode($resp,true); if(!isset($promData['data']['alerts'])){ echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); exit; } $firingMap = []; foreach($promData['data']['alerts'] as $item){ $an = $item['labels']['alertname']; $ins = $item['labels']['instance']; $key = "$an||$ins"; $firingMap[$key] = 1; } $res = mysqli_query($conn,"SELECT alert_name,instance FROM alert_log WHERE alert_type=2"); $delCnt = 0; while($row = mysqli_fetch_assoc($res)){ $k = $row['alert_name']."||".$row['instance']; if(isset($firingMap[$k])){ $n = mysqli_real_escape_string($conn,$row['alert_name']); $i = mysqli_real_escape_string($conn,$row['instance']); mysqli_query($conn,"DELETE FROM alert_log WHERE alert_type=2 AND alert_name='$n' AND instance='$i'"); $delCnt++; } } echo json_encode(["code"=>0,"msg"=>"同步完成","delete_clear_log"=>$delCnt],JSON_UNESCAPED_UNICODE); exit; } // 1. 今日统计卡片 if ($act === "day_total") { $sql = "SELECT SUM(IF(alert_type=1,1,0)) as fire_count, SUM(IF(alert_type=2,1,0)) as resolve_count, COUNT(DISTINCT instance) as instance_num FROM alert_log WHERE DATE(receive_time) = '$today'"; $data = mysqli_fetch_assoc(mysqli_query($conn, $sql)); echo json_encode($data, JSON_UNESCAPED_UNICODE); exit; } // 2. 今日告警TOP10图表 if ($act === "top_alert") { $sql = "SELECT alert_name,COUNT(*) cnt FROM alert_log WHERE DATE(receive_time)='$today' GROUP BY alert_name ORDER BY cnt DESC LIMIT 10"; $list = []; $q = mysqli_query($conn, $sql); while ($r = mysqli_fetch_assoc($q)) $list[] = $r; echo json_encode($list, JSON_UNESCAPED_UNICODE); exit; } // 3. 今日全量告警明细表格 if ($act === "log_list") { $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,ends_at,receive_time FROM alert_log WHERE DATE(receive_time)='$today' ORDER BY receive_time DESC"; $list = []; $q = mysqli_query($conn, $sql); while ($r = mysqli_fetch_assoc($q)) $list[] = $r; echo json_encode($list, JSON_UNESCAPED_UNICODE); exit; } // 4. 全局跨天未恢复告警(过滤整条下线规则,单实例仅靠恢复日志隐藏) if ($act === "active_firing") { $maxSql = "SELECT alert_name,instance,MAX(receive_time) max_rt FROM alert_log GROUP BY alert_name,instance"; $maxRes = mysqli_query($conn, $maxSql); $activeList = []; while ($maxRow = mysqli_fetch_assoc($maxRes)) { $an = $conn->real_escape_string($maxRow['alert_name']); $ins = $conn->real_escape_string($maxRow['instance']); $mrt = $conn->real_escape_string($maxRow['max_rt']); // 判断该规则是否整条下线,下线直接跳过 $ruleCheck = mysqli_query($conn, "SELECT status FROM monitor_rule WHERE rule_name='$an' LIMIT 1"); $ruleStatus = 1; if($ruleCheck && $ruleRow = mysqli_fetch_assoc($ruleCheck)){ $ruleStatus = intval($ruleRow['status']); } if($ruleStatus === 0){ continue; } $rowSql = "SELECT alert_name,instance,severity,starts_at,receive_time,alert_type FROM alert_log WHERE alert_name='$an' AND instance='$ins' AND receive_time='$mrt'"; $rowRes = mysqli_query($conn, $rowSql); $data = mysqli_fetch_assoc($rowRes); if ($data && (int)$data['alert_type'] === 1) { $activeList[] = $data; } } echo json_encode($activeList, JSON_UNESCAPED_UNICODE); exit; } // 非法请求兜底 echo json_encode(["code" => 400, "msg" => "无效请求参数act"], JSON_UNESCAPED_UNICODE); mysqli_close($conn); ?>