MCPcopy Index your code
hub / github.com/XiNian-dada/NodeLite

github.com/XiNian-dada/NodeLite @v3.0.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v3.0.1 ↗ · + Follow
2,299 symbols 6,510 edges 299 files 254 documented · 11% updated 1d agov3.0.2-rc.1 · 2026-07-05★ 5918 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

NodeLite Banner

中文 | English

CI Coverage

NodeLite

NodeLite 是一个用 Rust 编写的轻量级服务器监控面板,包含:

  • nodelite-server 中心服务,提供 WebSocket 接入、只读页面、只读 JSON API、SQLite 短期历史和快照恢复。
  • nodelite-agent Linux / macOS agent,采集 CPU、负载、内存、磁盘、网络总流量、实时速率和 WebSocket RTT。
  • nodelite-proto 服务端与 agent 共用的配置、协议和数据模型。

适合这样的场景:

  • 想要一个像哪吒面板那样“服务端 + 一条命令安装 Agent”的监控系统
  • 想把面板本体做得尽量轻,优先稳定、低占用、易部署
  • 希望网页端以查看为主,敏感配置仍然落在服务端文件与受控入口

快速开始

完整的公开部署文档可直接查看 GitHub Pages: https://xinian-dada.github.io/NodeLite/

版本建议:请始终使用 GitHub Releases 中的最新正式版本(不含 -alpha-beta-rc 标记)。latest 指向的即是最新正式版,pre-release 不会被自动选中。不要在正式环境中使用测试版本。

推荐按下面 3 步体验完整流程:

  1. 安装服务端
curl -fsSL https://github.com/XiNian-dada/NodeLite/releases/latest/download/install-server.sh | sudo sh
  1. 在服务端签发一条子机安装命令
/usr/local/bin/nodelite-server \
  --config /opt/nodelite/config/server.toml \
  install-agent \
  --node-id hk-01 \
  --node-label "Hong Kong 01"
  1. 把上一步打印出的命令粘贴到目标 Linux 子机执行

安装成功后:

  • 面板通过 https://你的域名/ 访问
  • Agent 通过 wss://你的域名/ws 自动接入
  • 历史数据默认保留 14 天

支持平台

  • nodelite-server 推荐部署在 Linux(systemd 环境),官方发布产物提供 x86_64-unknown-linux-muslaarch64-unknown-linux-musl
  • nodelite-agent 支持 Linux 与 macOS;官方发布二进制覆盖 Linux 与 macOS(Intel / Apple Silicon),其中 macOS 的一键安装 / launchd 集成仍属实验性支持,推荐先在测试机验证后再用于长期运行
  • 反向代理 推荐使用 Nginx 或 Caddy 终结 HTTPS / WSS

截图展示

白天模式

首页

首页

系统设置

系统设置页面

告警设置

告警设置页面

账户安全

账户安全页面

节点概览与监控

节点概览与监控页面

监控放大预览

监控放大预览

硬件信息

硬件页面

网络监控

网络页面

Agent 日志

Agent 日志页面

Agent 设置

Agent 设置页面

黑夜模式

首页

首页(黑夜模式)

系统设置

系统设置页面(黑夜模式)

告警设置

告警设置页面(黑夜模式)

账户安全

账户安全页面(黑夜模式)

节点概览与监控

节点概览与监控页面(黑夜模式)

监控放大预览

监控放大预览(黑夜模式)

硬件信息

硬件页面(黑夜模式)

网络监控

网络页面(黑夜模式)

Agent 日志

Agent 日志页面(黑夜模式)

Agent 设置

Agent 设置页面(黑夜模式)

性能表现

运行时占用观察

在 4 个被控端的实际运行环境下,v2.1.2 的长期观测值大致如下:

  • 服务端内存占用:4-10 MB
  • Agent 冷启动内存占用:约 800 KB
  • Agent 运行 24 小时后:约 1.2 MB
  • Agent 运行 72 小时后:约 3 MB

这些数字是观测值,不是固定上限。当前版本的 Agent 常驻内存会随着运行时长增加而缓慢上升,因此 800-1000 KB 更适合被理解为冷启动基线,而不是长时间运行后的稳定占用。

如果你对 Agent 的长期常驻内存敏感,建议在自己的环境中持续观察 RSS 变化并预留余量。

v2.2.6 Release 压测基线

下面这组数据来自 v2.2.6 在同一台机器上对当前版本连续执行 3 次仓库内置 loopback 压测后得到的均值,使用 release 构建直接实测:

