文档
sixty 测量什么,以及怎么安装
你应用里的 agent 会测量每个操作做了什么 —— 返回多少行、发出多少查询、花了多少时间、发出多少字节、抛了多少错 —— 然后把汇总发出去。收集端把每个版本和上一个作比较,并告诉你是哪次部署改变了什么。
有两个后果值得先知道。这里没有阈值要配置,因为比较的对象是你自己上一个版本,而不是某个人拍脑袋定的数字。而且在第二个版本上报之前什么都比不了,所以安装之后的第一次部署按设计就是安静的。
选择你的语言
每个服务端 agent 测量同样的核心信号,写同样的传输格式。不同的是运行时允许什么:只有 Python 能把计算和等待分开,只有 Node 不用你开口就给你的函数埋点,只有 PHP 必须在没有后台线程的情况下工作,而查询计划需要 Postgres。
Node
唯一一个不用你开口就会给你自己的函数埋点的 agent:构建期转换为每一个导出的异步函数开一个 span,于是每条查询都有一个可以归属的调用者。
npm install @sixty-sh/nodePython
唯一能把计算和等待分开的 agent。别的都只会告诉你代码变慢了,然后就没有下文 —— 这一个会说是两者中的哪一个,而它们需要完全相反的修法。
pip install sixty-shGo
这里的安装是显式的 —— 一个中间件、一层驱动包装,以及在值得测量的函数开头加两行 —— 因为 Go 没有可以挂钩的构建步骤,也没有办法在不被传入的情况下拿到调用方的 context。
go get github.com/sixty-sh/sixty-goRuby & Rails
唯一一个没有第二步的安装。railtie 会在启动时加上中间件、订阅 sql.active_record,并包住控制器的 action —— 没有 initializer 要写。
gem 'sixty'PHP
唯一一个必须在没有后台线程的情况下工作的 agent。PHP worker 跑不了定时器,而它学到的一切都会随这次请求消失,所以窗口在共享内存里汇集并合并 —— 而且必须无损,否则百分位数就是编的。
composer require sixty-sh/sixty在服务器前面
服务端的 span 在响应写完时就结束了,而那远远早于屏幕上出现任何东西。这些测量的是之后发生的那一半 —— 而在手机上,或者在只有 Supabase 的应用里,是那压根没有服务端 span 的一半。
Browser
服务器看不到的那些东西:对一个真实的人来说这个页面到底花了多久、哪些点击什么都没做,以及哪个组件重新渲染了四百次。
npm install @sixty-sh/browserReact Native
一个应用没有服务端的 span 可供比较,所以被拒绝的调用或者空的响应只能从设备上看到。这就是那个把它们变得可见的 agent。
npm install @sixty-sh/react-nativeSupabase
唯一一个知道这个端点「是什么」而不只是「花了多少」的 agent —— 所以它能把一条慢查询和一条拒绝了查询的策略区分开。
npm install @sixty-sh/supabase其余部分
- OpenTelemetry — 从现有 Collector 发送 OTLP 链路和指标,同时保留 Grafana、Prometheus、Elastic、Vercel、AWS 或其他后端。
- 每个 agent 分别追踪什么 —— 一张表,8 个 agent,所有信号。如果你在两个之间做选择,或者想知道某条发现为什么一直不出现,就该读这一页。
- 所有信号 —— 每一类发现是什么意思、单位是什么,以及什么样的代码改动会造成它。
- 它怎么工作 —— 以部署为锚、分位数 sketch、一条查询是怎么被归到发出它的那个函数上的,以及 agent 会给应用带来多少开销。
- MCP 服务器 —— 你的编辑器怎么读取发现、认领一条、修好它,并记录自己做了什么。
- GitHub —— 接上一个仓库,一条发现就会点名那次部署里动过它所在文件的那个 pull request。只读,而且不保存任何文件内容。
每个 agent 都遵守的两条规矩
它不能把你的应用弄坏。 每一条测量路径都被包了起来,所以 agent 内部的失败不会以应用错误的形式冒出来。当收集端联系不上时,agent 会继续往一个有上限的缓冲里测量,并丢掉最旧的窗口而不是一直变大;没有任何东西会阻塞,没有任何东西会永远重试,而应用对此毫不知情。
它永远不会知道你的用户是谁。 没有用户 id、没有会话 id、没有 cookie、没有 IP 地址,也没有任何来自查询的值 —— 语句在离开进程之前就已经被规范化成它的形状。独立访客是从一个每天轮换的编码里数出来的,那个编码由你自己的服务器推导、我们无法反推,而且它被折进一个计数之后就被丢掉,不做存储。这是代码的性质而不是一个开关,也就是说,这同样是一个这个产品对任何人都答不出来的问题,包括我们自己。