v1.7.0 · MIT · 自托管

Topophany — 在终端中查看的自托管网络监控

从哪里出发,经由哪条路径,抵达了什么——依据又是什么。

整张网络尽在一屏:哪条路径从哪里走得通,哪些服务有应答,每个状态背后的证据是什么。自托管,一个 Go 二进制文件,在终端里查看。

go install github.com/WhitenWhiten/topophany/cmd/topo@latest
新topophany-bar 把 Topophany 放进 macOS 菜单栏

01 终端界面

有没有出问题?在哪里?

topo preview 的录屏:真实的 TUI,合成的证据。 在浏览器里试用 →

~ topo preview 回放 · 200×50
预览模式下 Topophany 终端界面的录像,可在下方按章节选择。

故障来了

按 x,家里到洛杉矶中转线路的连接被阻断。只有确认的失败才会变红。

1–9 章节 space 暂停。也可以自己运行 topo preview。

02 语义

讲证据,不看颜色

没有通过的检查,就不会变绿。没人监控的服务保持 unknown。

默认没有绿色

服务证据状态
●主站Cloudflare ⇢ Oracle 纽约http 200 · 4 秒前由 Cloudflare FRA 应答 · 缓存 DYNAMIC
○家庭面板仅有备注已登记,未监控未配置检查unknown
✖VLESS+Reality 入口搬瓦工 · 洛杉矶tcp 超时 · 6 秒前来自 成都 MacBook · 3 个样本中 3 个DOWN

健康的行保持安静。没有检查就是 unknown,而不是在线。

观测点是明确的

tcp 超时 ×3 http 200 · 182 ms 成都worker · MacBook 洛杉矶搬瓦工 入口 纽约worker · Oracle 结论 成都出发的路径故障 · 服务器正常

从一个地方看到的失败,是那条路径的故障,而不是服务器宕机。

边缘作出了应答

结论 故障在边缘之后 · 源站未经证明

CDN 的应答无论自称什么,都只能证明边缘;只有不经过边缘、直达源站的检查,才能证明源站。

推测就标为推测

✖ INCIDENTVLESS+Reality 入口搬瓦工 · 洛杉矶

Failed checks
✖ m-exit-transit-a
Other-observer response evidence
● w-exit-aux-b
Hypothesis (not a finding)
source/path-specific interference, filtering or routing fault is possible; blocking authority and untested protocols are not established

事件给出证据,此外的一切都标为假设。

03 架构

一个二进制,三种角色

topo 既是客户端,也是采集器和观测点。不需要 CGO、数据库或外部模块。

  • 个二进制文件客户端、采集器和 worker
  • 个外部 Go 模块只有标准库
  • 种发布构建Linux、macOS、Windows · amd64、arm64
  • 个标签页支持鼠标

两个采集器,不搞共识算法那一套

worker 同时投递给两者,一方离线时先行缓冲。

生来只读

没有远程配置 API,也没有远程 shell。拓扑是你审阅过的本地 JSON。

有上限,也会明说

配额用满时,探测报错停止,而不是丢弃证据。

04 探针

它能测量什么

原生探针、代理链,以及针对现有工具的只读适配器。

原生探针

  • L7
    • http200 · 182 ms符合预期的状态码、正文、头部和出口 IP
    • ssh-bannerSSH-2.0 · 38 msSSH banner,不代表能登录
    • dnsA 192.0.2.10 · 9 ms符合预期的 A / AAAA 记录
  • L6
    • tlsTLS 1.3 · verified · 41 ms经过验证的证书链和名称
  • L4
    • tcpconnected · 23 ms连接已建立,仅此而已
    • udp-echononce echoed · 27 ms随机 nonce 被原样回显
  • L3
    • icmpecho reply · 31 ms回显应答,仅限 IPv4

代理链

  1. 观测点
  2. OpenSSH -W仅限首跳,校验主机密钥
  3. HTTP CONNECT
  4. HTTPS CONNECT校验代理的 TLS
  5. SOCKS5远程 DNS
  6. 目标

最多 12 跳。HTTP、TCP、TLS 和 SSH 检查会依次穿过每一跳。

只读适配器

  • MihomoGET /proxies内核报告的模式、链路和当前选择
  • Tailscaletailscale status --json对端是否在线,直连还是中继
  • WireGuardwg show wg0 dump最近一次握手与收发字节;从不保留密钥
  • cloudflaredGET /ready连接器报告的隧道会话与 colo

工具报告的状态只当作报告展示,绝不算作端到端的通过。

边缘与平台

  • CloudflareedgeWorkers 与 Pages;以及应答的 POP
  • VerceledgeFunctions;以及边缘与函数区域
  • Supabaseplatform所在区域的托管服务

应答记在发出它的边缘名下,绝不算到其后的源站头上。

05 交给 Agent

让 Agent 替你画出这张网

监控最费工夫的一步,是把网络描述清楚,而这恰好是你手边的编程 Agent 擅长的事。它读取机器上现成的信息,写出拓扑,并在任何东西运行之前,先用 topo validate 检查一遍。

这样问它

