15 观测、日志与链路工具
接口变慢时,一段异常栈只能证明某个线程在某个位置失败过。它通常不能回答故障从哪个发布版本开始、影响了多少请求、上游是否重试、下游是否已经饱和,也不能证明问题此刻仍在发生。日志、指标、Trace 和错误事件要解决的,正是这些不同层次的证据问题。
真正有效的观测链不是先买一套平台,再要求所有团队把数据灌进去。它从一个可验证的问题开始:先确定需要观察的对象,再选择信号,最后决定采集、传输、存储、查询和告警工具。对象和问题没有定义清楚时,更多数据只会带来更高成本和更大的敏感信息暴露面。
四类信号回答不同问题
日志保存离散事件和上下文,适合还原某次失败;指标把大量事件压缩成时间序列,适合判断趋势、容量和告警;Trace 记录一次请求跨组件的因果路径,适合寻找等待和错误传播;错误追踪平台把相似异常归并成可分派的问题,并把问题关联到发布版本和源码。
这四类信号不是同一份数据的四种皮肤。把用户 ID 放进指标 label 会制造高基数,把完整请求体塞进 span 会放大成本与合规风险,只记录聚合指标又无法还原单次故障。架构设计首先要决定每个字段属于哪类信号,以及它是否真的需要离开进程。
从最近的证据开始
应用刚刚在开发机或测试机报错时,先用 tail、ripgrep、jq 与 lnav 检查原始文件。这个入口没有平台依赖,能最快确认时间格式、轮转、JSON 结构、trace id 和异常栈是否完整。只有当证据跨机器、跨容器或需要多人长期查询时,集中日志平台才开始产生收益。
Elastic Stack、Loki 与云日志平台 解决的不是“把文件搬到网页里”,而是采集失败、解析规则、索引或 label 模型、保留、权限和成本如何共同工作。Elastic 依靠可搜索字段与索引结构获得强查询能力;Loki 更依赖低基数 label 选择日志流;云日志把基础设施运维交给厂商,同时引入 IAM、出口流量、配额和平台锁定。
趋势与容量问题进入 Prometheus 与 Grafana。Prometheus 负责发现目标、抓取样本、保存时间序列并执行规则,Grafana 负责查询与展示,但一张看板存在并不意味着指标正确。指标名称、类型、label 基数、抓取间隔、WAL、保留和告警窗口共同决定系统能否在故障时给出可信结论。
跨服务调用先经过 OpenTelemetry 建立稳定的遥测入口。应用侧 API、SDK、自动插桩、Resource 和 Context 决定数据怎样产生,Collector 的 receiver、processor 与 exporter 决定数据怎样被保护、清洗、批处理和发送。后端迁移时,稳定的 OTLP 接入层比在每个服务里直接绑定某个厂商 SDK 更容易控制变更范围。
Trace 需要被查询和保存时,再比较 Jaeger、Tempo 与 Zipkin。三者都能接收和展示调用链,但存储索引、查询方式、对象存储依赖、协议兼容和运维复杂度不同。选择后端时要从现有遥测协议、查询习惯、数据规模和存储能力出发,不能只比较 UI 截图。
Java 服务希望通过 Agent 快速建立 APM 拓扑时,可以进入 Apache SkyWalking。Agent、OAP、存储与 UI 是不同故障域:Agent 注入成功不代表 OAP 已接收,OAP 可用不代表存储能持续写入,拓扑空白也可能只是缺少真实流量或上下文传播。
需要把异常聚合为可分派问题,并关联 Release、commit 和 source map 时,使用 Sentry。DSN 负责事件上报,不等同于管理凭证;source map 是发布制品的一部分,不应靠开发者事后手工上传;Replay、Profile 和完整请求上下文则必须在成本与个人信息边界内单独决策。
把四类信号关联起来
一次排障可以从告警开始,但不能在告警结束。最小关联键通常包括统一时区、环境、service.name、服务版本和 trace id。发布版本帮助判断回归时间,trace id 把日志与 span 连接起来,服务与环境标签让指标和错误事件落到同一故障域。
关联键也会成为新的风险源。用户 ID、订单 ID、URL 全路径和 SQL 参数不适合作为 Prometheus label 或 Loki stream label;Authorization、Cookie、连接串和完整请求体不应进入日志与 Trace。需要排障的业务标识应经过分级、截断或不可逆处理,并且只进入有明确访问控制和保留期限的信号。
采集管道也会失败
观测系统不是业务系统之外的透明旁路。同步上报可能拖慢请求,异步队列可能占满内存,磁盘缓冲可能在网络故障时吃满节点,重试可能放大后端压力,采样可能恰好丢掉低频严重故障。采集器必须暴露自己的接收量、拒绝量、队列占用、发送失败和重试年龄,否则“平台没有数据”时无法判断是业务没有发生,还是证据在路上丢失。
接收成功也不等于数据可查。日志可能在解析阶段进入失败队列,Prometheus target 可能为 up=1 却抓到错误标签,Collector exporter 可能持续重试,Trace 后端可能写入对象存储但查询索引尚未建立。每条链都要分别验证生产端、传输端、存储端和查询端,不能只看一个绿色进程。
成本从字段设计开始
观测成本不是最后调整一个保留天数就能解决。日志事件大小与写入量、指标序列数与抓取频率、span 数量与属性大小、错误事件和 Replay 采样率,都会在采集、网络、存储和查询四个阶段重复放大。
容量评估至少记录每日写入量、峰值吞吐、活跃时间序列、平均 span 数、队列最长等待时间、压缩后存储增长和查询扫描量。演示环境可以使用固定阈值,生产阈值必须来自业务 SLO、容量预算和基线测量。没有基线时,“保留 30 天”只是愿望,不是架构参数。
团队如何长期持有这条链
应用团队负责埋点语义、服务版本、日志字段和错误归类;平台团队负责采集器、存储、租户、容量和升级;安全与合规角色负责字段分级、访问审计、保留与删除;值班人员负责把告警、查询和故障记录连接成可执行流程。职责可以由同一批人承担,但不能无人承担。
每新增一种 SDK、Agent、Collector 或后端,都应能回答五个问题:谁批准字段进入平台,谁处理发送失败,谁承担存储成本,谁能查询敏感数据,退出或迁移时如何停止双写并证明数据链已经切换。回答不了这些问题时,新增工具通常只是在延后一次更昂贵的治理。
