用途
Cairn 是一个自托管的可观测性技术栈。一个 Rust 摄取服务把日志、追踪、指标、浏览器事件、错误和支付事实写入 TimescaleDB。Grafana 是唯一界面:没有 Cairn UI,没有查询 API,没有管理守护进程。
本技能覆盖因 Cairn 的构建方式而成立的事实,用于为应用接入 Cairn 并构建其 Grafana 仪表盘。它假定你已经了解 OpenTelemetry、Grafana 和 SQL。
整体结构
一个项目就是一个产品。每个事实行都携带 (project_id, source_id),由服务端从凭据解析得出,客户端请求体从不决定归属。
来源(source)有种类之分:browser、collector、sentry、stripe 或 adapter。一个密钥属于一个来源。浏览器密钥是公开且可撤销的;适配器密钥留在私有网络内;Stripe 通过签名而非密钥进行认证。
Grafana 以 cairn_grafana 身份连接,通过 cairn_ui.* 契约和安全视图读取数据,无法看到密钥摘要或原始支付载荷。
每条路由在返回 2xx 之前先提交。投递语义为至少一次,并带有稳定的重试键,因此重试的批次是无操作,而不会重复计数。
路由
| 信号 | 路由 | 发送方 |
|---|---|---|
| 浏览器批量 | POST /v1/ingest | @cairn/web SDK |
| 崩溃信封 | POST /v1/errors, POST /api/{project}/envelope[/] | 通过 cairn.dsn() 的 Sentry SDK |
| 支付 webhook | POST /v1/webhooks/stripe/{source_id} | Stripe,经签名验证 |
| 私有事实 | POST /v1/adapters/{source_id}/facts | 你的后端适配器 |
| 追踪、指标、日志 | POST /v1/traces, /v1/metrics, /v1/logs | OTel Collector,绝不来自浏览器 |
工作流程
先确定要回答的问题:获客、激活、性能、错误、金钱。不能回答其中任何一项的面板不应上线。
然后阅读你正在处理部分的参考文档:
- references/frontend.md:浏览器 SDK、自定义事件、同意、采样。
- references/backend.md:Collector、Sentry DSN、Stripe webhook、适配器事实。
- references/events-identity.md:事件名称、props、identify 与 reset、共享设备。在编写任何仪表盘之前先把它做对。
- references/features.md:每个信号、表、保证和面板。在发明新事件或查询之前先查阅它。
- references/dashboards.md:Grafana 仪表盘。Web 产品复制 dashboards/samples/static-web-nginx.json,移动端加后端复制 ios-backend.json。绝不要复制 cairn.json 或 kubernetes.json,它们监控的是技术栈本身。
注意事项
- 项目、来源和环境来自凭据行,绝不来自客户端。请求体只携带业务数据。
- 浏览器绝不设置 name 或 email。只有适配器路由写入 display_name 和 email。浏览器批量只触及身份链接。
- 不带 reset() 的 identify() 是正常登录。时间线在查询时解析设备归属,因此客户端不得在登录时轮换 anon id。
- 事件时间是生产者时间,原样保留。早于 7 天或超前超过 1 小时的内容会被拒绝并给出原因,绝不截断。重试落在原始时间上。
- 同意被拒绝时不存储任何可归属内容。该批次仍计为流量,但不写入任何行。
- 记录 ID 携带时间:error:<id>:<micros>、web:<uuid>:<micros>、payment:<provider>:<event>、measurement:<source>:<micros>:<id>。过期的链接渲染为空,而不是错误的事实。
- 绝不要只按环境过滤。仪表盘查询要么把 (project, environment, ...) 一起限定作用域,要么跳过环境。参见 dashboards.md。
- 预 GA 架构没有迁移路径。运行过旧 migrations/0001_initial.sql 的数据库用 make reset-dev 重建,而不是迁移。