请把我的网络写成 Topophany 拓扑,保存到 topology.json。格式参考 `topo preview --print-topology` 的输出,以及 github.com/WhitenWhiten/topophany 里的 docs/REFERENCE.md。读取我的 SSH 配置、`tailscale status`,以及你能找到的 Compose 文件和反向代理配置:为每台机器写明所在位置、上面跑的服务、服务所属的应用和监听的地址,再从我要运行 worker 的机器发起检查,并把你了解到的情况写进各台机器的 notes。不要把任何密钥写进文件。反复运行 `topo validate --config topology.json` 直到通过,然后告诉我哪些是查到的、哪些是推测的。

Claude Code、Codex、Gemini CLI、Cursor,或任何能执行命令的 Agent 都行。密钥不会进文件:格式里只写环境变量名和密钥文件的路径,不写内容。

写好之后

  • 网络备忘录topology.json一份审阅过的文件,写清什么跑在哪里、每台机器怎么连上,旁边附着笔记和处置手册。Agent 动手之前先读它;它改了什么,你看 diff 就知道。
  • 随手可查的接口topo status · show · history一条命令,文字或 JSON,你和 Agent 都能用:现在有没有问题、那台服务器上跑着什么、某项检查昨晚表现如何。
  • 上线之前topo preview --config预览模式用合成证据画出你自己的网络,在启动任何一个 worker 之前,你和 Agent 都能先过一遍。

06 在 Mac 上

把网络放进菜单栏

topophany-bar 是 Topophany 的 macOS 伴侣应用。它通过 topo 读取 collector:状态显示在菜单栏,面板告诉你问题是从哪里看到的,桌面小组件让服务器和服务一直留在视野里。

一个 macOS 桌面:菜单栏里是白夜图标,月亮处于月偏食,旁边显示 2;其下展开的面板显示一个有两条警告的降级网络、看到它们的观测点和一张地图;桌面上摆着状态、服务器、时区、服务和地图小组件
一个有两条警告的演示网络,由应用自己的视图用合成数据绘制。

topophany-bar

macOS 26 及以上 · 预发布,从源码构建

  • 一眼看清用图标、数量或几个字显示状态。在内置的抖动夜空「白夜」里,月亮就是状态:一切正常时是满月,有降级时是月偏食,有服务中断时是血月。
  • 从哪里看到事件、受影响的应用和报告问题的观测点集中在一个面板里;任何一项都能在终端界面中打开,查看证据。
  • 直接读取 Beszel 与 Komari从 Beszel Hub 或 Komari 服务器挑选服务器,查看它们的 CPU、内存和磁盘,无需运行 collector。
  • 小组件与主题状态、服务器、服务、地图和时区小组件;六套主题,从原生 macOS 到印在纸上的终端界面。

07 为 iPhone Duo 设计

地图在铰链上方

iPhone App 还没有做。现在有的是 TUI 为它做的设计:--device 让 TUI 按 iPhone、iPad 以及 iPhone Duo 每种姿态的屏幕排版,并在终端里模拟出这块屏幕。在展开的 Duo 上,要看的和要点的分在折痕两侧。

终端模拟器画出的、为竖拿的 iPhone Duo 排版的 TUI:铰链上方是网络地图,一条受影响的路径标成琥珀色;下方是显示 5 个事件的状态卡、观测点、需要处理的列表,以及底部的标签页
终端模拟器里,竖着展开、像笔记本电脑一样半折:topo preview --device duo-laptop。
  • 上面看,下面点按笔记本式姿态排版时,地图放在立起的一半,也就是屏幕上;事件和所有控件放在手指所在的平放的一半。
  • 折叠不重绘平放时布局就已经给折痕留出了位置,所以折叠不会移动任何一个字符格。在模拟器里折叠、展开或转向手机,当前的标签页、选中项和打开的证据都会保留。
  • 避开系统区域布局不在折痕上、时钟和摄像头下方、安全区域之外放置控件,每个点按目标都有一指高。测试会检查每台设备上的每个标签页。

在终端里试试

go install github.com/WhitenWhiten/topophany/cmd/topo@main topo preview --device duo-laptop

[ 和 ] 切换姿态,\ 换下一台设备,鼠标代替手指。终端需要约 99×70 个字符格。下一个版本发布之前,--device 只在 main 上。

终端模拟器画出的、五种姿态下为 iPhone Duo 排版的 TUI,都是同一时刻:合上时在外屏上,标签页在时钟下方的竖栏里;横向展开,左边是地图,右边是列表;像书一样半折;竖着展开,地图在铰链上方;像笔记本电脑一样半折
模拟器画出的每种姿态下的同一时刻。合上时,标签页进入时钟下方的竖栏;横向展开,跨页的左右两边各司其职;竖着时,地图移到铰链上方。

08 安装

一分钟上手

预编译归档,或者一条 go install。

go install github.com/WhitenWhiten/topophany/cmd/topo@latest

需要 Go 1.26.11 或更新版本。

  1. 先随便看看

    内置演示。按 x 弄坏点什么。

    topo preview
  2. 启动采集器

    在 127.0.0.1:7447 上运行演示。

    topo init --dir ./demo topo serve --config ./demo/topology.json \ --auth ./demo/auth.json \ --data ./demo/collector-data \ --observer demo
  3. 打开 TUI

    在另一个终端里运行。

    topo --credentials ./demo/credentials.json