mirror of
https://github.com/rnvm9wjdtj-bot/myaps_api.git
synced 2026-06-02 05:54:40 +00:00
722 lines
44 KiB
HTML
722 lines
44 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title data-i18n-page-title="page.title">MyAPI 系统监控面板</title>
|
||
<link rel="icon" href="/static/swagger/favicon.png" type="image/png">
|
||
<link rel="stylesheet" href="/static/monitor/css/monitor.css">
|
||
<link rel="stylesheet" href="/static/monitor/lib/prism.min.css">
|
||
<script src="/static/monitor/lib/chart.min.js"></script>
|
||
<script src="/static/monitor/lib/prism.min.js"></script>
|
||
<script src="/static/monitor/lib/prism-json.min.js"></script>
|
||
<script src="/static/lib/i18n/i18n.js"></script>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<header class="header">
|
||
<nav class="nav-menu">
|
||
<a href="#" class="nav-item active" data-page="overview" data-i18n="monitor.nav.overview">📊 Overview</a>
|
||
<a href="#" class="nav-item" data-page="database" data-i18n="monitor.nav.database">🗃️ 数据库<span id="database-badge" class="nav-badge" style="display: none;"></span></a>
|
||
<a href="#" class="nav-item" data-page="event-helpers" data-i18n="monitor.nav.events">☎️ 事件处理</a>
|
||
<a href="#" class="nav-item" data-page="scheduler" data-i18n="monitor.nav.scheduler">⏰ 定时任务</a>
|
||
<a href="#" class="nav-item" data-page="api-requests" data-i18n="monitor.nav.http_requests">📥 接收请求<span id="api-requests-badge" class="nav-badge" style="display: none;"></span></a>
|
||
<a href="#" class="nav-item" data-page="outbound-requests" data-i18n="monitor.nav.outbound_requests">📤 发送请求<span id="outbound-requests-badge" class="nav-badge" style="display: none;"></span></a>
|
||
<a href="#" class="nav-item" data-page="logs" data-i18n="monitor.nav.logs">📋 日志<span id="logs-badge" class="nav-badge" style="display: none;"></span></a>
|
||
</nav>
|
||
<div class="header-info">
|
||
<select id="lang-selector" class="lang-selector" onchange="i18n.switchLanguage(this.value)">
|
||
<option value="zh-CN">🇨🇳 中文</option>
|
||
<option value="en-US">🇺🇸 English</option>
|
||
<option value="de-DE">🇩🇪 Deutsch</option>
|
||
</select>
|
||
<span id="status-indicator" class="status healthy" data-i18n="monitor.status.healthy">● 系统正常</span>
|
||
<span id="last-update"><span data-i18n="monitor.other.last_update">最后更新</span> --</span>
|
||
<button id="refresh-btn" class="btn btn-primary" onclick="refreshAll()" data-i18n="monitor.btn.refresh">刷新</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Overview 页面 -->
|
||
<main class="main-content page-content active" id="page-overview">
|
||
<!-- 资源监控卡片 -->
|
||
<section class="card">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.resource">资源使用</h2>
|
||
<span class="badge" id="resource-badge" data-i18n="monitor.status.running">运行中</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="metrics-grid">
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.cpu">CPU 使用率</div>
|
||
<div class="metric-value" id="cpu-value">--%</div>
|
||
<div class="progress-bar">
|
||
<div class="progress-fill" id="cpu-bar"></div>
|
||
</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.memory">内存使用</div>
|
||
<div class="metric-value" id="memory-value">
|
||
<span id="memory-usage">-- MB</span>
|
||
<span id="memory-percent" class="memory-percent">--%</span>
|
||
</div>
|
||
<div class="progress-bar">
|
||
<div class="progress-fill" id="memory-bar"></div>
|
||
</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.threads">线程数</div>
|
||
<div class="metric-value" id="threads-value">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.uptime">运行时间</div>
|
||
<div class="metric-value" id="uptime-value">--</div>
|
||
</div>
|
||
</div>
|
||
<div class="chart-container">
|
||
<canvas id="resource-chart"></canvas>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 数据库状态卡片 -->
|
||
<section class="card">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.db_status">账套状态</h2>
|
||
<span class="badge" id="db-badge" data-i18n="monitor.status.checking">检查中</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="db-summary" id="db-summary">
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.total_connections">总连接数</span>
|
||
<span class="summary-value" id="db-total">--</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.healthy">健康</span>
|
||
<span class="summary-value healthy" id="db-healthy">--</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.unhealthy">异常</span>
|
||
<span class="summary-value error" id="db-unhealthy">--</span>
|
||
</div>
|
||
</div>
|
||
<div class="db-list" id="db-list">
|
||
<!-- 动态生成数据库连接列表 -->
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 提醒信息卡片 -->
|
||
<section class="card">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.recent_alerts">最近告警</h2>
|
||
<button class="btn btn-small" onclick="clearAlerts()" data-i18n="monitor.btn.clear">清空</button>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="alert-list" id="alert-list">
|
||
<!-- 动态生成告警列表 -->
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 接收请求卡片 -->
|
||
<section class="card">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.api_requests">接收请求</h2>
|
||
<span class="badge" id="http-badge" data-i18n="monitor.status.running">监控中</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="http-summary" id="http-summary">
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.requests_total">总请求数</span>
|
||
<span class="summary-value" id="http-total">--</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.error_rate">错误率</span>
|
||
<span class="summary-value" id="http-error-rate">--%</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.avg_time">平均响应</span>
|
||
<span class="summary-value" id="http-avg-time">--ms</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label">QPS</span>
|
||
<span class="summary-value" id="http-rpm">--</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 发送请求卡片 -->
|
||
<section class="card">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.outbound_requests">发送请求</h2>
|
||
<span class="badge" id="outbound-badge" data-i18n="monitor.status.running">监控中</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="outbound-summary" id="outbound-summary">
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.requests_total">总请求数</span>
|
||
<span class="summary-value" id="outbound-total">--</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.error_rate">错误率</span>
|
||
<span class="summary-value" id="outbound-error-rate">--%</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.avg_time">平均响应</span>
|
||
<span class="summary-value" id="outbound-avg">--ms</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 定时任务监控卡片 -->
|
||
<section class="card">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.scheduler">定时任务</h2>
|
||
<span class="badge" id="scheduler-badge" data-i18n="monitor.status.checking">检查中</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="scheduler-info" id="scheduler-info">
|
||
<div class="info-item">
|
||
<span class="info-label" data-i18n="monitor.metric.scheduler_status">调度器状态</span>
|
||
<span class="info-value" id="scheduler-status">--</span>
|
||
</div>
|
||
<div class="info-item">
|
||
<span class="info-label" data-i18n="monitor.metric.job_count">任务数量</span>
|
||
<span class="info-value" id="job-count">--</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- 数据库页面 -->
|
||
<main class="main-content page-content" id="page-database">
|
||
<!-- 数据库详细信息卡片 -->
|
||
<section class="card full-width">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.mysql">MySQL</h2>
|
||
<span class="badge" id="db-detail-badge" data-i18n="monitor.status.checking">检查中</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<!-- 数据库详细信息 -->
|
||
<div class="db-detail-table-container">
|
||
<table class="db-detail-table" id="db-detail-table">
|
||
<thead>
|
||
<tr>
|
||
<th data-i18n="monitor.col.db_name">账套名称</th>
|
||
<th data-i18n="monitor.metric.connection_status">连接状态</th>
|
||
<th data-i18n="monitor.col.last_check">最后检查</th>
|
||
<th data-i18n="monitor.col.current_connections">当前连接</th>
|
||
<th data-i18n="monitor.col.max_connections">最大连接</th>
|
||
<th data-i18n="monitor.col.min_connections">最小连接</th>
|
||
<th data-i18n="monitor.col.idle_connections">空闲连接</th>
|
||
<th data-i18n="monitor.col.used_connections">使用中连接</th>
|
||
<th data-i18n="monitor.col.usage">使用率</th>
|
||
<th data-i18n="monitor.col.processed_records">处理记录</th>
|
||
<th data-i18n="monitor.col.count">次数</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="db-detail-tbody">
|
||
<!-- 动态生成数据库详细信息 -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Redis 监控卡片 -->
|
||
<section class="card full-width">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.redis">Redis</h2>
|
||
<span class="badge" id="redis-badge" data-i18n="monitor.status.checking">检查中</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="redis-metrics-grid">
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.connection_status">连接状态</div>
|
||
<div class="metric-value" id="redis-status">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.host">主机</div>
|
||
<div class="metric-value" id="redis-host">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.port">端口</div>
|
||
<div class="metric-value" id="redis-port">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.database">数据库</div>
|
||
<div class="metric-value" id="redis-db">--</div>
|
||
</div>
|
||
</div>
|
||
<div class="redis-pool-metrics">
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.used_connections">使用连接数</div>
|
||
<div class="metric-value" id="redis-connections-used">0</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.max_connections">最大连接数</div>
|
||
<div class="metric-value" id="redis-connections-max">0</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.connection_usage">连接使用率</div>
|
||
<div class="metric-value" id="redis-connection-usage">0%</div>
|
||
</div>
|
||
</div>
|
||
<div class="redis-buffer-metrics">
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.buffer_size">缓冲大小</div>
|
||
<div class="metric-value" id="redis-buffer-size">0</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.buffer_threshold">缓冲阈值</div>
|
||
<div class="metric-value" id="redis-buffer-threshold">0</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.buffer_usage">缓冲使用率</div>
|
||
<div class="metric-value" id="redis-buffer-usage">0%</div>
|
||
</div>
|
||
</div>
|
||
<div class="chart-container">
|
||
<h3 data-i18n="monitor.chart.redis_connections">Redis 连接池使用情况</h3>
|
||
<canvas id="redis-connections-chart"></canvas>
|
||
</div>
|
||
<div class="chart-container">
|
||
<h3 data-i18n="monitor.chart.redis_buffer">Redis 缓冲大小变化</h3>
|
||
<canvas id="redis-buffer-chart"></canvas>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- 接收请求页面 -->
|
||
<main class="main-content page-content" id="page-api-requests">
|
||
<section class="card full-width">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.http_requests_log">接收请求记录</h2>
|
||
<div class="card-actions">
|
||
<div class="date-selector" style="display: none;">
|
||
<label for="api-date-picker">选择日期:</label>
|
||
<input type="date" id="api-date-picker" value="">
|
||
<button class="btn btn-sm" onclick="fetchRequestsByDate()">查询</button>
|
||
</div>
|
||
<div class="toggle-switch">
|
||
<label>
|
||
<input type="checkbox" id="show-api-internal-requests" onchange="toggleAPIIntternalRequests()">
|
||
<span class="toggle-slider"></span>
|
||
<span data-i18n="monitor.other.show_internal">显示内部请求</span>
|
||
</label>
|
||
</div>
|
||
<button class="btn btn-sm" onclick="refreshAPIRequests()" data-i18n="monitor.btn.refresh">刷新</button>
|
||
<button class="btn btn-sm btn-secondary" onclick="resetAPIStats()" data-i18n="monitor.btn.reset_stats">重置统计</button>
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="api-requests-table-container">
|
||
<table class="api-requests-table" id="api-requests-table">
|
||
<thead>
|
||
<tr>
|
||
<th data-i18n="monitor.col.index">序号</th>
|
||
<th data-i18n="monitor.col.timestamp">时间戳</th>
|
||
<th data-i18n="monitor.col.method">方法</th>
|
||
<th data-i18n="monitor.col.path">端点</th>
|
||
<th data-i18n="monitor.col.query_params">查询参数</th>
|
||
<th data-i18n="monitor.col.status">状态码</th>
|
||
<th data-i18n="monitor.col.duration">响应时间</th>
|
||
<th data-i18n="monitor.col.client_ip">客户端IP</th>
|
||
<th data-i18n="monitor.col.error_message">错误信息</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="api-requests-tbody">
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<!-- 接收请求详情模态对话框 -->
|
||
<div class="modal" id="api-request-modal" style="display: none;">
|
||
<div class="modal-overlay" onclick="hideRequestDetail()"></div>
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3>请求详情</h3>
|
||
<button class="btn btn-small close-btn" onclick="hideRequestDetail()">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="api-detail-content">
|
||
<div class="api-detail-section">
|
||
<h4>请求信息</h4>
|
||
<div class="api-detail-info" id="api-detail-request-info"></div>
|
||
</div>
|
||
<div class="api-detail-bodies">
|
||
<div class="api-detail-section">
|
||
<div class="section-header">
|
||
<h4>请求体</h4>
|
||
<div class="section-actions">
|
||
<button class="btn btn-small" onclick="highlightRequestBody()">高亮</button>
|
||
<button class="btn btn-small" onclick="copyRequestBody()">复制</button>
|
||
</div>
|
||
</div>
|
||
<pre class="api-detail-body"><code class="language-json" id="api-detail-request-body"></code></pre>
|
||
</div>
|
||
<div class="api-detail-section">
|
||
<div class="section-header">
|
||
<h4>响应体</h4>
|
||
<div class="section-actions">
|
||
<button class="btn btn-small" onclick="highlightResponseBody()">高亮</button>
|
||
<button class="btn btn-small" onclick="copyResponseBody()">复制</button>
|
||
</div>
|
||
</div>
|
||
<pre class="api-detail-body"><code class="language-json" id="api-detail-response-body"></code></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- 定时任务页面 -->
|
||
<main class="main-content page-content" id="page-scheduler">
|
||
<section class="card full-width">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.scheduler_detail">定时任务详情</h2>
|
||
<span class="badge" id="scheduler-detail-badge" data-i18n="monitor.status.checking">检查中</span>
|
||
<button class="btn btn-small" onclick="refreshSchedulerPage()" data-i18n="monitor.btn.refresh">刷新</button>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="scheduler-detail-grid" id="scheduler-detail-grid">
|
||
<!-- 动态生成定时任务详细信息 -->
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- 发送请求页面 -->
|
||
<main class="main-content page-content" id="page-outbound-requests">
|
||
<section class="card full-width">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.outbound_requests_log">发送请求记录</h2>
|
||
<div class="card-actions">
|
||
<div class="date-selector" style="display: none;">
|
||
<label for="outbound-date-picker">选择日期:</label>
|
||
<input type="date" id="outbound-date-picker" value="">
|
||
<button class="btn btn-sm" onclick="fetchOutboundRequestsByDate()">查询</button>
|
||
</div>
|
||
<div class="toggle-switch">
|
||
<label>
|
||
<input type="checkbox" id="show-internal-requests" onchange="toggleInternalRequests()">
|
||
<span class="toggle-slider"></span>
|
||
<span data-i18n="monitor.other.show_internal">显示内部请求</span>
|
||
</label>
|
||
</div>
|
||
<button class="btn btn-sm" onclick="refreshOutboundRequests()" data-i18n="monitor.btn.refresh">刷新</button>
|
||
<button class="btn btn-sm btn-secondary" onclick="resetOutboundStats()" data-i18n="monitor.btn.reset_stats">重置统计</button>
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
|
||
<div class="outbound-requests-container">
|
||
<table class="outbound-requests-table">
|
||
<thead>
|
||
<tr>
|
||
<th data-i18n="monitor.col.index">序号</th>
|
||
<th data-i18n="monitor.col.timestamp">时间戳</th>
|
||
<th data-i18n="monitor.col.method">方法</th>
|
||
<th data-i18n="monitor.col.url">URL</th>
|
||
<th data-i18n="monitor.col.status">状态码</th>
|
||
<th data-i18n="monitor.col.duration">响应时间</th>
|
||
<th data-i18n="monitor.col.module">模块</th>
|
||
<th data-i18n="monitor.col.error_message">错误信息</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="outbound-requests-table">
|
||
<!-- 动态生成发送请求记录 -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- 日志页面 -->
|
||
<main class="main-content page-content" id="page-logs">
|
||
<!-- 原有日志记录卡片 -->
|
||
<section class="card full-width">
|
||
<div class="card-header">
|
||
<h2>Warning & Error</h2>
|
||
<div class="log-page-controls">
|
||
<button class="btn btn-primary" onclick="window.open('/monitor/live-logs', '_blank')" data-i18n="monitor.btn.live_logs">实时日志</button>
|
||
<button class="btn btn-primary" onclick="window.open('/monitor/history-logs', '_blank')" data-i18n="monitor.btn.history_query">历史查询</button>
|
||
<div class="toggle-switch">
|
||
<label>
|
||
<input type="checkbox" id="show-read-logs" onchange="toggleReadLogs()">
|
||
<span class="toggle-slider"></span>
|
||
<span data-i18n="monitor.other.show_read">显示已读</span>
|
||
</label>
|
||
</div>
|
||
<select id="log-page-level" onchange="fetchLogsPage()">
|
||
<option value="" data-i18n="monitor.filter.all_logs">全部日志</option>
|
||
<option value="error">错误日志</option>
|
||
<option value="warning">警告日志</option>
|
||
</select>
|
||
<button class="btn btn-small" onclick="markAllLogsAsRead()" data-i18n="monitor.btn.mark_all_read">标记全部已读</button>
|
||
<button class="btn btn-small" onclick="clearReadStatus()" data-i18n="monitor.btn.clear_read_status">清空已读状态</button>
|
||
<button class="btn btn-small" onclick="refreshLogsPage()" data-i18n="monitor.btn.refresh">刷新</button>
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="logs-table-container">
|
||
<table class="logs-table" id="logs-table">
|
||
<thead>
|
||
<tr>
|
||
<th data-i18n="monitor.col.index">序号</th>
|
||
<th data-i18n="monitor.col.time">时间</th>
|
||
<th data-i18n="monitor.col.level">级别</th>
|
||
<th data-i18n="monitor.col.module">模块</th>
|
||
<th data-i18n="monitor.col.message">消息</th>
|
||
<th data-i18n="monitor.col.is_read">已读</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="logs-tbody">
|
||
<!-- 动态生成日志记录 -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- 事件处理页面 -->
|
||
<main class="main-content page-content" id="page-event-helpers">
|
||
<!-- 事件监听卡片 -->
|
||
<section class="card full-width">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.event_listener">事件监听</h2>
|
||
<div class="events-actions">
|
||
<button class="btn btn-small" onclick="refreshEventStats()" data-i18n="monitor.btn.refresh">刷新</button>
|
||
<button class="btn btn-small" onclick="flushAllEvents()" data-i18n="monitor.btn.flush_all">立即刷新所有</button>
|
||
<button class="btn btn-small btn-secondary" onclick="resetEventStats()" data-i18n="monitor.btn.reset_stats">重置统计</button>
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="events-summary" id="events-summary">
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.events_received">总接收事件</span>
|
||
<span class="summary-value" id="events-total-received">--</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.events_processed">已处理事件</span>
|
||
<span class="summary-value healthy" id="events-total-processed">--</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.events_interrupted">中断处理</span>
|
||
<span class="summary-value error" id="events-total-failed">--</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.pending">待处理</span>
|
||
<span class="summary-value" id="events-total-pending">--</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.overall_success_rate">整体成功率</span>
|
||
<span class="summary-value" id="events-success-rate">--%</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.active_event_types">活跃事件类型</span>
|
||
<span class="summary-value" id="events-active-types">--</span>
|
||
</div>
|
||
<!-- 背压监控 -->
|
||
<div class="summary-item" id="backpressure-summary" style="display: none;">
|
||
<span class="summary-label" data-i18n="monitor.metric.backpressure_status">背压状态</span>
|
||
<span class="summary-value" id="backpressure-status">正常</span>
|
||
</div>
|
||
<div class="summary-item" id="backpressure-pending" style="display: none;">
|
||
<span class="summary-label" data-i18n="monitor.metric.backpressure_pending">待处理事件</span>
|
||
<span class="summary-value" id="backpressure-pending-count">--</span>
|
||
</div>
|
||
<div class="summary-item" id="backpressure-percent" style="display: none;">
|
||
<span class="summary-label" data-i18n="monitor.metric.backpressure_usage">背压使用率</span>
|
||
<span class="summary-value" id="backpressure-usage">--%</span>
|
||
</div>
|
||
<!-- 事件循环健康状态 -->
|
||
<div class="summary-item" id="event-loop-status" style="display: none;">
|
||
<span class="summary-label" data-i18n="monitor.metric.event_loop_status">事件循环状态</span>
|
||
<span class="summary-value" id="event-loop-health">正常</span>
|
||
</div>
|
||
</div>
|
||
<div class="events-table-container">
|
||
<table class="events-table" id="events-table">
|
||
<thead>
|
||
<tr>
|
||
<th data-i18n="monitor.col.description">描述</th>
|
||
<th data-i18n="monitor.col.total_received">总接收</th>
|
||
<th data-i18n="monitor.col.pending">待处理</th>
|
||
<th data-i18n="monitor.col.processed">已处理</th>
|
||
<th data-i18n="monitor.col.interrupted">中断</th>
|
||
<th data-i18n="monitor.col.completion_rate">完成率</th>
|
||
<th data-i18n="monitor.col.avg_latency">平均延迟</th>
|
||
<th data-i18n="monitor.col.operation">操作</th>
|
||
<th data-i18n="monitor.col.last_action">最后动作</th>
|
||
<th data-i18n="monitor.col.status">状态</th>
|
||
<th data-i18n="monitor.col.operation">操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="events-tbody">
|
||
<!-- 动态生成事件统计列表 -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 下半部分:左边是回调跟踪器和事件去重器,右边是DeadLetter队列 -->
|
||
<div class="event-helpers-layout">
|
||
<!-- 左边:回调跟踪器和事件去重器 -->
|
||
<div class="left-column">
|
||
<!-- 回调跟踪器卡片 -->
|
||
<section class="card">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.callback_tracker">回调跟踪器</h2>
|
||
<span class="badge" id="callback-badge" data-i18n="monitor.status.monitoring">监控中</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="metrics-grid">
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.pending_callbacks">待处理回调</div>
|
||
<div class="metric-value" id="callback-pending">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.max_retries">最大重试次数</div>
|
||
<div class="metric-value" id="callback-max-retries">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.pending_retries">待处理重试</div>
|
||
<div class="metric-value" id="callback-pending-retries">--</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 事件去重器卡片 -->
|
||
<section class="card">
|
||
<div class="card-header">
|
||
<h2 data-i18n="monitor.card.event_deduplicator">事件去重器</h2>
|
||
<span class="badge" id="deduplicator-badge" data-i18n="monitor.status.monitoring">监控中</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="metrics-grid">
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.total_entries">总存储条目</div>
|
||
<div class="metric-value" id="deduplicator-total">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.active_items">活跃项目</div>
|
||
<div class="metric-value" id="deduplicator-active">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.ttl_seconds">TTL (秒)</div>
|
||
<div class="metric-value" id="deduplicator-ttl">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.max_entries">最大条目</div>
|
||
<div class="metric-value" id="deduplicator-max">--</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- 右边:DeadLetter队列 -->
|
||
<div class="right-column">
|
||
<section class="card dead-letter-card">
|
||
<div class="card-header">
|
||
<h2>Dead Letter Queue</h2>
|
||
<div class="dead-letter-actions">
|
||
<button class="btn btn-small" onclick="refreshDeadLetterStats()" data-i18n="monitor.btn.refresh">刷新</button>
|
||
<button class="btn btn-small btn-secondary" onclick="clearDeadLetters()" data-i18n="monitor.btn.clear">清空</button>
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="metrics-grid">
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.pending_events">待写入事件</div>
|
||
<div class="metric-value" id="dlq-pending">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.total_events">总事件数</div>
|
||
<div class="metric-value" id="dlq-total">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.file_size">文件大小</div>
|
||
<div class="metric-value" id="dlq-file-size">--</div>
|
||
</div>
|
||
<div class="metric-item">
|
||
<div class="metric-label" data-i18n="monitor.metric.running_status">运行状态</div>
|
||
<div class="metric-value" id="dlq-running">--</div>
|
||
</div>
|
||
</div>
|
||
<div class="dead-letter-summary" id="dead-letter-summary" style="margin-top: 15px; padding-top: 15px; border-top: 1px solid #e2e8f0;">
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.dl_total">DL总数</span>
|
||
<span class="summary-value" id="dead-letter-total">--</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.recent_dl">最近DL</span>
|
||
<span class="summary-value" id="dead-letter-recent">--</span>
|
||
</div>
|
||
<div class="summary-item">
|
||
<span class="summary-label" data-i18n="monitor.metric.process_success_rate">处理成功率</span>
|
||
<span class="summary-value" id="dead-letter-success-rate">--%</span>
|
||
</div>
|
||
</div>
|
||
<div class="dead-letter-table-container" style="margin-top: 15px;">
|
||
<table class="dead-letter-table" id="dead-letter-table">
|
||
<thead>
|
||
<tr>
|
||
<th data-i18n="monitor.col.id">ID</th>
|
||
<th data-i18n="monitor.col.event_type">事件类型</th>
|
||
<th data-i18n="monitor.col.time">时间</th>
|
||
<th data-i18n="monitor.col.database">数据库</th>
|
||
<th data-i18n="monitor.col.table">表</th>
|
||
<th data-i18n="monitor.col.error_message">错误信息</th>
|
||
<th data-i18n="monitor.col.operation">操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="dead-letter-tbody">
|
||
<!-- 动态生成DeadLetter列表 -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<footer class="footer">
|
||
<p> </p>
|
||
</footer>
|
||
</main>
|
||
</div>
|
||
|
||
<!-- 超时提示模态框 -->
|
||
<div class="modal" id="inactivity-modal" style="display: none;">
|
||
<div class="modal-overlay"></div>
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3>⌛ 监控已超时</h3>
|
||
</div>
|
||
<div class="modal-body">
|
||
<p>由于长时间未活动,监控已自动暂停以节省资源。</p>
|
||
<p>如需继续监控,请点击下方按钮恢复连接。</p>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn btn-primary" onclick="resumeMonitoring()">恢复连接</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="/static/monitor/js/monitor.js"></script>
|
||
</body>
|
||
</html> |