82 lines
23 KiB
HTML
82 lines
23 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<meta name="color-scheme" content="dark"><title>设备监控 · 192.168.1.37</title>
|
||
<link rel="icon" href="/favicon.svg"><link rel="stylesheet" href="/style.css">
|
||
<script src="/app.js" defer></script><script src="/tasks.js" defer></script>
|
||
</head>
|
||
<body>
|
||
<svg class="sprite" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
|
||
<symbol id="pulse" viewBox="0 0 24 24"><path d="M2 13h5l3-8 5 15 3-9h4"/></symbol>
|
||
<symbol id="grid" viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></symbol>
|
||
<symbol id="trend" viewBox="0 0 24 24"><path d="M3 3v18h18M6 15l5-5 4 3 6-8"/></symbol>
|
||
<symbol id="logs" viewBox="0 0 24 24"><path d="M7 3H4v18h16V3h-3M9 3h6v4H9zM8 11h8M8 15h8"/></symbol>
|
||
<symbol id="help" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M9 9a3 3 0 0 1 6 0c0 2-3 2-3 4M12 17h.01"/></symbol>
|
||
<symbol id="cpu" viewBox="0 0 24 24"><rect x="6" y="6" width="12" height="12" rx="2"/><path d="M9 1v5m6-5v5M9 18v5m6-5v5M1 9h5m-5 6h5m12-6h5m-5 6h5M9 9h6v6H9z"/></symbol>
|
||
<symbol id="memory" viewBox="0 0 24 24"><rect x="2" y="6" width="20" height="12" rx="2"/><path d="M6 10v4m4-4v4m4-4v4m4-4v4M6 18v3m4-3v3m4-3v3m4-3v3"/></symbol>
|
||
<symbol id="gpu" viewBox="0 0 24 24"><rect x="3" y="5" width="18" height="13" rx="2"/><circle cx="10" cy="11.5" r="3.5"/><path d="M16 9h2m-2 4h2M6 18v3m3-3v3m3-3v3m3-3v3M3 8H1"/></symbol>
|
||
<symbol id="disk" viewBox="0 0 24 24"><path d="m5 3-3 13v5h20v-5L19 3zM2 16h20M6 18.5h.01m4-.01h.01"/></symbol>
|
||
<symbol id="full" viewBox="0 0 24 24"><path d="M3 9V3h6m6 0h6v6M3 15v6h6m6 0h6v-6"/></symbol>
|
||
<symbol id="check" viewBox="0 0 24 24"><path d="m5 12 4 4L19 6"/></symbol>
|
||
<symbol id="alert" viewBox="0 0 24 24"><path d="M12 3 2 21h20zM12 9v5m0 3v.1"/></symbol>
|
||
<symbol id="clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M12 6v6l4 2"/></symbol>
|
||
<symbol id="download" viewBox="0 0 24 24"><path d="M12 3v12m-4-4 4 4 4-4M4 16v5h16v-5"/></symbol>
|
||
</svg>
|
||
<aside class="sidebar">
|
||
<a class="brand" href="#overview" data-section-link="overview"><span class="brand-mark"><svg><use href="#pulse"/></svg></span><span>设备监控<small>HARDWARE WATCH</small></span></a>
|
||
<div class="nav-caption">工作空间</div>
|
||
<nav aria-label="主导航">
|
||
<a href="#overview" class="active" data-section-link="overview" aria-current="location"><svg><use href="#grid"/></svg>设备总览</a>
|
||
<a href="#trends" data-section-link="trends"><svg><use href="#trend"/></svg>性能趋势</a>
|
||
<a href="#events" data-section-link="events"><svg><use href="#logs"/></svg>问题与维护<span id="nav-alert" class="nav-count" hidden></span></a>
|
||
<a href="#tasks" data-section-link="tasks"><svg><use href="#clock"/></svg>定时任务</a>
|
||
<a href="#guide" data-section-link="guide"><svg><use href="#help"/></svg>使用说明</a>
|
||
</nav>
|
||
<div class="sidebar-node"><span class="tiny-label">正在监控</span><strong><i class="dot"></i> NODE / 037</strong><span>192.168.1.37</span><div class="node-rule"></div><p>实时状态 · 性能历史<br>设备告警 · 维护建议</p></div>
|
||
<div class="sidebar-footer"><span class="dot"></span> 局域网设备监控</div>
|
||
</aside>
|
||
<main>
|
||
<header class="page-header" id="overview"><div><div class="eyebrow">基础设施 / 设备总览</div><h1>设备运行,一目了然<span class="title-dot">.</span></h1><p>192.168.1.37 <span class="separator">/</span> <span id="host-name">正在连接设备</span></p></div><div class="header-actions"><span class="live-badge" id="connection"><i class="dot"></i>连接中</span><button id="fullscreen" class="icon-button" aria-label="切换全屏"><svg><use href="#full"/></svg></button></div></header>
|
||
<div class="section-context"><div><span class="context-label">正在查看</span><strong id="current-section">设备总览</strong></div><div class="context-actions"><button id="back-to-top" class="context-button" hidden>↑ 回到顶部</button><button id="next-section" class="context-button">下一项:性能趋势 ↓</button></div><div class="reading-progress"><i id="reading-progress"></i></div></div>
|
||
<section class="health-banner loading" id="health-banner" aria-live="polite"><div class="health-icon"><svg id="health-icon"><use href="#pulse"/></svg></div><div class="health-text"><strong id="health-title">正在读取设备状态</strong><p id="health-description">首次连接可能需要几秒,请稍候。</p></div><div class="health-time"><span>最近更新</span><strong id="last-update">—</strong></div></section>
|
||
<section id="current-issues" class="current-issues" aria-label="当前需要处理的问题" hidden></section>
|
||
<section class="overview-grid" aria-label="设备关键指标">
|
||
<article class="metric-card"><div class="card-top"><span>CPU 使用率</span><svg><use href="#cpu"/></svg></div><div class="metric-value" id="cpu-value">—<small>%</small></div><div class="meter"><i id="cpu-bar"></i></div><div class="metric-bottom"><span id="cpu-threads">正在读取</span><strong id="cpu-temp">— °C</strong></div></article>
|
||
<article class="metric-card"><div class="card-top"><span>内存占用</span><svg><use href="#memory"/></svg></div><div class="metric-value" id="memory-value">—<small>%</small></div><div class="meter violet"><i id="memory-bar"></i></div><div class="metric-bottom"><span id="memory-used">— / — GiB</span><strong id="memory-free">— 可用</strong></div></article>
|
||
<article class="metric-card"><div class="card-top"><span>计算显卡</span><svg><use href="#gpu"/></svg></div><div class="metric-value" id="gpu-count">—<small>/ — 在线</small></div><div class="gpu-online-label" id="gpu-online-text"><i class="dot"></i>正在确认显卡状态</div><div class="metric-bottom"><span>按 UUID 识别显卡</span><strong id="gpu-type">NVIDIA</strong></div></article>
|
||
<article class="metric-card"><div class="card-top"><span>系统磁盘</span><svg><use href="#disk"/></svg></div><div class="metric-value word" id="disk-health">—</div><div class="disk-health-detail" id="disk-health-detail">正在读取健康状态</div><div class="metric-bottom"><span id="disk-space">— / — GiB</span><strong id="disk-temp">— °C</strong></div></article>
|
||
</section>
|
||
<section class="section-heading compact"><div><h2>显卡实时状态</h2><span>高使用率表示正在计算,不等于硬件故障。</span></div><span class="subtle-pill">每 10 秒采样</span></section>
|
||
<section class="gpu-grid" id="gpu-grid" aria-label="计算显卡实时状态"><article class="gpu-card skeleton">正在读取显卡…</article><article class="gpu-card skeleton">正在读取显卡…</article></section>
|
||
<section class="system-strip" aria-label="其他实时指标"><span><svg><use href="#clock"/></svg>连续运行 <strong id="uptime">—</strong></span><span>磁盘读取 <strong id="disk-read">— MB/s</strong></span><span>磁盘写入 <strong id="disk-write">— MB/s</strong></span><span>网络接收 <strong id="net-rx">— MB/s</strong></span><span>网络发送 <strong id="net-tx">— MB/s</strong></span></section>
|
||
<section id="trends" class="section-heading"><div><div class="eyebrow">PERFORMANCE</div><h2>性能趋势</h2><p id="history-caption">正在加载历史数据</p></div><div class="segmented" id="ranges" role="group" aria-label="曲线时间范围"><button data-range="1h">1 小时</button><button data-range="6h">6 小时</button><button data-range="24h" class="selected">24 小时</button><button data-range="7d">7 天</button><button data-range="30d">30 天</button></div></section>
|
||
<div class="history-note" id="history-note">历史曲线显示真实采样数据;没有采集到的时段留空。</div>
|
||
<section class="chart-grid" aria-label="历史性能曲线">
|
||
<article class="chart-card"><div class="chart-heading"><h3>CPU 与内存</h3><span>%</span></div><div class="chart-legend" id="legend-system"></div><div class="chart" id="chart-system" role="img" aria-label="CPU 和内存占用历史曲线"></div></article>
|
||
<article class="chart-card"><div class="chart-heading"><h3>显卡使用率</h3><span>%</span></div><div class="chart-legend" id="legend-gpu"></div><div class="chart" id="chart-gpu" role="img" aria-label="显卡使用率历史曲线"></div></article>
|
||
<article class="chart-card"><div class="chart-heading"><h3>硬件温度</h3><span>°C</span></div><div class="chart-legend" id="legend-temp"></div><div class="chart" id="chart-temp" role="img" aria-label="CPU 与显卡温度历史曲线"></div></article>
|
||
<article class="chart-card"><div class="chart-heading"><h3>显卡功耗</h3><span>W</span></div><div class="chart-legend" id="legend-power"></div><div class="chart" id="chart-power" role="img" aria-label="显卡功耗历史曲线"></div></article>
|
||
</section>
|
||
<section id="events" class="section-heading"><div><div class="eyebrow">EVENTS & MAINTENANCE</div><h2>问题与维护</h2><p>先看设备现在能不能用,再看什么时候出现、下一步怎么处理。</p></div><button class="text-button" id="export-events"><svg><use href="#download"/></svg>导出本页</button></section>
|
||
<div class="event-explainer"><strong>重复日志已合并,不代表设备坏了很多次。</strong><span>同一设备、同类问题在 5 分钟内继续报告,会归在同一段记录中。黄色表示需要观察或安排检查,不等于显卡已经损坏。</span></div>
|
||
<section class="event-panel"><form class="event-toolbar" id="event-filter"><label>展示方式<select id="event-view"><option value="issues">按问题合并(推荐)</option><option value="raw">逐条技术记录</option></select></label><label>问题类型<select id="category"><option value="">全部问题</option></select></label><label>级别<select id="severity"><option value="problem">需要关注与处理</option><option value="ERROR">需要处理</option><option value="WARN">需要关注</option><option value="INFO">开机等运行记录</option><option value="">所有记录</option></select></label><label>开始日期<input type="date" id="date-from"></label><label>结束日期<input type="date" id="date-to"></label><label class="search-label">搜索<input type="search" id="event-search" placeholder="例如:供电、连接重试、磁盘"></label><button class="primary-button" type="submit">查询日志</button></form><div class="event-caption"><span id="event-count">正在读取问题记录…</span><span>展开看中文说明;技术详情默认收起</span></div><div id="event-list" aria-live="polite"></div><div class="pagination"><span id="page-label">第 1 页</span><div><button id="previous-page" class="text-button" disabled>上一页</button><button id="next-page" class="text-button" disabled>下一页</button></div></div></section>
|
||
<section id="tasks" class="section-heading"><div><div class="eyebrow">SCHEDULED TASKS</div><h2>定时任务</h2><p>到点自动执行命令或脚本,关闭网页也会继续运行。时间均为北京时间。</p></div><button class="primary-button" id="task-create" disabled>+ 新增任务</button></section>
|
||
<section class="task-panel" aria-label="服务器定时任务管理">
|
||
<div class="task-authbar"><div><strong id="task-auth-title">正在连接任务管理服务</strong><p id="task-auth-description">监控页面可直接查看,管理任务需要登录。</p></div><div class="task-auth-actions"><button id="task-login-open" class="primary-button">登录管理</button><button id="task-change-password" class="text-button" hidden>修改密码</button><button id="task-logout" class="text-button" hidden>退出管理</button></div></div>
|
||
<div id="task-locked" class="task-empty"><svg><use href="#clock"/></svg><h3>把重复维护交给计划任务</h3><p>支持命令、Bash/Python 脚本和服务器已有脚本。<br>可用于定时检查、备份、证书续签或计划重启。</p><span>初始管理员登录信息见交付的登录说明文件,账号与 SSH 密码相互独立。</span></div>
|
||
<div id="task-manager" hidden><div class="task-toolbar"><div><strong id="task-count">任务列表</strong><span id="task-server-time"></span></div><div><button id="task-refresh" class="text-button">刷新</button><button id="task-all-runs" class="text-button">全部执行记录</button></div></div><div class="task-table-heading"><span>任务名称</span><span>执行周期 / 下次执行</span><span>状态 / 最近结果</span><span>操作</span></div><div id="task-list"></div><div class="task-footnote">执行身份为 root。新任务默认停用;启用后才会按计划执行。同一任务不会重叠运行,错过时间不补跑。</div></div>
|
||
</section>
|
||
<section class="guide" id="guide"><div><svg><use href="#help"/></svg><h2>第一次使用?先看状态,再看问题</h2></div><div class="guide-grid"><article><span class="guide-number">01</span><h3>顶部看现在是否正常</h3><p>绿色表示当前检查未发现异常。黄色表示需要关注,红色表示有故障需要处理。断开连接时会单独提示,不继续显示“正常”。</p></article><article><span class="guide-number">02</span><h3>曲线看何时开始变化</h3><p>选择时间范围,移到曲线上查看具体时刻。使用率高通常说明任务繁忙;温度、掉卡和通信错误才需要结合告警判断。</p></article><article><span class="guide-number">03</span><h3>维护操作先看执行内容</h3><p>问题记录有处理建议。定时任务可以真正执行服务器操作,保存前请检查脚本、周期和启用状态;重启类任务会中断正在进行的计算。</p></article></div></section>
|
||
<footer><span>设备监控 / NODE 037</span><span>性能数据保留 30 天 · 故障记录最长保留 90 天 · 北京时间 UTC+8</span></footer>
|
||
</main>
|
||
<div class="toast" role="status" id="toast" hidden></div>
|
||
<nav class="mobile-section-nav" aria-label="页面分区导航"><a href="#overview" data-section-link="overview" class="active"><svg><use href="#grid"/></svg>总览</a><a href="#trends" data-section-link="trends"><svg><use href="#trend"/></svg>趋势</a><a href="#events" data-section-link="events"><svg><use href="#logs"/></svg>问题</a><a href="#tasks" data-section-link="tasks"><svg><use href="#clock"/></svg>任务</a><a href="#guide" data-section-link="guide"><svg><use href="#help"/></svg>说明</a></nav>
|
||
<dialog id="task-login-dialog" class="task-dialog small-dialog" aria-labelledby="task-login-heading"><form id="task-login-form"><div class="dialog-heading"><div><h2 id="task-login-heading">登录任务管理</h2><p>只有管理员可以创建和执行服务器任务。</p></div><button type="button" class="dialog-close" data-close-dialog="task-login-dialog" aria-label="关闭登录窗口">×</button></div><div class="dialog-content task-form-grid"><label class="full-field">账号<input id="task-login-user" value="admin" autocomplete="username" required></label><label class="full-field">管理密码<input id="task-login-password" type="password" autocomplete="current-password" required></label><p class="form-error full-field" id="task-login-error" role="alert" hidden></p></div><div class="dialog-footer"><span>此处不是 SSH root 密码。</span><button class="primary-button" type="submit">登录</button></div></form></dialog>
|
||
<dialog id="task-editor-dialog" class="task-dialog" aria-labelledby="task-editor-heading"><form id="task-editor-form"><div class="dialog-heading"><div><h2 id="task-editor-heading">新增定时任务</h2><p>先填写执行内容,再设置周期。新任务默认停用,可先手动测试。</p></div><button type="button" class="dialog-close" data-close-dialog="task-editor-dialog" aria-label="关闭任务编辑">×</button></div><div class="dialog-content task-form-grid"><input id="task-id" type="hidden"><label>任务名称<input id="task-name" placeholder="例如:每天检查显卡" maxlength="80" required></label><label>快速模板<select id="task-template"><option value="custom">自定义任务</option><option value="hardware">显卡状态检查</option><option value="reboot">服务器定时重启</option><option value="certificate">SSL 证书续签示例</option></select></label><div class="template-hint full-field" id="task-template-hint" hidden></div><label>执行方式<select id="task-mode"><option value="command">直接输入命令</option><option value="script">粘贴脚本内容</option><option value="file">服务器上的脚本文件</option></select></label><label id="task-language-field">脚本解释器<select id="task-interpreter"><option value="bash">Bash / Shell</option><option value="python3">Python 3</option><option value="auto">按文件自身方式执行</option></select></label><label class="full-field" id="task-body-field"><span class="field-label-row"><span id="task-body-label">执行命令</span><button type="button" id="task-import-file" class="inline-button">导入本地脚本</button></span><textarea id="task-body" rows="7" spellcheck="false" placeholder="例如:/usr/bin/nvidia-smi" required></textarea><input id="task-upload" type="file" accept=".sh,.py,.txt" hidden></label><label class="full-field" id="task-path-field" hidden>服务器脚本的绝对路径<input id="task-path" placeholder="例如:/root/renew-cert.sh"></label><label class="full-field" id="task-arguments-field" hidden>脚本参数(可选)<input id="task-arguments" placeholder="例如:--check,带空格的参数请加引号"></label><div class="task-form-divider full-field"><strong>什么时候执行</strong><span>北京时间 UTC+8</span></div><label>执行周期<select id="task-cycle"><option value="daily">每天</option><option value="weekly">每周</option><option value="monthly">每月</option><option value="minutes">每隔若干分钟</option><option value="hours">每隔若干小时</option><option value="once">指定日期,仅执行一次</option><option value="cron">自定义 Cron(五段)</option></select></label><label data-task-cycle="daily weekly monthly">执行时间<input type="time" id="task-time" value="03:00"></label><label data-task-cycle="monthly" hidden>每月几日<input id="task-day" type="number" value="1" min="1" max="31"><small>当月没有该日期时会跳过。</small></label><label data-task-cycle="minutes hours" hidden>间隔数值<input id="task-every" type="number" value="60" min="1" max="1440"><small>从启用任务开始计时。</small></label><label class="full-field" data-task-cycle="once" hidden>指定执行时间<input id="task-once" type="datetime-local"></label><div class="weekday-field full-field" data-task-cycle="weekly" hidden><span>选择星期</span><div id="task-weekdays"><label><input type="checkbox" value="0" checked>一</label><label><input type="checkbox" value="1">二</label><label><input type="checkbox" value="2">三</label><label><input type="checkbox" value="3">四</label><label><input type="checkbox" value="4">五</label><label><input type="checkbox" value="5">六</label><label><input type="checkbox" value="6">日</label></div></div><label class="full-field" data-task-cycle="cron" hidden>Cron 表达式<input id="task-cron" value="0 3 * * *" spellcheck="false"><small>分 时 日 月 周,例如 0 3 * * * 表示每天 03:00。支持范围、列表和 */步长。</small></label><div class="schedule-preview full-field"><button type="button" class="text-button" id="task-preview">检查执行周期</button><span id="task-preview-text">错过执行时间不补跑;同一任务不会重叠执行。</span></div><details class="full-field task-advanced"><summary>高级设置(可选)</summary><div class="task-form-grid"><label>工作目录<input id="task-cwd" value="/root"></label><label>最长执行秒数<input id="task-timeout" type="number" value="1800" min="10" max="86400"></label><label class="full-field">备注<input id="task-notes" maxlength="400" placeholder="记录维护用途、域名或注意事项"></label></div></details><label class="task-enabled-field full-field"><input id="task-enabled" type="checkbox"><span>保存后启用,到计划时间自动执行<small>不勾选时仅保存,可先手动测试。执行身份:root。</small></span></label><p class="form-error full-field" id="task-editor-error" role="alert" hidden></p></div><div class="dialog-footer"><span>保存不会立即执行脚本。</span><div><button type="button" class="text-button" data-close-dialog="task-editor-dialog">取消</button><button type="submit" class="primary-button" id="task-save">保存任务</button></div></div></form></dialog>
|
||
<dialog id="task-confirm-dialog" class="task-dialog small-dialog" aria-labelledby="task-confirm-heading"><div class="dialog-heading"><h2 id="task-confirm-heading">确认操作</h2></div><div class="dialog-content"><p id="task-confirm-message"></p><pre id="task-confirm-code" class="raw-log" hidden></pre></div><div class="dialog-footer"><button id="task-confirm-no" class="text-button">取消</button><button id="task-confirm-yes" class="primary-button">确认</button></div></dialog>
|
||
<dialog id="task-runs-dialog" class="task-dialog log-dialog" aria-labelledby="task-runs-heading"><div class="dialog-heading"><div><h2 id="task-runs-heading">任务执行记录</h2><p>成功表示命令退出码为 0,具体业务结果仍以输出为准。</p></div><button type="button" class="dialog-close" data-close-dialog="task-runs-dialog" aria-label="关闭执行记录">×</button></div><div class="run-layout"><div id="task-runs-list" class="task-runs-list"></div><div class="task-run-output"><div id="task-run-meta" class="task-run-meta">选择一次执行,查看输出和错误。</div><pre id="task-run-output">尚未选择执行记录。</pre></div></div></dialog>
|
||
<dialog id="task-password-dialog" class="task-dialog small-dialog" aria-labelledby="task-password-heading"><form id="task-password-form"><div class="dialog-heading"><h2 id="task-password-heading">修改任务管理密码</h2><button type="button" class="dialog-close" data-close-dialog="task-password-dialog" aria-label="关闭密码窗口">×</button></div><div class="dialog-content task-form-grid"><label class="full-field">原管理密码<input type="password" id="task-old-password" autocomplete="current-password" required></label><label class="full-field">新密码(至少 12 个字符)<input type="password" id="task-new-password" autocomplete="new-password" minlength="12" required></label><label class="full-field">再次输入新密码<input type="password" id="task-repeat-password" autocomplete="new-password" minlength="12" required></label><p class="form-error full-field" id="task-password-error" hidden></p></div><div class="dialog-footer"><span>修改后需要重新登录。</span><button type="submit" class="primary-button">保存新密码</button></div></form></dialog>
|
||
</body>
|
||
</html>
|