cargo test -p nodelite-server --release load_test_scaling_scores -- --ignored --nocapture
cargo test -p nodelite-server --release load_test_api_surface_scores -- --ignored --nocapture
cargo test -p nodelite-server --release load_test_reconnect_storm_scores -- --ignored --nocapture

测试机:Apple M1 Pro / 32 GB / macOS 26.5

这组基线走的是真实 WebSocket 建链、真实 metrics 上报和真实只读 API 轮询,但仍然是单机 loopback,不包含反向代理、TLS 终结和跨机网络抖动。

相较 README 中上一版 v2.2.5 基线,本版本当前样本可见的改进包括:

  • 1000 节点 dashboard fanout 场景下,/api/nodes 响应体从 968995 B 降到 285001 B,约缩小 70.6%
  • 1000 节点 dashboard fanout 场景下,/api/nodes p95 从 12.61 ms 降到 3.51 ms,约下降 72.2%
  • 1000 节点 dashboard fanout 场景下,/metrics p95 从 20.22 ms 降到 7.29 ms,约下降 64.0%
  • 1000 节点 history pressure 场景下,history p95 从 70.90 ms 降到 33.86 ms,约下降 52.2%
  • 500 节点 64 disk entry 场景下,/metrics 响应体从 3146308 B 降到 637182 B,约缩小 79.7%

吞吐与总览延迟

节点数 全部接入耗时 收敛耗时 总 metrics 数 metrics 吞吐 overview p50 overview p95 overview max
20 186.5 ms 22.3 ms 240 10761.2/s 0.45 ms 0.62 ms 0.83 ms
50 456.6 ms 21.7 ms 600 27671.0/s 0.46 ms 0.87 ms 2.72 ms
100 1131.8 ms 22.5 ms 1200 53484.1/s 0.58 ms 1.42 ms 5.01 ms
200 2269.4 ms 36.5 ms 2400 72864.0/s 0.54 ms 5.30 ms 12.55 ms

200 节点读接口延迟

load_test_api_surface_scores 在 steady-state 下持续上报 3600 条 metrics,同时对只读 API 做 20 轮采样;其中历史接口返回的是一个节点 360 个种子历史点对应的精确时间区间。下表同样使用 3 次重复执行后的均值。

接口 p50 p95 max
/api/overview 0.66 ms 2.72 ms 6.54 ms
/api/nodes 0.67 ms 2.93 ms 3.48 ms
/api/nodes/{node_id} 0.66 ms 2.98 ms 3.21 ms
/api/nodes/{node_id}/history 1.59 ms 3.54 ms 4.99 ms

200 节点重连风暴

load_test_reconnect_storm_scores 会把 200 个节点连续拉起和断开 4 轮,共计 800 次会话建立。下面这些数值也使用 3 次重复执行后的均值:

  • 批量接入 p95:1822.13 ms
  • 最后一轮指标恢复 p95:74.66 ms
  • 批量断开完成 p95:22.84 ms
  • 风暴期间 /api/overview p95:2.56 ms
  • 风暴期间 /api/nodes p95:3.12 ms

说明:

  • 这里的“接入耗时”指批量节点建立 WebSocket 并完成认证的时间。
  • “收敛耗时”指最后一轮指标上报完成、服务端状态更新到位的时间。
  • 这组成绩主要用于展示当前版本的大致量级感,不等同于生产 SLA。
  • 实际表现会受到构建模式、反向代理、SQLite I/O、历史保留时长、TLS 和宿主机网络条件影响。

大规模回归压测

下面这组压测默认标记为 ignored,只在手动排查性能回归时运行,不影响默认 CI:

cargo test -p nodelite-server --release load_test_large_fleet_scores -- --ignored --nocapture
cargo test -p nodelite-server --release load_test_dashboard_fanout_scores -- --ignored --nocapture
cargo test -p nodelite-server --release load_test_history_pressure_scores -- --ignored --nocapture
cargo test -p nodelite-server --release load_test_payload_size_scores -- --ignored --nocapture

覆盖范围:

  • load_test_large_fleet_scores500 / 1000 节点 loopback WebSocket 上报,同时采样 /api/overview/api/nodes 和 Prometheus /metrics
  • load_test_dashboard_fanout_scores1000 节点、20 个 dashboard reader 并发刷新,并穿插 Prometheus scrape。
  • load_test_history_pressure_scores1000 节点下对历史查询做并发 reader 压力,覆盖 SQLite 读写竞争。
  • load_test_payload_size_scores500 节点、每节点 64 个 disk entry,观察大 payload 的 API body 和渲染前置压力。

