更新
This commit is contained in:
+440
@@ -0,0 +1,440 @@
|
||||
<?php
|
||||
session_start();
|
||||
// 会话超时:30分钟无操作自动登出
|
||||
$expire = 1800;
|
||||
if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) {
|
||||
session_destroy();
|
||||
header("Location: ../login.php");
|
||||
exit;
|
||||
}
|
||||
// 刷新登录时间
|
||||
$_SESSION['login_time'] = time();
|
||||
$userName = htmlspecialchars($_SESSION['username']);
|
||||
$userRole = $_SESSION['role'];
|
||||
$roleText = $userRole === 'admin' ? '管理员' : '只读用户';
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>开发者调试面板 - Advantest 运维告警监控平台</title>
|
||||
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
|
||||
<script src="/static/js/jquery.min.js"></script>
|
||||
<style>
|
||||
*{box-sizing:border-box;margin:0;padding:0}
|
||||
body{
|
||||
background:#f9fafc;
|
||||
font-family:"Inter","PingFang SC","Microsoft YaHei";
|
||||
color:#1d2939;
|
||||
line-height:1.6;
|
||||
}
|
||||
/* 顶部导航 */
|
||||
.header{
|
||||
background:#ffffff;
|
||||
border-bottom:1px solid #eef2fb;
|
||||
color:#152c5b;
|
||||
padding:20px 40px;
|
||||
display:flex;
|
||||
justify-content:space-between;
|
||||
align-items:center;
|
||||
box-shadow:0 2px 12px rgba(21,44,91,0.05);
|
||||
}
|
||||
.header-left{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:14px;
|
||||
}
|
||||
.header-title{
|
||||
font-size:24px;
|
||||
font-weight:700;
|
||||
letter-spacing:1px;
|
||||
color:#152c5b;
|
||||
}
|
||||
.header-sub{
|
||||
font-size:14px;
|
||||
color:#64748b;
|
||||
}
|
||||
.header-right{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:18px;
|
||||
font-size:14px;
|
||||
flex-wrap:wrap;
|
||||
}
|
||||
.user-info{
|
||||
color:#475569;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:6px;
|
||||
}
|
||||
.btn-base{
|
||||
border:none;
|
||||
padding:9px 18px;
|
||||
border-radius:8px;
|
||||
cursor:pointer;
|
||||
font-size:14px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:6px;
|
||||
transition:all 0.2s ease;
|
||||
}
|
||||
.btn-outline{
|
||||
background:#ffffff;
|
||||
color:#152c5b;
|
||||
border:1px solid #cbd5e1;
|
||||
}
|
||||
.btn-outline:hover{
|
||||
background:#f7f8fc;
|
||||
border-color:#152c5b;
|
||||
}
|
||||
.btn-primary{
|
||||
background:#152c5b;
|
||||
color:#fff;
|
||||
}
|
||||
.btn-primary:hover{
|
||||
background:#0f1e42;
|
||||
}
|
||||
.btn-success{
|
||||
background:#10b981;
|
||||
color:#fff;
|
||||
}
|
||||
.btn-success:hover{
|
||||
background:#059669;
|
||||
}
|
||||
.btn-warning{
|
||||
background:#e6a23c;
|
||||
color:#fff;
|
||||
}
|
||||
.btn-danger{
|
||||
background:#f56c6c;
|
||||
color:#fff;
|
||||
}
|
||||
/* 主容器 */
|
||||
.container{
|
||||
padding:36px 40px;
|
||||
max-width:1600px;
|
||||
margin:0 auto;
|
||||
}
|
||||
h1{
|
||||
display:none;
|
||||
}
|
||||
/* 卡片样式 统一企业面板风格 */
|
||||
.card{
|
||||
background:#fff;
|
||||
border-radius:16px;
|
||||
padding:32px;
|
||||
margin-bottom:36px;
|
||||
box-shadow:0 3px 18px rgba(21,44,91,0.06);
|
||||
border:1px solid #eef2fb;
|
||||
}
|
||||
.card h3{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:10px;
|
||||
margin-bottom:26px;
|
||||
padding-bottom:16px;
|
||||
border-bottom:1px solid #eef2fb;
|
||||
font-size:19px;
|
||||
font-weight:600;
|
||||
color:#152c5b;
|
||||
}
|
||||
.card h3 i{
|
||||
color:#2563eb;
|
||||
font-size:20px;
|
||||
}
|
||||
.row{
|
||||
display:flex;
|
||||
gap:12px;
|
||||
align-items:center;
|
||||
margin-bottom:10px;
|
||||
flex-wrap:wrap;
|
||||
}
|
||||
label{
|
||||
font-size:14px;
|
||||
color:#475569;
|
||||
width:110px;
|
||||
}
|
||||
input{
|
||||
padding:8px 12px;
|
||||
border:1px solid #dcdfe6;
|
||||
border-radius:8px;
|
||||
width:280px;
|
||||
font-size:14px;
|
||||
}
|
||||
input[type="date"]{
|
||||
width:200px;
|
||||
}
|
||||
button{
|
||||
padding:9px 18px;
|
||||
border:none;
|
||||
border-radius:8px;
|
||||
cursor:pointer;
|
||||
font-size:14px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:6px;
|
||||
}
|
||||
button.normal{
|
||||
background:#409eff;
|
||||
color:#fff;
|
||||
}
|
||||
button.normal:hover{
|
||||
background:#2979e0;
|
||||
}
|
||||
.tip{
|
||||
font-size:13px;
|
||||
color:#94a3b8;
|
||||
margin-top:8px;
|
||||
padding-left:110px;
|
||||
}
|
||||
/* 返回结果区块 */
|
||||
#result{
|
||||
margin-top:20px;
|
||||
padding:20px;
|
||||
background:#1e1e1e;
|
||||
color:#fff;
|
||||
border-radius:12px;
|
||||
white-space:pre-wrap;
|
||||
min-height:260px;
|
||||
font-family:Consolas,monospace;
|
||||
font-size:13px;
|
||||
}
|
||||
/* 响应式适配 */
|
||||
@media (max-width:768px){
|
||||
.header{padding:16px 24px;flex-direction:column;gap:16px;align-items:flex-start}
|
||||
.container{padding:24px}
|
||||
.card{padding:24px}
|
||||
.row{flex-direction:column;align-items:flex-start}
|
||||
label{width:auto}
|
||||
input{width:100% !important;max-width:320px}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 顶部导航 -->
|
||||
<div class="header">
|
||||
<div class="header-left">
|
||||
<div>
|
||||
<div class="header-title"><i class="fa fa-code"></i> 开发者调试面板</div>
|
||||
<div class="header-sub">全部告警接口可视化调用 · 后端API调试工具</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<span class="user-info"><i class="fa fa-user-circle"></i><?php echo $userName; ?>(<?php echo $roleText; ?>)</span>
|
||||
<button class="btn-base btn-outline" onclick="location.href='../admin.php'"><i class="fa fa-arrow-left"></i>返回系统后台</button>
|
||||
<button class="btn-base btn-outline" onclick="location.reload()"><i class="fa fa-refresh"></i>刷新页面</button>
|
||||
<button class="btn-base btn-primary" onclick="location.href='../dashboard.php'"><i class="fa fa-line-chart"></i>告警监控大屏</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<!-- 1 临时清理单实例告警 clear_single_instance -->
|
||||
<div class="card">
|
||||
<h3><i class="fa fa-eraser"></i>1. 临时隐藏单实例告警 clear_single_instance</h3>
|
||||
<div class="row">
|
||||
<label>rule_name:</label>
|
||||
<input id="c_rule" placeholder="例 Port_Down">
|
||||
<label>instance:</label>
|
||||
<input id="c_ins" placeholder="例 10.150.10.82:389">
|
||||
<button class="normal" onclick="req('clear_single_instance','c_rule','c_ins')"><i class="fa fa-play"></i>执行清理</button>
|
||||
</div>
|
||||
<div class="tip">仅插入恢复日志,下次故障自动重新展示;instance冒号无需手动编码,JS自动处理</div>
|
||||
</div>
|
||||
|
||||
<!-- 2 永久屏蔽单实例 offline_single_instance -->
|
||||
<div class="card">
|
||||
<h3><i class="fa fa-ban"></i>2. 永久屏蔽单实例 offline_single_instance</h3>
|
||||
<div class="row">
|
||||
<label>rule_name:</label>
|
||||
<input id="off_rule" placeholder="例 Port_Down">
|
||||
<label>instance:</label>
|
||||
<input id="off_ins" placeholder="例 10.150.10.82:389">
|
||||
<button class="btn-danger" onclick="req('offline_single_instance','off_rule','off_ins')"><i class="fa fa-ban"></i>永久屏蔽</button>
|
||||
</div>
|
||||
<div class="tip">修改monitor_rule状态0,不执行恢复接口则永久不展示该实例告警</div>
|
||||
</div>
|
||||
|
||||
<!-- 3 恢复单实例 restore_single_instance -->
|
||||
<div class="card">
|
||||
<h3><i class="fa fa-check-circle"></i>3. 恢复单实例 restore_single_instance</h3>
|
||||
<div class="row">
|
||||
<label>rule_name:</label>
|
||||
<input id="res_rule" placeholder="例 Port_Down">
|
||||
<label>instance:</label>
|
||||
<input id="res_ins" placeholder="例 10.150.10.82:389">
|
||||
<button class="btn-success" onclick="req('restore_single_instance','res_rule','res_ins')"><i class="fa fa-unlock"></i>恢复实例告警</button>
|
||||
</div>
|
||||
<div class="tip">解除单实例永久屏蔽状态,新故障会正常展示</div>
|
||||
</div>
|
||||
|
||||
<!-- 4 整条规则下线 clear_offline_rule -->
|
||||
<div class="card">
|
||||
<h3><i class="fa fa-cog"></i>4. 整条规则全部下线 clear_offline_rule</h3>
|
||||
<div class="row">
|
||||
<label>rule_name:</label>
|
||||
<input id="cr_rule" placeholder="例 Host_Ping_Offline">
|
||||
<button class="btn-danger" onclick="reqSingle('clear_offline_rule','cr_rule')"><i class="fa fa-power-off"></i>下线整条规则</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 5 恢复整条规则 restore_rule -->
|
||||
<div class="card">
|
||||
<h3><i class="fa fa-cog"></i>5. 恢复整条规则 restore_rule</h3>
|
||||
<div class="row">
|
||||
<label>rule_name:</label>
|
||||
<input id="rr_rule" placeholder="例 Host_Ping_Offline">
|
||||
<button class="btn-success" onclick="reqSingle('restore_rule','rr_rule')"><i class="fa fa-refresh"></i>恢复整条规则</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 6 删除单实例全部日志 delete_single_instance_log -->
|
||||
<div class="card">
|
||||
<h3><i class="fa fa-trash"></i>6. 删除单实例所有告警日志 delete_single_instance_log</h3>
|
||||
<div class="row">
|
||||
<label>rule_name:</label>
|
||||
<input id="del_rule" placeholder="例 Port_Down">
|
||||
<label>instance:</label>
|
||||
<input id="del_ins" placeholder="例 10.150.10.82:389">
|
||||
<button class="btn-warning" onclick="req('delete_single_instance_log','del_rule','del_ins')"><i class="fa fa-trash"></i>清空日志</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 7 同步Prometheus实时告警 sync_prom_alerts -->
|
||||
<div class="card">
|
||||
<h3><i class="fa fa-refresh"></i>7. 手动同步Prometheus告警(清除脏恢复记录)</h3>
|
||||
<div class="row">
|
||||
<button class="normal" onclick="simpleReq('sync_prom_alerts')"><i class="fa fa-sync"></i>立即同步校准数据库</button>
|
||||
</div>
|
||||
<div class="tip">自动删除故障中残留的手动恢复记录,修复前端“故障存在但页面不显示”bug</div>
|
||||
</div>
|
||||
|
||||
<!-- 8 数据查询接口 -->
|
||||
<div class="card">
|
||||
<h3><i class="fa fa-database"></i>8. 数据查询接口(获取面板原始数据)</h3>
|
||||
<div class="row">
|
||||
<button class="normal" onclick="simpleReq('day_total')"><i class="fa fa-bar-chart"></i>今日统计 day_total</button>
|
||||
<button class="normal" onclick="simpleReq('top_alert')"><i class="fa fa-pie-chart"></i>告警TOP10 top_alert</button>
|
||||
<button class="normal" onclick="simpleReq('log_list')"><i class="fa fa-list"></i>今日明细 log_list</button>
|
||||
<button class="normal" onclick="simpleReq('active_firing')"><i class="fa fa-exclamation-circle"></i>当前未恢复 active_firing</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 9 导出CSV报表(带日历选择) -->
|
||||
<div class="card">
|
||||
<h3><i class="fa fa-download"></i>9. 导出告警CSV报表</h3>
|
||||
|
||||
<!-- 第一组:单日导出(原有功能保留) -->
|
||||
<div class="row" style="margin-bottom:12px;gap:10px;align-items:center;flex-wrap:wrap;">
|
||||
<label>单日导出:</label>
|
||||
<input type="date" id="csv_date" placeholder="留空导出今日">
|
||||
<button class="btn-success" onclick="exportCsvSingle()"><i class="fa fa-download"></i>下载单日报表</button>
|
||||
</div>
|
||||
<div class="tip" style="margin-bottom:16px;">不选择日期默认导出今日告警;选择历史日期下载单日报表</div>
|
||||
|
||||
<!-- 第二组:区间导出(新增) -->
|
||||
<div class="row" style="gap:10px;align-items:center;flex-wrap:wrap;">
|
||||
<label>区间导出:</label>
|
||||
<input type="date" id="csv_start">
|
||||
<span>~</span>
|
||||
<input type="date" id="csv_end">
|
||||
<button class="btn-primary" onclick="exportCsvRange()"><i class="fa fa-download"></i>下载区间报表</button>
|
||||
</div>
|
||||
<div class="tip">填写开始、结束日期,导出该时间段全部告警数据</div>
|
||||
</div>
|
||||
|
||||
<!-- 返回结果输出 -->
|
||||
<div class="card">
|
||||
<h3><i class="fa fa-terminal"></i>接口返回结果(JSON)</h3>
|
||||
<div id="result">等待执行接口操作...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 接口路径 同目录 index.php
|
||||
const apiUrl = "./index.php";
|
||||
const resultDom = document.getElementById("result");
|
||||
|
||||
// 双参数接口 act + rule_name + instance
|
||||
function req(act, ruleId, insId){
|
||||
const rule = document.getElementById(ruleId).value.trim();
|
||||
const ins = document.getElementById(insId).value.trim();
|
||||
if(!rule || !ins){
|
||||
resultDom.innerText = "错误:rule_name 和 instance 不能为空";
|
||||
return;
|
||||
}
|
||||
const params = new URLSearchParams();
|
||||
params.append("act", act);
|
||||
params.append("rule_name", rule);
|
||||
params.append("instance", ins);
|
||||
fetch(`${apiUrl}?${params.toString()}`)
|
||||
.then(r=>r.json())
|
||||
.then(json=>{
|
||||
resultDom.innerText = JSON.stringify(json,null,2);
|
||||
})
|
||||
.catch(e=>{
|
||||
resultDom.innerText = "请求异常:"+e;
|
||||
})
|
||||
}
|
||||
|
||||
// 单参数接口 act + rule_name
|
||||
function reqSingle(act, ruleId){
|
||||
const rule = document.getElementById(ruleId).value.trim();
|
||||
if(!rule){
|
||||
resultDom.innerText = "错误:rule_name 不能为空";
|
||||
return;
|
||||
}
|
||||
const params = new URLSearchParams();
|
||||
params.append("act", act);
|
||||
params.append("rule_name", rule);
|
||||
fetch(`${apiUrl}?${params.toString()}`)
|
||||
.then(r=>r.json())
|
||||
.then(json=>{
|
||||
resultDom.innerText = JSON.stringify(json,null,2);
|
||||
})
|
||||
.catch(e=>{
|
||||
resultDom.innerText = "请求异常:"+e;
|
||||
})
|
||||
}
|
||||
|
||||
// 无参数接口
|
||||
function simpleReq(act){
|
||||
fetch(`${apiUrl}?act=${act}`)
|
||||
.then(r=>r.json())
|
||||
.then(json=>{
|
||||
resultDom.innerText = JSON.stringify(json,null,2);
|
||||
})
|
||||
.catch(e=>{
|
||||
resultDom.innerText = "请求异常:"+e;
|
||||
})
|
||||
}
|
||||
|
||||
// 单日导出
|
||||
function exportCsvSingle(){
|
||||
const dateVal = document.getElementById("csv_date").value.trim();
|
||||
let url = `${apiUrl}?act=export_csv`;
|
||||
if(dateVal){
|
||||
url += `&date=${encodeURIComponent(dateVal)}`;
|
||||
}
|
||||
window.open(url,"_blank");
|
||||
}
|
||||
|
||||
// 区间导出
|
||||
function exportCsvRange(){
|
||||
const startDate = document.getElementById("csv_start").value.trim();
|
||||
const endDate = document.getElementById("csv_end").value.trim();
|
||||
if(!startDate || !endDate){
|
||||
alert("请同时选择开始日期和结束日期");
|
||||
return;
|
||||
}
|
||||
if(startDate > endDate){
|
||||
alert("开始日期不能晚于结束日期");
|
||||
return;
|
||||
}
|
||||
let url = `${apiUrl}?act=export_csv`;
|
||||
url += `&start=${encodeURIComponent(startDate)}&end=${encodeURIComponent(endDate)}`;
|
||||
window.open(url,"_blank");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user