NAS Traffic Lens 是一个面向家庭 NAS 的轻量网络监控面板:实时公网流量、进程与 Docker 归因、容器保护与告警通知,并内置一个只读运维助手——用一句话就能查"今天公网上传了多少流量""最近哪个进程上传最多""哪个容器在大量读写磁盘"。
已在 极空间 Z425(x86,i915 核显 + Intel NPU) 与 绿联 DXP4300 Plus(ARM,Mali GPU + RKNPU + VPU) 上实机验证,同一镜像同时提供 linux/amd64 与 linux/arm64,通用 Linux 与飞牛 OS 使用通用模板即可。各平台的能力差异与部署步骤见 多 NAS 兼容性说明。
Windows / macOS 另有 Traffic Lens 0.5.0 桌面预览版:无需 Docker,可查看本机基础资源与网卡总流量、使用本机 AI 分析,也可保存并切换多台 NAS。每台 NAS 可选择客户端布局或网页布局,完整使用其 Docker、AI、监控和系统页面。各端新增服务导航,支持分组、搜索、图标与地址维护,Docker Web 端口可一键加入导航。桌面端支持从 GitHub 检查并安装签名更新。
桌面版不包含本机公网归属、进程网络流量和传感器采集;完整能力与构建方法见 桌面客户端使用与构建。Mac Apple Silicon / Intel 和 Windows x64 安装包见 桌面 Releases;跨平台签名更新包由 GitHub Actions 编译。NAS 导航需要更新 Docker 镜像,Compose 不需要新增环境变量或挂载。
当前项目已经拆分为前后端:
front-end/:Vue 3 + Vite 前端。server/:FastAPI 后端、采集器、SQLite 存储、通知模块。doc/:更细的功能设计和运行说明。docker-compose.yml:本地构建测试用。docker-compose.nas.yml:NAS 部署推荐模板。
仓库提供符合 Agent Skills 格式的 nas-traffic-lens。它让支持该格式的 Agent 按需查询流量、历史、进程、系统、容器和告警,也可按明确指令修改单条监控或容器保护规则,以及重启指定容器。查询和操作不调用内置 AI 模型。
在安装了 Codex 的其他机器上,可让 Codex 使用 $skill-installer 安装 isle24/datatotal 中的 .agents/skills/nas-traffic-lens,也可以直接运行:
python3 "${CODEX_HOME:-$HOME/.codex}/skills/.system/skill-installer/scripts/install-skill-from-github.py" \
--repo isle24/datatotal --path .agents/skills/nas-traffic-lens安装完成后,在新的 Codex 对话或下一轮中使用 $nas-traffic-lens。查询需要 NAS 的访问地址和认证;修改规则或重启容器还需要支持 Agent 操作接口的 NAS 版本以及已启用的面板密码。已经存在同名技能时,安装器不会覆盖它。
在仓库中可从项目技能目录发现;若希望在其他目录使用,可将技能目录链接到所用 Agent 的技能目录,例如:
mkdir -p ~/.agents/skills
ln -s "$(pwd)/.agents/skills/nas-traffic-lens" ~/.agents/skills/nas-traffic-lens然后可在支持技能调用的 Agent 中使用 $nas-traffic-lens。技能目录中的查询程序也可独立运行(需要 Python 3.9 或更新版本):
python3 .agents/skills/nas-traffic-lens/scripts/ntl.py --url http://NAS-IP:8088 overview
python3 .agents/skills/nas-traffic-lens/scripts/ntl.py --url http://NAS-IP:8088 history --period day
python3 .agents/skills/nas-traffic-lens/scripts/ntl.py --help可用 NTL_URL 提供服务地址。需要登录时,交互终端会隐藏密码输入;自动化可通过可信凭据提供程序经标准输入传入 --password-stdin,不要把密码写入命令行、文件或日志。也可使用 ntl_sshbind.py --help 查看已有 sshbind 和 Docker 权限下的查询方式,它仅在内存中读取密码。优先使用 HTTPS;HTTP 会在网络上传送明文密码与 Cookie,应限于可信网络。返回错误时程序以非零状态退出。overview 中的实时速率和累计字节与 history --period day 的今日累计是不同口径;历史数据可能有落库延迟或缺失。
rules --kind monitor|protection 返回规则与版本,rule-put / rule-delete 使用该版本进行单条修改,发生并发冲突会拒绝写入;container-restart <容器ID> 重启明确指定的容器。写操作都需要 --apply,且服务端必须配置面板密码。更多参数可用各子命令的 --help 查看;请求结果未知时应先核对状态,再决定是否重试。
截图取自实际运行的极空间 NAS(NAS 镜像 2026.10.07-12)。
首页门户:居中品牌 + 一行实时状态 + 六个大入口卡片,顶部按钮默认隐藏、鼠标移入才出现;服务导航里的服务直接出现在首页,/ 或 ⌘K 搜索后回车直达。
运维助手(只读 Agent):一句话提问,面板展示选用的只读工具、参数、耗时与 token 估算,结果渲染成小卡与排行条,原始 JSON 可折叠查看。
流量总览:公网/内网实时速率、累计流量、连接数与 Docker 概况。
| 浅色 | 暗色 |
|---|---|
![]() |
![]() |
系统与加速器:CPU/内存/磁盘/温度,以及 GPU、NPU、VPU 的实时利用率(ARM 机型通过 devfreq 与 /proc/mpp_service 读取)。
| GPU / NPU / VPU 卡片 | 展开 VPU 的 13 个编解码核心 |
|---|---|
![]() |
![]() |
设置:按功能区独立保存,容器保护支持搜索勾选容器。
| 常用设置 | 容器保护 |
|---|---|
![]() |
![]() |
手机端(浏览器访问 NAS):
- 实时公网/内网上下行速率。
- 物理网卡优先展示,可切换查看全部网卡、bridge、veth、docker0 等接口。
- 公网累计流量统计,避免系统网卡累计混入内网复制、Docker bridge、组播广播。
- 公网连接数统计,尽量按路由器的“活跃会话数”口径展示。
- 进程级上行/下行排行,按需加载,降低后台压力。
- 连接与端口弹窗,支持筛选、分页、公网/内网、方向、协议、网卡、进程和关键词过滤。
- Docker 容器列表、端口识别、手动端口、端口备注、服务类型、快捷访问、图标上传。
- 内置 qBittorrent、Redis、MySQL、MariaDB、PostgreSQL、MoviePilot、Nginx、MongoDB、Prometheus、Grafana、LinuxServer、Docker 等图标;按容器名、镜像名和 Compose service 自动匹配,支持
qbittorrent-nox、moviepolite等别名,手动上传/选择优先。 - Docker stats 按需加载,页面离开后不继续刷新,减少 Docker socket 压力。
- 监控中心展示上传速率、连接数、每日流量等规则的运行状态。
- 通知渠道模块,支持 Webhook、IYUU、MeoW,并支持消息模板变量。
- 历史统计折线图,支持今日、本周、本月等时间范围。
- 系统状态页面,展示 CPU、内存、磁盘、温度风扇与加速器利用率:Intel 机型读 i915 PMU 与 intel_vpu,ARM 机型(绿联云等)读 devfreq 的 Mali GPU / RKNPU 负载与
/proc/mpp_service/load的 13 个 VPU 核心。 - 首页门户:居中品牌与实时状态、六个入口卡片(含 Docker 容器数)、服务直达卡片与搜索,顶部按钮默认隐藏。
- 运维助手(只读 Agent):自然语言 → 计划 → 白名单只读工具 → 结果解读,最多 2 次模型调用;10 个工具覆盖流量概览/历史/进程排行/连接明细、系统状态、容器列表/单容器/容器资源排行、最近告警、配置概况;密钥脱敏、结果裁剪、每次提问写入审计表并统计当日用量。
- AI 中心支持 OpenAI、Claude、DeepSeek、Kimi、Qwen、MiniMax 和自定义接口的按需分析与对话;首页、历史、监控中心都有快捷分析入口。
- AI 中心包含“设置助手”:可以用自然语言同时调整运行参数、监控规则、通知模板非敏感字段、容器保护、Docker 备注/内置图标和 AI 偏好;AI 先生成差异预览,点击一次确认后才写入 SQLite。
- AI 设置助手不会读取或修改密码、API Key、Webhook/IYUU/MeoW Token、Docker socket、数据库/日志路径,也不会执行 SQL、宿主命令或 Docker 命令。
- 支持访问密码、登录失败限制、SQLite 持久化、日志目录映射。
- 上传阈值可在设置页使用
MB/GB/MB/s/GB/s编辑;后端仍以字节保存,旧值53687091200会自动显示为50 GB。 - 上传告警会保存触发值、阈值、Top 网卡、可见进程、活跃公网连接、Docker 归属和每个通知渠道的投递结果。
- 手风琴卡片为层叠 3D 牌堆:滚动视差、悬停浮起、点击展开置顶,Docker / 传感器 / 规则 / 设置编辑器全部接入。
- 监控中心支持按日期回溯上传异常;AI 回复支持安全 Markdown,
Enter发送、Shift+Enter换行。
推荐运行方式是 Docker。
| 环境 | 说明 |
|---|---|
| 极空间 Z425 | Intel Ultra 5 125H,x64 架构,推荐 linux/amd64 镜像 |
| 绿联 DXP4300 Plus | ARM aarch64(UGOS Pro),推荐 linux/arm64 镜像,模板见 docker-compose.ugreen.yml |
| 普通 x86 NAS / Linux 主机 | 使用 linux/amd64 |
| ARM NAS / ARM Linux 主机 | 使用 linux/arm64 |
| macOS / Windows Docker Desktop | 可用于开发和构建,但采集宿主网络信息会受 Docker 虚拟化限制 |
要完整读取宿主网络、进程和 Docker 信息,Linux/NAS 部署时建议使用:
network_mode: hostpid: hostprivileged: true- 默认映射
/var/run/docker.sock,用于 Docker 容器发现和保护规则
如果镜像已经推送到 Docker Hub,可以直接使用 docker-compose.nas.yml:
docker compose -f docker-compose.nas.yml up -d然后访问:
http://NAS-IP:8088
默认端口是 8088,可通过环境变量修改:
environment:
APP_PORT: "8088"默认 compose 已设置访问密码:
DASHBOARD_PASSWORD: "123456"如果只在内网访问,也仍建议保留密码。要关闭密码,删除或置空 DASHBOARD_PASSWORD。
极空间 Z425 推荐使用 linux/amd64:
services:
nas-traffic-lens:
image: isle204/nas-traffic-lens:latest
container_name: nas-traffic-lens
restart: unless-stopped
network_mode: host
pid: host
platform: linux/amd64
privileged: true
environment:
# Web 服务监听端口;host 网络模式下无需配置 ports。
APP_PORT: "8088"
# 首次部署请修改。留空或删除该项会关闭登录验证。
DASHBOARD_PASSWORD: "123456"
volumes:
# SQLite、上传图标和日志持久化。
- ./data:/data
- ./logs:/logs
# 默认启用 Docker 容器发现、端口识别和容器保护。
- /var/run/docker.sock:/var/run/docker.sock:ro
# 可选:暴露 Intel 核显 / NPU 设备,极空间 UI 支持 devices 时再打开。
# devices:
# - /dev/dri:/dev/dri
# - /dev/accel:/dev/accel注意:极空间 UI 如果提示 invalid volume path: /proc,不要映射 /proc。本项目通过 pid: host 读取宿主进程信息,不需要把 /proc 作为 volume 映射。
项目使用多阶段 Dockerfile:
node:20-slim构建前端静态资源。python:3.12-slim安装后端依赖和运行 FastAPI。- 镜像内读取
/app/VERSION作为页面和 API 版本号。
本机直接构建并运行:
docker compose up -d --build查看日志:
docker logs -f nas-traffic-lens停止:
docker compose down极空间 Z425 是 x64 架构,应构建 linux/amd64。
VERSION=$(cat VERSION)
docker buildx build \
--platform linux/amd64 \
-t isle204/nas-traffic-lens:${VERSION} \
-t isle204/nas-traffic-lens:${VERSION}-amd64 \
-t isle204/nas-traffic-lens:amd64 \
-t isle204/nas-traffic-lens:latest-amd64 \
-t isle204/nas-traffic-lens:latest \
--load .导出离线包:
docker save \
isle204/nas-traffic-lens:${VERSION} \
isle204/nas-traffic-lens:${VERSION}-amd64 \
isle204/nas-traffic-lens:amd64 \
isle204/nas-traffic-lens:latest-amd64 \
isle204/nas-traffic-lens:latest \
-o nas-traffic-lens-amd64.tar在 NAS 上导入:
docker load -i nas-traffic-lens-amd64.tar然后 compose 使用:
image: isle204/nas-traffic-lens:latest
platform: linux/amd64给 ARM NAS 或 ARM Linux 主机使用:
VERSION=$(cat VERSION)
docker buildx build \
--platform linux/arm64 \
-t isle204/nas-traffic-lens:${VERSION}-arm64 \
-t isle204/nas-traffic-lens:arm64 \
-t isle204/nas-traffic-lens:latest-arm64 \
--load .导出离线包:
docker save \
isle204/nas-traffic-lens:${VERSION}-arm64 \
isle204/nas-traffic-lens:arm64 \
isle204/nas-traffic-lens:latest-arm64 \
-o nas-traffic-lens-arm64.tarARM 设备 compose 示例:
image: isle204/nas-traffic-lens:arm64
platform: linux/arm64如果要发布到 Docker Hub,让同一个 tag 同时支持 amd64 和 arm64,使用 --push:
VERSION=$(cat VERSION)
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t isle204/nas-traffic-lens:${VERSION} \
-t isle204/nas-traffic-lens:latest \
--push .如果不想自动推送,只想本地打包,请使用前面单架构的 --load + docker save。docker buildx build --load 一次只能可靠加载一个平台,所以本项目建议 amd64 和 arm64 分开构建、分开保存 tar。
登录:
docker login推送 amd64 固定版本和 latest:
VERSION=$(cat VERSION)
docker push isle204/nas-traffic-lens:${VERSION}
docker push isle204/nas-traffic-lens:${VERSION}-amd64
docker push isle204/nas-traffic-lens:amd64
docker push isle204/nas-traffic-lens:latest-amd64
docker push isle204/nas-traffic-lens:latest推送 arm64:
VERSION=$(cat VERSION)
docker push isle204/nas-traffic-lens:${VERSION}-arm64
docker push isle204/nas-traffic-lens:arm64
docker push isle204/nas-traffic-lens:latest-arm64也可以直接执行仓库内的推送脚本。它会读取 VERSION,推送 amd64/arm64 架构 tag,再创建多架构版本 tag 和 latest:
./scripts/push-docker.sh脚本默认使用 OrbStack 的 orbstack Docker context。只预览命令不执行推送:
DRY_RUN=1 ./scripts/push-docker.sh脚本默认给 Docker CLI/buildx 设置本机代理 http://127.0.0.1:10808,不需要每次手动切换代理环境。可用以下变量覆盖或关闭:
DOCKER_PUSH_PROXY=http://127.0.0.1:10808 ./scripts/push-docker.sh
DOCKER_PUSH_PROXY_ENABLED=false ./scripts/push-docker.sh说明:docker push 的网络请求最终由 Docker 守护进程发起。若 OrbStack 自身仍显示独立的 daemon proxy,需要在 OrbStack 中把代理设置为宿主机网关地址(通常是 host.lima.internal:10808);脚本中的 127.0.0.1 适用于宿主机上的 Docker CLI/buildx 请求。
如果你的 Docker context 名称不同,可以覆盖:
DOCKER_CONTEXT=default ./scripts/push-docker.sh日常部署推荐使用 latest,这样文档和 compose 不需要每次跟着版本号修改。遇到缓存、回滚或需要确认版本时,再改用固定版本 tag,例如当前 VERSION 文件中的版本。
普通部署只需要 compose 中的 APP_PORT 和 DASHBOARD_PASSWORD。监控规则、通知渠道、消息模板、采样间隔、历史保留、连接窗口、Conntrack 刷新、阶段统计和 Docker 自动发现都可以在“设置”页面修改,并写入 /data/traffic.db。
在“设置”页面的“AI 分析配置”中选择厂商、填写 API Key,然后启用按需请求。内置预设包括 OpenAI、Claude、DeepSeek、Kimi、Qwen、MiniMax 和自定义兼容接口。OpenAI、DeepSeek、Kimi、Qwen、MiniMax 使用 OpenAI-compatible API;Claude 使用 Anthropic 原生 API(/v1/messages 和 /v1/models)。DeepSeek 预设按官方文档使用 https://api.deepseek.com 和 deepseek-v4-flash,也可从 /models 读取并选择其他模型。Base URL 和模型都可以手动覆盖,方便使用代理、自建网关或区域 endpoint;Base URL 只接受 http:// 或 https://。
点击“读取模型”时,前端把当前未保存的配置发送到后端,由后端请求厂商的 /models 接口并缓存 60 秒。浏览器不会直接接触厂商 API Key;如果厂商不支持模型列表,仍可手动填写模型名称。
- AI 请求只在点击“AI 分析”或发送 AI 中心对话时发起,不会进入后台采集循环,也不会定时调用外部服务。
- 网页默认使用 SSE 流式显示回答,DeepSeek/OpenAI-compatible 和 Claude 原生流式格式都会统一转换为增量事件;普通 JSON 调用方式仍然保留。
- 发送内容是有限的聚合摘要:当前概览、日/周/月/年历史、进程排行、最多 50 个 Docker 容器摘要、系统状态、监控规则和最近告警;不会发送完整连接原始表。
- API Key 保存于 SQLite 的
ai_settings配置中,接口只返回掩码,不回显完整 Key,也不会写入应用日志。请把/data目录当作敏感配置保存。 - 未启用 AI 或没有 API Key 时,AI 接口会返回可读的配置提示,不会影响流量采集和首页显示。
- 保存 AI 配置时,请求超时默认 60 秒并规范化到
5..180秒,最大输出 Token 会规范化到128..393216。DeepSeek 预设默认使用官方最大输出393216Token;官方 1M 是上下文窗口,不等于单次输出长度。超大输出会增加等待时间、内存和 API 费用,请按实际需要调低。 - AI 对话和快捷分析会写入 SQLite 的
ai_messages表,页面刷新或容器重启后会恢复最近 100 条消息;AI 页面可手动清空记录。回答因达到 Token 上限、连接异常或本地硬上限而不完整时,页面会明确提示。 - AI 问题包含
YYYY-MM-DD日期时,会额外读取该日有上限的公网总量、Top 网卡、Top 进程和告警证据。AI 不能执行任意 SQL、宿主命令,也不会收到通知 Token 或 API Key。 - AI 助手回复按 Markdown 展示。原始 HTML 会先转义,链接只允许
http、https、mailto、站内路径和锚点,避免通过v-html注入脚本。
设置页的“AI 中心 -> 设置助手”支持自然语言生成配置预览,例如“把采样间隔改为 2 秒,并开启 Docker 自动发现”。预览会显示路径、原值、新值、风险和过期时间,只有点击“确认应用”才会写入 SQLite;proposal 默认 10 分钟有效、只能应用一次,服务重启后失效,设置在预览期间发生变化时会拒绝应用。密码、API Key、通知 Token、socket、数据库/日志路径、SQL 和宿主命令必须人工配置,AI 不会读取这些内容。
Docker 图标随镜像内置,不访问外部 CDN。容器列表会按用户自定义图标、用户选择的 iconKey、容器名/Compose service/镜像名依次匹配;未匹配时使用通用图标。Docker 编辑器可选择内置图标、上传 PNG/JPG/WebP 或清除覆盖。内置图标清单可通过认证接口 GET /api/docker/icons 获取。
通知渠道支持 Webhook、IYUU 和 MeoW。模板保留原始 {value} / {threshold} 数值变量,同时提供 {value_human} / {threshold_human} 可读变量,例如 96.29 GB、50 GB。常用变量还包括 {app}、{version}、{rule_id}、{rule_name}、{message}、{severity}、{timestamp}、{container_name}、{container_reason}。通知失败不会阻塞采集,会在告警详情保存截断后的渠道结果;Token 和目标 URL 会脱敏。
设置页会把每日/阶段总量显示为 MB 或 GB,把实时速率显示为 MB/s 或 GB/s。SQLite、规则 API 和旧环境变量继续使用字节,已有配置不需要迁移。
新增监控规则默认选择“每日公网上传总量”,以服务运行时区的当天 00:00 至次日 00:00 统计 WAN 上传,不使用首页的全局累计。每个 SQLite 持久化周期检查一次,默认周期为 60 秒。每条每日规则各自每天最多触发一次,跨天重新计算,当天的通知标记跨服务重启保留。持续秒 = 0 表示条件达到阈值后立即触发,不是停用规则。触发后会写入 alerts 和 alert_evidence,再异步发送通知;通知完成后保存每个渠道的 HTTP 状态、成功或失败原因。
已有规则保留指标、阈值和通知渠道。若原来选择“阶段累计公网上传总量”,请将指标改为“每日公网上传总量”再保存;阶段指标仍用于手动开始的阶段累计,页面会明确说明统计范围。
监控中心的“上传异常记录”可以按日期查询。证据包含触发日期、时间、实际值、阈值、Top 公网网卡、触发瞬间可见的公网进程/连接和 Docker 归属。历史进程聚合可能包含内网流量,因此只作为来源参考,公网网卡总量才是告警判定依据。旧版本没有保存进程或通知回执时,页面会明确显示证据缺失,不会猜测来源。
首次启动没有 SQLite 配置时,程序使用代码默认值;保存后 SQLite 配置优先于对应环境变量。因此更新镜像时不需要把几十个默认参数复制到 compose。
| 变量 | 默认值 | 说明 |
|---|---|---|
APP_PORT |
8088 |
Web 服务端口 |
DASHBOARD_PASSWORD |
空 | 设置后启用访问密码 |
APP_SECRET |
空 | 会话签名密钥;不填时根据密码派生 |
DB_PATH |
/data/traffic.db |
SQLite 路径;推荐保持默认并映射 /data |
LOG_DIR |
/logs |
日志目录;推荐保持默认并映射 /logs |
CAPTURE_INTERFACES |
自动 | 高级选项,指定抓包网卡,逗号分隔 |
下表用于诊断、低负载调优或首次启动默认值覆盖,不需要放进推荐 compose。已有 SQLite 运行配置时,页面保存值优先。
| 变量 | 默认值 | 说明 |
|---|---|---|
SESSION_TTL_SECONDS |
604800 |
登录会话有效期,默认 7 天 |
UVICORN_ACCESS_LOG |
false |
是否开启 HTTP access log,默认关闭以降低写盘 |
FILE_LOG |
true |
是否写入 LOG_DIR 文件;设为 false 时直接输出到容器 stdout/stderr |
CONSOLE_LOG |
true |
是否把日志同步输出到容器控制台 |
SAMPLE_SECONDS |
1 |
采样间隔 |
RETENTION_SECONDS |
3600 |
内存中短期历史保留秒数 |
PERSIST_INTERVAL_SECONDS |
60 |
写入 SQLite 的间隔 |
HISTORY_RETENTION_DAYS |
400 |
历史数据保留天数 |
COLLECTOR_PROFILE |
balanced |
采集档位:low 低负载近似公网总量、balanced Go/libpcap 优先、diagnostic 诊断模式 |
COLLECTOR_MODE |
auto |
采集后端:auto/golibpcap/python/off;ebpf 目前仅实验提示并回退 Go |
GO_COLLECTOR_ENABLED |
true |
是否允许启动 Go libpcap 外部采集器 |
ENABLE_PACKET_CAPTURE |
true |
是否启用抓包归因;关闭后公网累计和进程流量会不可用或变少 |
CAPTURE_MAX_EVENTS_PER_SECOND |
2000 |
抓包每秒精确记录阈值,超过后动态抽样并按倍率折算 |
CAPTURE_SAMPLE_RATE |
1 |
固定抓包采样率,1 表示不固定抽样 |
CAPTURE_DYNAMIC_SAMPLE |
true |
高包量时是否自动抽样并按倍率折算流量 |
CAPTURE_MAX_SAMPLE_RATE |
50 |
动态抽样最大倍率 |
ENABLE_SYSTEM_TRAFFIC_CALIBRATION |
true |
抓包统计明显低于系统网卡计数时,用系统计数补齐总量 |
SYSTEM_TRAFFIC_CALIBRATION_THRESHOLD |
1.25 |
系统网卡增量超过抓包增量多少倍时触发校准 |
SYSTEM_TRAFFIC_CALIBRATION_MIN_BYTES |
262144 |
单次校准最小系统增量,避免小流量抖动 |
SYSTEM_TRAFFIC_CALIBRATION_MAX_FACTOR |
20 |
单次校准最大补齐倍率 |
SYSTEM_TRAFFIC_CALIBRATION_ASSUME_WAN |
false |
抓包没有公网/内网比例时是否默认补到公网 |
MAX_RATE_HISTORY_POINTS |
180 |
内存中的实时速率诊断点数,历史图表使用 SQLite |
ENABLE_DOCKER_DISCOVERY |
true |
首次启动的 Docker 发现默认值;之后可在设置页面修改 |
DOCKER_SOCKET |
/var/run/docker.sock |
Docker socket 路径 |
DOCKER_LIST_CACHE_SECONDS |
20 |
Docker 容器列表缓存秒数 |
DOCKER_STATS_CACHE_SECONDS |
5 |
单容器 stats 缓存秒数 |
DOCKER_WEB_PROBE_TTL_SECONDS |
86400 |
Web 端口探测缓存秒数 |
DOCKER_WEB_PROBE_TIMEOUT |
1 |
单次 Web 探测超时秒数 |
DOCKER_API_MAX_BYTES |
2097152 |
单次 Docker socket 响应最大读取字节 |
PROCESS_RECENT_SECONDS |
180 |
30 秒进程排行的内存缓存窗口,默认只保留最近几分钟 |
MAX_CONNECTION_TRACKED |
10000 |
抓包连接缓存硬上限,超过后淘汰最久未活跃连接 |
MAX_PROCESS_TRACKED |
2048 |
进程累计缓存硬上限 |
MAX_PORT_TRACKED |
4096 |
端口累计缓存硬上限 |
MAX_DOCKER_CACHE_ENTRIES |
512 |
Docker stats 和 Web 探测缓存条目上限 |
MAX_DOCKER_ICON_DATA_CHARS |
2097152 |
单个 Docker 图标 data URL 最大字符数 |
LOGIN_MAX_ATTEMPTS |
10 |
单客户端登录失败次数上限 |
LOGIN_LOCK_SECONDS |
300 |
登录锁定秒数 |
ALERT_WAN_TX_BPS |
0 |
兼容旧持续公网上传速率阈值,单位 B/s |
ALERT_WAN_TX_MBPS |
空 | 可读的持续上传默认阈值,单位 MB/s;旧字节变量优先 |
ALERT_WAN_TX_SECONDS |
0 |
默认持续公网上传触发秒数 |
ALERT_STAGE_TX_BYTES |
0 |
兼容旧阶段上传规则,单位 B;首页不再展示阶段公网 |
ALERT_STAGE_TX_GB |
空 | 可读的阶段上传默认阈值,单位 GB |
ALERT_DAILY_TX_BYTES |
0 |
兼容旧每日公网上传阈值,单位 B |
ALERT_DAILY_TX_GB |
空 | 可读的每日上传默认阈值,单位 GB |
ALERT_NOTIFY_CHANNEL |
webhook |
默认通知渠道类型:webhook、iyuu、meow |
ALERT_WEBHOOK_URL |
空 | 默认 Webhook 地址 |
ALERT_WEBHOOK_TIMEOUT |
5 |
通知请求超时秒数 |
CONNECTION_ACTIVE_SECONDS |
120 |
活跃连接统计窗口 |
CONNECTION_RETENTION_SECONDS |
900 |
连接明细缓存保留秒数 |
CONNECTION_COUNT_SOURCE |
conntrack |
连接数来源:conntrack、socket、capture |
CONNTRACK_REFRESH_SECONDS |
30 |
conntrack 连接数刷新间隔 |
CONNTRACK_COUNT_MODE |
active |
active 统计活跃会话,raw 统计原始表条目 |
CONNTRACK_TCP_STATES |
ESTABLISHED |
active 模式下计入的 TCP 状态 |
CONNTRACK_UDP_REQUIRE_ASSURED |
true |
UDP 是否只统计已确认双向会话 |
CONNTRACK_INCLUDE_UNREPLIED |
false |
是否统计未回应连接 |
CONNTRACK_MIN_TIMEOUT_SECONDS |
3 |
active 模式最小剩余超时时间 |
CONNTRACK_MAX_LINES |
30000 |
首页连接数每次最多扫描 conntrack 行数 |
CONNTRACK_SCAN_SECONDS |
1 |
首页连接数每次最多扫描秒数 |
CONNTRACK_CONNECTION_MAX_LINES |
30000 |
连接弹窗 conntrack 明细每次最多扫描行数 |
CONNTRACK_CONNECTION_SCAN_SECONDS |
1.5 |
连接弹窗 conntrack 明细每次最多扫描秒数 |
SOCKET_TCP_STATES |
ESTABLISHED |
socket 模式下计入的 TCP 状态 |
SOCKET_REFRESH_SECONDS |
60 |
socket 连接数刷新间隔 |
PROC_SCAN_TIMEOUT_SECONDS |
1 |
扫描 /proc socket 到进程归属的单次时间预算 |
MAX_PROC_FD_LINKS |
60000 |
单次最多读取的进程 fd 链接数 |
MAX_PROC_NET_LINES |
60000 |
单个 /proc/net/* 文件最多读取行数 |
INTERFACE_REFRESH_SECONDS |
30 |
网卡元信息刷新间隔 |
端口、密码、数据库路径、日志路径、Docker socket 和抓包接口属于部署边界;其余常用配置优先在设置页面修改。
推荐映射:
volumes:
- ./data:/data
- ./logs:/logs
- /var/run/docker.sock:/var/run/docker.sock:ro文件说明:
- SQLite:
./data/traffic.db - 普通日志:
./logs/uvicorn.log - 错误日志:
./logs/uvicorn-error.log - 数据库启动时会在
./data/backups/保留最近 7 份 SQLite 快照,用于升级后配置恢复。
系统页还会读取宿主可用的风扇转速传感器,按 CPU 风扇、系统风扇、机箱风扇等名称分别显示 RPM。容器没有暴露 Linux hwmon 传感器时会显示未检测到,不会伪造转速。
规则、通知渠道和容器保护规则都保存在 traffic.db 的 settings 表中。更新镜像不会自动迁移旧容器内部的 /data,必须始终把同一个宿主机目录映射到 /data。检查当前容器是否使用了原来的数据库:
docker inspect nas-traffic-lens --format '{{json .Mounts}}'
ls -lh ./data/traffic.db ./data/backups/如果升级时误用了新的空目录,先停止容器并重新挂载原来的 data 目录。启动时若发现单条旧配置格式异常,接口 GET /api/settings 会通过 settingsRecovery 返回跳过记录数量,其他有效规则仍会继续加载,原始配置不会被启动过程覆盖。
清理历史统计:进入 设置 → 历史数据维护 → 清理流量历史,确认后只删除网卡和进程流量历史。规则、通知渠道、图标、AI 对话及告警证据均保留。对应接口为需要登录的 POST /api/history/clear。
不要删除 traffic.db 来清理历史:同一数据库也保存配置和告警证据。
容器保护的重启动作不限次数:每次占用达到阈值并满足持续时间,且冷却时间已结束,就重启对应容器;不会因为累计次数多而改为停止或按次数锁定。累计次数仅用于记录,跨服务重启保留。旧版本因重启次数上限停止并锁定的规则,升级后自动解除次数锁定,保留历史计数。明确选择“停止”的规则仍按停止动作处理;若动作结果不确定则保留待确认状态,可使用“重置计数并解除锁定”。解除锁定本身不会启动已停止的容器。
监控范围支持单容器、多选容器、所有运行中容器。多选和全部范围对每个容器分别判断 CPU、内存或磁盘 I/O 阈值,持续时间、冷却、累计重启记录和动作状态也分别记录,只对超限目标执行动作。全部范围会自动纳入之后新增的容器;多选保存稳定名称和 Compose 身份,容器重建后继续匹配,同服务的其他副本不会被自动选中。规则详情显示逐容器采样结果、占用和失败原因。
容器保护的 CPU 阈值按整机口径统计:100% 表示宿主机全部 CPU 核心合计占满,页面展示和规则判断都使用这个值(例如 18 核机器上某个容器吃满 1 个核约为 5.6%);接口另保留单核口径字段 cpuPercentSingleCore(100% = 一个核心,与 docker stats 一致)用于对照排查。内存百分比以容器内存限制为分母,未设限制时通常以主机内存为分母。内存用量可用 MB/GB 设置,磁盘 I/O 可用 MB/s/GB/s 设置。保存规则后持续时间重新计算,已有累计动作次数保留,旧版次数锁定自动解除。批量规则的重置按钮会同时重置该规则下所有目标。
升级提示:CPU 百分比改为整机口径后,已保存的容器保护规则中的 CPU 阈值也按整机百分比重新解释。如果旧规则是按单核口径设置的,请按 旧阈值 ÷ 逻辑核心数 换算后重新保存;例如 18 核机器上的旧阈值 90(单核口径)约等于整机 5%。升级后达到整机阈值并满足持续时间才会执行动作。
首次从未保存动作计数的旧版本升级时,保护计数从零开始,已有规则继续保留。磁盘保护按不同采样时刻的累计读写字节差计算速率;重复缓存样本不会被当成零速率,过期样本不会触发动作。
Go 采集器内部 API 仅监听 127.0.0.1,不需要开放或映射 18088。Go 采集数据同时用于实时告警、网卡历史、进程历史和触发时连接证据。历史进程聚合仍包含抓包可见的内网与公网流量;旧版本未保存的进程记录无法补回。
清理日志:
rm -f ./logs/*.log
docker restart nas-traffic-lens推荐 compose 默认映射 Docker socket 并开启自动发现,可在页面显示容器列表、端口、备注、快捷访问和容器保护状态:
volumes:
- /var/run/docker.sock:/var/run/docker.sock:roDocker socket 应视为主机级控制权限::ro 只限制挂载点的文件系统写入,不会把 Docker API 变成只读;本项目的容器保护也会通过它执行 restart/stop。请使用强登录密码并只在可信内网部署。不需要 Docker 功能时,在设置页面关闭“Docker 自动发现”并删除 socket 挂载;首次启动也可用 ENABLE_DOCKER_DISCOVERY=false 覆盖默认值。
性能策略:
/api/docker/containers只返回轻量容器列表。/api/docker/containers/{id}单独返回某个容器的端口、图标、备注等详情。/api/docker/containers/{id}/stats只在点击“显示占用”时读取。- 页面关闭或离开 Docker 页后,不继续刷新容器 stats。
host 网络模式容器通常没有 published ports,页面支持手动添加端口。
支持 x86(Intel 核显 + NPU)与 ARM(绿联云等 Rockchip RK3588 机型:Mali GPU + RKNPU + VPU)两类平台,能力自动探测:完整矩阵与各平台部署步骤见 doc/nas-compat.md。
Intel 核显通常通过 /dev/dri 暴露:
devices:
- /dev/dri:/dev/driNPU/AI Boost 是否可见取决于宿主驱动和设备节点。如果宿主存在 /dev/accel,可尝试:
devices:
- /dev/accel:/dev/accelprivileged: true 已经包含全部设备节点,不需要再写 devices;用 devices 时请把上面两行取消注释。
利用率读取方式:
- Intel 核显(i915):读取内核 i915 PMU 的
*-busy事件(intel_gpu_top用的是同一来源),按两次采样之间各引擎的忙碌时间算出利用率,服务端每 2 秒采一次;未映射 PMU 时回退到amdgpu的gpu_busy_percent。系统页会列出 Render/3D、Video、Video Enhance、Blitter、Compute 每个引擎的占比,以及核心频率和空闲驻留(RC6)。 - Intel NPU(intel_vpu):读取
/sys/class/accel/*/device/npu_busy_time_us(内核 6.11+ 提供,官方文档说明它就是用来算 NPU 利用率的),同时显示当前/最高频率、常驻显存、电源状态和调度模式。 - ARM 机型(绿联云 / RK3588 等):Mali GPU 与 RKNPU 通过
/sys/class/devfreq/*/load读取 governor 上报的负载;驱动在空闲时可能上报固定基线(RKNPU 为 100/1000),页面按观测到的最小负载做基线校正,避免把空闲显示成 10%。详情里同时给出原始 load、基线与 governor。 - VPU(视频编解码):Rockchip 机型读取
/proc/mpp_service/load,系统页出现「VPU」卡片,按解码(vdpu/rkvdec/av1d/jpegd)与编码(vepu/rkvenc/jpege)聚合,展开可看 13 个核心各自的实时利用率。Intel 平台没有该卡片,编解码负载体现在 i915 的 vcs 引擎上。 - 读取 PMU 需要容器具备
privileged或CAP_PERFMON;只映射设备节点时页面会显示设备可用并给出具体原因,而不是显示错误的百分比。
温度会把 coretemp、acpitz、nvme、drivetemp 等传感器名整理为 CPU、主板/机箱、NVMe、硬盘等更容易看的名称;ARM 机型的 soc_thermal、bigcore0_thermal、gpu_thermal、npu_thermal 等热区会显示为 SoC、CPU 大核 0、GPU、NPU。
不要映射 /proc。使用:
pid: host优先查看日志:
docker logs -f nas-traffic-lens如果日志写入文件:
tail -f ./logs/uvicorn-error.log常见处理:
- 只抓必要网卡,设置
CAPTURE_INTERFACES: "eth0"或实际物理网卡名。 - 保持默认只展示物理网卡,需要排查时再切换“全部接口”。
- 保持 Docker stats 按需查看,不要让页面长期打开大量容器详情。
- Docker 发现异常时先在设置页面关闭“Docker 自动发现”,再确认 Docker socket 是否可映射。
- 查看
/api/diagnostics可以看到当前 RSS 内存、线程数、连接缓存、进程缓存、Docker 缓存规模。
优先打开:
http://NAS-IP:8088/api/diagnostics
重点看:
memory.rssBytes:后端进程实际内存。caches.connectionTotals:抓包连接缓存数量。caches.processTotals:进程累计缓存数量。caches.processRecentKeys:短期进程排行缓存数量。caches.dockerStats/caches.dockerWebProbes:Docker 按需缓存数量。capture.droppedEvents:动态抽样跳过的包数。capture.sampledEvents/capture.weightedBytes:抽样折算是否正在发生。calibration.interfaces:系统网卡计数校准是否已参与补齐。conntrack.truncated:conntrack 是否因行数或时间预算被截断。
默认已经加了硬上限,BT、DHT、UDP 或大量短连接不会无限撑大内存。如果 NAS 负载仍高,可以进一步调低:
PROCESS_RECENT_SECONDS: "90"
CONNECTION_RETENTION_SECONDS: "300"
MAX_CONNECTION_TRACKED: "8000"
MAX_PROCESS_TRACKED: "2048"
MAX_PORT_TRACKED: "4096"
CAPTURE_MAX_EVENTS_PER_SECOND: "1000"
CONNTRACK_MAX_LINES: "15000"
CONNTRACK_CONNECTION_MAX_LINES: "15000"如果不常看连接明细,也可以只抓指定物理网卡:
CAPTURE_INTERFACES: "eth0"如果 Docker 引擎或宿主负载异常,先在设置页面关闭 Docker 自动发现,并用以下高级覆盖验证:
CONNECTION_COUNT_SOURCE: "socket"
ENABLE_PACKET_CAPTURE: "false"
FILE_LOG: "false"这个模式会牺牲公网阶段统计、进程流量归因和 Docker 自动发现,但可以快速判断压力是否来自 conntrack/抓包/Docker socket。
迅雷、BT、DHT 这类场景包量很高。旧版本为了保护 Docker 引擎,超过 CAPTURE_MAX_EVENTS_PER_SECOND 后会直接跳过包,因此可能出现极空间系统监控显示 10MB/s 以上,而本页面公网流量只显示 1MB/s 左右。
新版本改为两层保护:
- 超过精确记录阈值后动态抽样,并按抽样倍率折算字节数。
- 如果抓包统计仍明显低于系统网卡计数,会按已识别到的公网/内网比例补齐接口总量和历史统计。
排查时打开:
http://NAS-IP:8088/api/diagnostics
重点看 capture.sampledEvents、capture.weightedBytes 和 calibration.interfaces。如果它们在下载时增长,说明高速下载已经触发抽样/校准。
如果你希望更精确、NAS CPU 也扛得住,可以提高:
CAPTURE_MAX_EVENTS_PER_SECOND: "5000"
CAPTURE_MAX_SAMPLE_RATE: "100"默认使用 conntrack 的 active 模式,尽量贴近路由器活跃会话数。如果仍然偏大,可以调小:
CONNECTION_ACTIVE_SECONDS: "60"
CONNTRACK_MIN_TIMEOUT_SECONDS: "10"
CONNTRACK_UDP_REQUIRE_ASSURED: "true"
CONNTRACK_INCLUDE_UNREPLIED: "false"如果宿主没有 conntrack,可改:
CONNECTION_COUNT_SOURCE: "socket"保持:
DOCKER_LIST_CACHE_SECONDS: "20"
DOCKER_STATS_CACHE_SECONDS: "5"列表页只加载容器摘要,单容器端口和 stats 都是按需接口。如果仍然慢,先关闭 Docker 自动发现,使用手动端口配置。
页面会尽量识别常见非 Web 服务。非 Web 端口默认复制地址,不直接 http:// 打开。可手动设置端口类型,或点击探测按钮让服务缓存一次 HTTP/HTTPS 探测结果。
前端:
cd front-end
npm install
npm run build后端:
python3 -m venv .venv
. .venv/bin/activate
pip install -r server/requirements.txt
APP_PORT=8088 FRONTEND_DIR=front-end/dist python -m uvicorn server.main:app --host 0.0.0.0 --port 8088代码检查:
python3 -m py_compile server/main.py server/services/*.py
cd front-end && npm run build- 修改代码。
- 更新
VERSION,例如2026.06.26-4。 - 运行后端和前端检查。
- 提交 Git。
- 分别构建 amd64 和 arm64。
- 生成 tar 或推送 Docker Hub。
- NAS compose 使用固定版本 tag 部署。
版本号由镜像内 /app/VERSION 提供,页面和 /api/health 会显示这个版本。不要只改 Docker tag 而不改 VERSION。
更细的功能说明、设计取舍和模块说明见:
启动时默认优先使用 Go + libpcap,不可用时回退 Python Scapy。eBPF 代码保留为实验方向,但当前生产镜像不启用 eBPF。
| 档位 | 适合场景 | 行为 |
|---|---|---|
low |
长期常驻,接近宝塔这类面板的低负载统计 | 不抓包,按物理/默认网卡系统计数近似公网总量,不提供进程/端口归因 |
balanced |
默认推荐 | Go libpcap 抓包,保留公网/内网、进程、连接、端口归因 |
diagnostic |
排查偷跑或异常连接 | 保留详细采集能力,适合短时间打开 |
可通过 COLLECTOR_PROFILE=low|balanced|diagnostic 和 COLLECTOR_MODE=auto|golibpcap|python|off 调整。细节见 doc/README.md § 采集后端架构。
Go collector(独立编译):
cd server/go-collector
go build -o go-collector .前端:








