408 lines
16 KiB
PHP
408 lines
16 KiB
PHP
<?php
|
|
session_start();
|
|
$act = $_GET['act'] ?? '';
|
|
|
|
// 未登录直接拒绝所有接口访问
|
|
if(empty($_SESSION['user_id'])){
|
|
header("Content-Type:application/json;charset=utf-8");
|
|
echo json_encode(["code"=>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;
|
|
}
|
|
// 接收自定义日期参数,不传则取今日
|
|
$targetDate = $_GET['date'] ?? date("Y-m-d");
|
|
// 简单日期格式校验 Y-m-d
|
|
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $targetDate)) {
|
|
header("Content-Type:application/json;charset=utf-8");
|
|
echo json_encode(["code"=>400,"msg"=>"日期格式错误,请使用 Y-m-d,例如 2026-07-01"], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
$sql = "SELECT alert_type,alert_name,instance,severity,starts_at,receive_time
|
|
FROM alert_log WHERE DATE(receive_time) = '$targetDate' 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=告警报表_" . $targetDate . ".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;
|
|
}
|
|
|
|
// ============后台管理专用接口 start============
|
|
// 修改密码 BCrypt哈希加密,匹配历史密码算法
|
|
if($act === "change_pwd"){
|
|
$uid = $_SESSION['user_id'];
|
|
$oldPwdRaw = $_GET['old_pwd'] ?? '';
|
|
$newPwdRaw = $_GET['new_pwd'] ?? '';
|
|
if(empty($oldPwdRaw) || empty($newPwdRaw)){
|
|
echo json_encode(["code"=>400,"msg"=>"密码不能为空"],JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
// 查询原密码哈希
|
|
$userSql = "SELECT password FROM admin_user WHERE user_id='$uid' LIMIT 1";
|
|
$userRes = mysqli_query($conn,$userSql);
|
|
$userRow = mysqli_fetch_assoc($userRes);
|
|
if(!$userRow){
|
|
echo json_encode(["code"=>401,"msg"=>"账户不存在"],JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
$oldHash = $userRow['password'];
|
|
// 校验旧密码(和原有登录逻辑一致)
|
|
if(!password_verify($oldPwdRaw, $oldHash)){
|
|
echo json_encode(["code"=>400,"msg"=>"原密码输入错误"],JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
// 生成新bcrypt哈希
|
|
$newHash = password_hash($newPwdRaw, PASSWORD_DEFAULT);
|
|
$updateSql = "UPDATE admin_user SET password='$newHash', update_at=NOW() WHERE user_id='$uid'";
|
|
mysqli_query($conn,$updateSql);
|
|
echo json_encode(["code"=>0,"msg"=>"密码修改成功"],JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
// 保存界面外观配置
|
|
if($act === "save_theme"){
|
|
// 兼容POST/GET
|
|
$title = mysqli_real_escape_string($conn,$_POST['title'] ?? $_GET['title'] ?? '');
|
|
$color = mysqli_real_escape_string($conn,$_POST['color'] ?? $_GET['color'] ?? '');
|
|
$pagesize = mysqli_real_escape_string($conn,$_POST['pagesize'] ?? $_GET['pagesize'] ?? '20');
|
|
$footer = mysqli_real_escape_string($conn,$_POST['footer'] ?? $_GET['footer'] ?? '');
|
|
$lang = mysqli_real_escape_string($conn,$_POST['lang'] ?? $_GET['lang'] ?? 'zh');
|
|
|
|
$sql = "REPLACE INTO sys_config (k,v) VALUES
|
|
('page_title','$title'),
|
|
('theme_color','$color'),
|
|
('page_size','$pagesize'),
|
|
('footer_text','$footer'),
|
|
('lang','$lang')";
|
|
mysqli_query($conn,$sql);
|
|
echo json_encode(["code"=>0,"msg"=>"外观配置已保存"],JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
// 保存侧边栏外链
|
|
if($act === "save_sidebar_link"){
|
|
$linkText = mysqli_real_escape_string($conn,$_GET['link_text'] ?? '');
|
|
$sql = "REPLACE INTO sys_config (k,v) VALUES ('sidebar_links','$linkText')";
|
|
mysqli_query($conn,$sql);
|
|
echo json_encode(["code"=>0,"msg"=>"侧边外链保存成功"],JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
// 单独切换语言接口
|
|
if ($_POST['act'] === 'save_lang') {
|
|
$lang = mysqli_real_escape_string($conn, $_POST['lang']);
|
|
$sql = "REPLACE INTO sys_config(k, v) VALUES ('lang', '$lang')";
|
|
mysqli_query($conn, $sql);
|
|
echo json_encode(["code" => 0]);
|
|
exit;
|
|
}
|
|
// ============后台管理专用接口 end============
|
|
// 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);
|
|
?>
|