每条 *_RESULT 输出都会包含对应场景的 p95 延迟、API body bytes 的 p50/p95/max、当前进程 RSS、history writer queue depth、dropped writes,以及 SQLite db/wal/shm 文件大小。

下面这张表仍然是本次同机实测的单次样本结果,用来展示更大规模场景的大致量级,不作为多轮均值基线:

场景 关键规模 metrics 吞吐 关键 p95 响应体大小 RSS history dropped writes
load_test_large_fleet_scores 500 节点 68678.5/s overview 1.18 ms / nodes 1.67 ms / metrics 7.55 ms overview 257 B / nodes 142501 B / metrics 637186 B 194.8 MiB 0
load_test_large_fleet_scores 1000 节点 89675.3/s overview 1.56 ms / nodes 4.08 ms / metrics 18.54 ms overview 261 B / nodes 285001 B / metrics 1264700 B 335.7 MiB 0
load_test_dashboard_fanout_scores 1000 节点 + 20 readers 88934.8/s overview 2.08 ms / nodes 3.51 ms / metrics 7.29 ms overview 261 B / nodes 285001 B / metrics 1264700 B 337.9 MiB 0
load_test_history_pressure_scores 1000 节点 + 20 history readers 90773.1/s history 33.86 ms history 50823 B 334.6 MiB 0
load_test_payload_size_scores 500 节点 + 64 disk entries 43559.1/s nodes 1.55 ms / metrics 14.81 ms nodes 142501 B / metrics 637182 B 222.8 MiB 0

首页 DOM 渲染压力可以用真实 nodelite-server/assets/index.html 生成自包含 fixture:

node scripts/benchmark-index-dom.mjs --nodes 500
node scripts/benchmark-index-dom.mjs --nodes 1000

脚本会写入 target/load-test/index-dom-*.html。用浏览器打开生成文件后,页面右下角会显示 renderMsjsHeapBytesdomNodeCountnodeCardCount,同一份结果也会挂到 window.__NODELITE_DOM_BENCHMARK__ 便于控制台读取。需要模拟大磁盘 payload 时可追加 --disks 64

当前能力

  • 一键安装与升级:
  • install-server.sh
  • install-agent.sh
  • nodelite-server install-agent
  • nodelite-server upgrade-agent
  • 服务端只读页面:
  • /
  • /nodes/{node_id}
  • 服务端只读 API:
  • /api/overview
  • /api/nodes
  • /api/nodes/{node_id}
  • /api/nodes/{node_id}/history
  • agent 接入协议:
  • hello
  • metrics
  • ping
  • pong
  • server_notice
  • refresh_token_request
  • refresh_token_response
  • 设置页:
  • 查看服务端版本、路径、历史保留与节点 token 到期时间
  • 修改只读面板密码
  • 启用 / 禁用 TOTP 2FA
  • 手动触发服务端更新并查看更新日志
  • 14 天 SQLite 历史保留
  • 快照落盘与进程重启后恢复最近状态
  • agent 指数退避自动重连

历史数据语义

历史图用于展示基础趋势,不是逐条 metrics 上报的完整归档。Server 默认同一节点每 30 秒最多写入一个历史点,并在查询时按时间窗口和 max_points 返回适合绘图的采样结果。

历史写入走 bounded queue + batch SQLite writer。队列满时 Server 会优先保证实时 WebSocket 心跳和面板当前状态,丢弃该次历史写入并递增 /metrics 中的 nodelite_history_dropped_writes_total。这个值长期应为 0;如果持续增长,说明历史 writer 跟不上上报速率或磁盘 I/O,历史图可能出现缺口,但实时视图仍会继续更新。

本地构建

cargo check

Prometheus 抓取

NodeLite 现在提供受保护的 /metrics 端点,输出 Prometheus exposition text。它和仪表盘共用只读认证,因此抓取端需要带上同一组 Basic Auth 凭据。

默认 /metrics 只导出 server / overview 聚合和少量 node summary 指标,避免大规模集群下 scrape 响应体过大。如果需要按节点导出 CPU、uptime、memory、load、network 等最新快照细节,可在 server.toml[metrics] 中设置 export_node_resource_metrics = true;如果还需要按挂载点导出磁盘指标,再设置 export_node_disk_metrics = true。这些开关会按节点数和挂载点数量增加 series 与响应体大小,建议只在确实需要 Prometheus 长期采集这些细节时开启。

先用 curl 验证:

curl -u viewer:secret https://monitor.example.com/metrics

Prometheus 示例:

scrape_configs:
  - job_name: nodelite
    scheme: https
    metrics_path: /metrics
    basic_auth:
      username: viewer
      password: secret
    static_configs:
      - targets:
          - monitor.example.com

常用运维指标:

  • nodelite_history_dropped_writes_total: 历史写入队列满时丢弃的历史点总数。
  • nodelite_history_queue_depth / nodelite_history_queue_capacity: 历史 writer 当前排队量与队列容量。
  • nodelite_audit_dropped_writes_total: 审计写入队列满时丢弃的审计事件总数。
  • nodelite_audit_queue_depth / nodelite_audit_queue_capacity: 审计 writer 当前排队量与队列容量。
  • nodelite_audit_write_failures_total: 审计 writer 入队或落库失败总数。
  • nodelite_view_cache_hits_total{kind} / nodelite_view_cache_misses_total{kind}: overviewnodesmetrics 视图响应体缓存命中与未命中次数。
  • nodelite_api_body_bytes{kind} / nodelite_metrics_response_body_bytes: 最近一次构建的 API、基础 /metrics 与最终 /metrics 响应体大小。
  • nodelite_process_resident_memory_bytes: Server 进程 RSS,用于定位常驻内存增长。
  • nodelite_sqlite_file_bytes{kind}: history/audit SQLite 主文件、WAL 与 SHM 文件大小。
  • nodelite_sqlite_wal_checkpoint_observed{database}: 最近一次 passive WAL checkpoint probe 是否成功。
  • nodelite_sqlite_wal_checkpoint_active{database}: SQLite 库当前是否处于 WAL journal mode。
  • nodelite_sqlite_wal_checkpoint_busy{database}: PRAGMA wal_checkpoint(PASSIVE) 返回的 busy 标志。
  • nodelite_sqlite_wal_checkpoint_pages{database,state}: logcheckpointedbacklog WAL 页数。backlog 持续增长且 WAL 文件 bytes 同步增长时,通常说明 checkpoint 被长读事务或磁盘 I/O 拖住。
  • nodelite_registry_nodes: 当前加载的注册节点数量。
  • nodelite_registry_disk_entries_total: 当前节点快照中持有的磁盘条目总数。
  • nodelite_ws_messages_total{type}: 已认证 WebSocket 消息按类型累计计数。

SQLite 运维提示:

  • History 使用 WAL 模式提升写入/查询并发,/metrics 会最多每 60 秒执行一次受控的 wal_checkpoint(PASSIVE) probe。PASSIVE 不会截断 WAL,也不会等待其它连接释放锁;它会尝试推进可 checkpoint 的 WAL 页,并返回当前 WAL 页数、已 checkpoint 页数和 busy 状态。
  • History 和 Audit 的 retention prune 使用 DELETE 删除过期行。SQLite 主库文件不会因为 DELETE 立即缩小,WAL 也可能在 checkpoint 前保持较大;这属于 SQLite 的正常文件复用行为。
  • nodelite_sqlite_file_bytes{kind="history_wal"}kind="audit_wal" 持续增长时,建议同时告警 nodelite_sqlite_wal_checkpoint_pages{state="backlog"} 和 busy 标志,用来区分写入增长、checkpoint 被阻塞和外部磁盘问题。
  • 如需回收主库文件空洞,在维护窗口停止服务或确保无长事务后手动执行 VACUUM;如需强制截断 WAL,应在维护窗口对目标库执行 PRAGMA wal_checkpoint(TRUNCATE)。不要在高峰期把这些操作放进自动热路径。

测试覆盖率

安装 cargo-tarpaulin(仅需一次,仅支持 Linux):

cargo install cargo-tarpaulin

运行覆盖率分析:

cargo tarpaulin --config tarpaulin.toml

HTML 报告输出到 target/tarpaulin/tarpaulin-report.html,可用浏览器打开查看逐行覆盖情况。

覆盖率目标

阶段 目标 时间
基线 记录当前值 立即
短期 75% 2 周内
长期 80% 持续

重点覆盖模块:auth、admission、sanitize、registry(安全关键路径)。

如需单独跑新增的属性测试,可直接使用:

cargo test -p nodelite-server sanitize::tests
cargo test -p nodelite-server registry::tests

协议解析 fuzz smoke

fuzz/ 是独立的 Cargo crate,不属于默认 workspace,因此不会被普通 cargo test --workspace 编译。它覆盖外部 WebSocket 文本帧的 JSON 解析入口: WireMessage(Agent 通道)和 BrowserMessage(浏览器通道)。

常用手动验证命令:

cargo test --manifest-path fuzz/Cargo.toml
cargo run --manifest-path fuzz/Cargo.toml --bin wire_message -- fuzz/corpus/protocol_messages
cargo run --manifest-path fuzz/Cargo.toml --bin browser_message -- fuzz/corpus/protocol_messages
cargo run --manifest-path fuzz/Cargo.toml --bin protocol_messages -- 10000

其中 protocol_messages 使用固定种子的伪随机输入跑指定迭代数,适合在本地或 定期任务中做“任意输入不崩溃”的快速 smoke;真实崩溃应以能复现的 corpus 文件 形式加入 fuzz/corpus/protocol_messages/

交叉编译 Linux x86_64 / aarch64

仓库内已经包含 musl 目标的 lld 链接配置,可以直接构建静态 Linux 二进制:

cargo build --release --target x86_64-unknown-linux-musl \
  -p nodelite-server \
  -p nodelite-agent

cargo build --release --target aarch64-unknown-linux-musl \
  -p nodelite-server \
  -p nodelite-agent

产物位置:

target/x86_64-unknown-linux-musl/release/nodelite-server
target/x86_64-unknown-linux-musl/release/nodelite-agent
target/aarch64-unknown-linux-musl/release/nodelite-server
target/aarch64-unknown-linux-musl/release/nodelite-agent

推荐部署拓扑

生产环境建议这样放:

  1. nodelite-server 监听在 127.0.0.1:8080
  2. Nginx 或 Caddy 对外暴露 443
  3. 面板和 API 走 HTTPS
  4. Agent 通过 wss://你的域名/ws 接入

这样可以把 TLS、访问日志、限流和基础访问控制都放到反代层。

服务端部署

推荐直接用 GitHub Release 里的交互式安装器。它会清

Extension points exported contracts — how you extend this code

AlertSettingsViewOverrides (Interface)
Override shape for the alert View fixture: nested channels accept partials.
nodelite-server/web/src/api/__fixtures__/nodes.ts
AsyncReadWrite (Interface)
(no doc) [1 implementers]
nodelite-server/src/alerts/delivery/webhook.rs
NodeHistoryEntry (Interface)
(no doc)
nodelite-server/web/src/stores/nodeHistory.ts
LocaleRef (Interface)
(no doc)
nodelite-server/web/src/i18n/language.ts
EffectiveGeoLocation (Interface)
(no doc)
nodelite-server/web/src/lib/nodeMeta.ts
UptimeParts (Interface)
(no doc)
nodelite-server/web/src/lib/format.ts

Core symbols most depended-on inside this repo

len
called by 126
nodelite-server/src/admission.rs
push
called by 123
nodelite-agent/src/session.rs
is_empty
called by 88
nodelite-agent/src/session.rs
get
called by 87
nodelite-server/src/state/view_cache.rs
load
called by 86
nodelite-server/src/registry/lifecycle.rs
makeNode
called by 64
nodelite-server/web/src/api/__fixtures__/nodes.ts
makeNodeStatus
called by 62
nodelite-server/web/src/api/__fixtures__/nodes.ts
trim
called by 60
nodelite-server/src/admission.rs

Shape

Function 1,528
Method 391
Class 254
Interface 85
Enum 41

Languages

Rust81%
TypeScript19%

Modules by API surface

nodelite-server/src/state.rs53 symbols
nodelite-server/src/admission.rs48 symbols
nodelite-proto/src/config/defaults.rs47 symbols
nodelite-server/assets/index-alert-settings.js46 symbols
nodelite-server/web/src/api/types.ts45 symbols
nodelite-server/src/state/registry.rs45 symbols
nodelite-server/src/geoip.rs43 symbols
nodelite-server/src/test_support.rs42 symbols
nodelite-server/src/auth.rs41 symbols
nodelite-server/src/handlers/metrics_exporter.rs37 symbols
nodelite-server/src/handlers/auth_routes.rs35 symbols
nodelite-server/src/alerts/delivery/webhook.rs34 symbols

For agents

$ claude mcp add NodeLite \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact