超越业务逻辑的编码 — 日志、指标、追踪与仪表盘从代码里长出来
超越业务逻辑的编码 — 日志、指标、追踪与仪表盘从代码里长出来
这一章讲什么: 一个服务上线后,你凭什么知道它好不好?答案必须在你写代码的时候就写好—— 日志、指标、追踪、仪表盘,四样东西全是代码的产物,不是运维后来贴上去的膏药。 这一章是全书第一个动手层章节,给出了大量可以直接抄的代码、配置和清单。 读完你会拿到一条主线:同一个用户请求,如何穿过日志 → 指标 → 追踪 → 仪表盘这四层信号。
1. 主线例子:一笔支付请求的四层人生
本章全部机制,都挂在同一个具体输入上走一遍。输入:用户点击「结账」,支付 49.99 元。
第 1 层 日志: 服务写下一行 JSON——"event": "payment_failed", "order_id": "A123",
"reason": "insufficient_funds", "trace_id": "c78f9d2a..."
第 2 层 指标: 代码里 REQUEST_COUNT.inc() 加一,直方图记一次延迟 240ms
→ Prometheus 定时来 /metrics 端点抓走
第 3 层 追踪: 请求进网关时拿到 trace_id,调用支付服务、写消息队列,
每个服务都把自己的一小段(span)挂到同一个 trace_id 上
第 4 层 仪表盘: Grafana 上,SLO 行显示「支付成功率 99.2%,已跌破 99.9% 目标」,
依赖行显示「支付网关错误率飙升」,注解行显示「14:03 有一次配置变更」
图说:一层信号回答一个问题。日志答「发生了什么」,指标答「多严重、什么趋势」,
追踪答「卡在哪一跳」,仪表盘答「现在要不要人管」。
上面每个字段名都来自原书示例;金额与延迟数值沿用了原书例子的量级。下面四节把每一层讲透,第五节讲不同负载的监控怎么调,第六节讲仪表盘归谁管, 第七节是一个真实的翻车与翻盘案例。
2. 结构化日志:从「Error occurred」到可查询的数据
2.1 解决什么问题
传统日志是这样的:
User login failed
Connection error原书的话很直白:这种日志「在生产里几乎没用」——数据量巨大的时候,没有格式的文本 让 ELK/OpenSearch 这类日志处理器无从下手1。
结构化日志的做法:每行日志是一个键值对(通常就是 JSON——一种通用的文本数据格式),字段名固定。 原书给的完整例子(照抄,这是知识本身):
{
"timestamp": "2025-09-18T10:23:54Z",
"level": "ERROR",
"event": "user_login_failed",
"user_id": "12345",
"ip_address": "192.168.1.10",
"reason": "invalid_password"
}同一个例子换到我们的主线:两行都写「Payment failed」的裸日志,排查时无法区分; 带上下文的结构化日志写明是订单 A123、用户 78910、信用卡、余额不足—— 谁受影响、哪一步失败、为什么、什么时候,四个问题一条日志答完2。
结构化之后,日志从「要肉眼翻的文本」变成「可以查询的数据」: 按 IP 筛所有失败登录、按用户算错误率、按小时数密码尝试次数,都是一条查询3。
2.2 五条最佳实践(原书的清单,接住)
- 分级:DEBUG(开发排错细节)< INFO(服务启动、用户登录这类大事)< WARN(不致命但蹊跷)< ERROR(功能坏了)< FATAL(系统要停);
- 带关联 ID(correlation ID):分布式系统里一笔请求穿过多个服务,给每笔请求一个唯一 ID 写进每行日志,才能把散在各服务的日志串回同一个故事4;
- 绝不记敏感数据:密码、卡号、PII(个人身份信息)要么脱敏(改成认不出原值的样子)、要么哈希(用算法搅成不可逆的乱码)5;
- 跨服务统一格式:所有服务用同一套字段名,集中分析才成立。
2.3 代码怎么写(原书的 Python 例子,照抄)
原书给了一个 JSONFormatter 的例子:自定义一个日志格式化器,把每条记录转成 JSON,
并自动生成 correlation_id6。输出长这样:
{"timestamp": "2025-09-18 12:20:45", "level": "INFO", "message": "User login successful", "correlation_id": "9e3a..."}
{"timestamp": "2025-09-18 12:20:46", "level": "ERROR", "message": "Payment failed due to insufficient funds", "correlation_id": "3f4b..."}2.4 为什么日志是开发者的事,不是运维的事
原书给了五条理由,本质是同一件事的不同侧面:写日志的人是半夜读日志的人7:
| 理由 | 机制 |
|---|---|
| 加快事故解决 | 模糊日志(「Error in service」)让定位根因靠猜;具体日志(「transaction failed for order_id=A123 due to insufficient funds」)一眼定位。MTTR(平均修复时长)差距由此而来 |
| 开发者为自己的代码值班 | SRE 推行的「自己的代码自己背」意味着凌晨 2 点被叫起来的人就是写代码的人——知道自己要读,日志自然会写好 |
| 日志是反馈环 | 哪个 API 最常被调?有没有暴力破解登录的迹象?新功能上线后有没有意外报错?答案都在日志里 |
| 可观测平台依赖它 | Prometheus/Grafana/OpenSearch/Splunk 的告警和仪表盘,原料都是结构化日志 |
| 合规要求 | 金融、医疗行业,记「谁在何时做了什么」是法定义务,不是可选项 |
3. 代码级指标:把「感觉不对」变成「曲线破了阈值」
3.1 解决什么问题
日志给细节,但海量日志里看不出趋势。原书的对比例子:日志告诉你 「14:01:45 有一条 503」;指标给你一张图——每秒请求数 14:00 开始掉、错误率 14:01 开始飙8。 两者合起来才是完整的可观测图景。
关键立场:不要只依赖基础设施指标(CPU、内存),要从代码里主动暴露业务级指标—— 每分钟处理多少订单、API 平均响应时间、缓存命中率、ML 推理延迟9。
3.2 四种指标类型(名字必须留,Prometheus 生态的通用语)
| 类型 | 行为 | 例子 |
|---|---|---|
| Counter(计数器) | 只增不减 | 请求总数、错误总数 |
| Gauge(仪表盘值) | 可上可下 | 当前内存占用、活跃会话数 |
| Histogram(直方图) | 把值分桶统计 | 响应时间分进 <100ms / <500ms / <1s 各档 |
| Summary(摘要) | 直方图的统计聚合版 | p95 延迟(第 95 百分位:比它快的请求占 95%) |
3.3 代码怎么写(原书的 Python 例子,照抄)
用 prometheus_client 库,两行定义指标,处理请求时打点,
start_http_server(8000) 开一个 /metrics 端点供 Prometheus 来抓取10。
抓走的数据长这样(照抄):
# TYPE app_requests_total counter
app_requests_total 42.0
app_request_latency_seconds_bucket{le="0.1"} 12.0
app_request_latency_seconds_bucket{le="0.5"} 38.0
app_request_latency_seconds_bucket{le="1.0"} 42.0
app_request_latency_seconds_count 42.0
app_request_latency_seconds_sum 20.57读法:42 个请求里,12 个快于 0.1 秒,38 个快于 0.5 秒,全部快于 1 秒—— 直方图桶的存在,让「p95 延迟」这类 SLO 算得出来。数据进 Grafana 画图、配告警11。
3.4 五条最佳实践
- 技术和业务指标都暴露(别只有 CPU,要有「每秒订单数」这种 KPI);
- 命名一致,加服务名前缀(如
payment_requests_total); - 基数要低:标签值必须有限——把
user_id当标签会让时间序列爆炸,监控系统的存储被撑垮; - 对齐 SLI/SLO:指标要能直接算服务等级指标(延迟、错误率)和目标;
- 本地先验证指标暴露正确再上线12。
判断(我们的,不是书里的): 第 3 条「基数要低」是本章含金量最高的一句劝, 也是新人最容易踩的坑:
user_id当标签,十万用户就是十万条时间序列。 原书在日志节、指标节、追踪节里把这条反模式重复了三遍——重复是有意的: 高基数是成本失控的第一大来源,而且是在「一切正常」的时候悄悄发生的。 如果错,会错在: 某些新系统(原生支持高基数的可观测后端)正在放宽这条限制; 若读者所在平台是这类系统,这条禁令的代价评估要重写,但「先想清楚标签的取值集合有多大」 这个习惯仍然成立。
4. 把可观测性建进微服务:契约、传播、采样
这是全书最硬的一节。中心主张:系统碎成几十个独立部署的服务后,可观测性不再是工具选择, 而是架构属性——每个服务必须「自我描述」13。
4.1 可观测性契约(observability contract)
原书把它定义成「每个服务必须满足的、不可讨价还价的接口」。内容三块14:
第一,身份坐标。 每个信号都带三个字段:service.name(稳定可读的名字)、
service.version(语义版本或 Git SHA)、deployment.environment(dev/staging/prod)。
原书说,出事时能按 version=1.12.0 切片,「值它的黄金重量」——切到具体版本,
才知道是不是刚上的新版闯的祸。
第二,三个标准端点。 每个服务都发布:
| 端点 | 回答谁的问题 | 答什么 |
|---|---|---|
/healthz(存活) | 平台(Kubernetes) | 进程活着没、卡死没?卡了就重启它 |
/readyz(就绪) | 负载均衡 | 能安全收流量了吗?(检查数据库、缓存、消息队列等下游) |
/metrics | Prometheus | 来抓指标 |
原书特别提醒:存活和就绪服务两个观众,混为一谈会出乱子—— 探活失败被重启、就绪没好就接流量,结果就是无谓的重启风暴或 5xx 洪水15。
第三,三支柱,有意为之。 契约不是「随便记点什么」,是三样各就其位:
追踪(traces,跨服务的端到端请求路径)、指标(metrics,每条路由的 RED 信号——
Rate 速率、Errors 错误、Duration 时长——加业务 KPI)、日志(结构化、带上下文、
与追踪关联——每行日志带 trace_id/span_id)。
外加一条纪律:一致性压倒聪明。命名约定只定一次(属性名 snake_case、指标带服务前缀、 span 名用「动词-资源」),用代码评审和 lint 规则强制执行——最好的可观测性, 是所有地方都能用同一种查法16。
4.2 上下文传播:一笔请求的故事如何穿过进程边界
单体应用里,栈追踪(stack trace,程序出错时自动打印的调用链)把故事讲完。
微服务里,故事跨进程、跨协议,需要一个可携带的叙事——W3C Trace Context 标准
(名字要留,业界标准)就是这套叙事:一个 trace_id 从 API 网关流入,穿过服务调用、
消息队列,进入后台 worker17。
落到我们的主线例子里,完整故事是: 用户点结账 → 服务 A 校验请求 → 服务 B 扣款 → 一条消息进队列 → 服务 C 履约发货, 五跳挂在同一个 trace_id 下,压力之下这一屏的清晰度「改变结局」18。
传播的三个现实细节:
- HTTP 到 HTTP:用 OpenTelemetry(可观测性数据采集的标准工具集,名字留)的自动注入/提取,框架自动在请求头里带上 traceparent;
- HTTP 到消息队列:把 trace 上下文放进消息头(每个网络请求开头附带的元数据小标签,元数据即「描述数据的数据」),消费者取出来续上——不做这步,异步环节(发送方不等回应、各干各的通信方式)就是全盲的;
- 网关和代理:必须原样转发 trace 头,不能剥离;已有
X-Correlation-Id的旧系统,让它从 trace_id 派生,日志和追踪才对得上19。
4.3 插桩策略:自动铺广度,手动标业务
原书的分工极清晰,照单接住20:
| 用自动插桩(auto-instrumentation) | 用手动 span |
|---|---|
| 覆盖那 80% 不该手写的:进出网络 I/O、框架、常用数据库客户端、gRPC、消息队列 | 标业务关键时刻:promo_applied、inventory_reserved、model_scored(促销生效、库存锁定、模型打分) |
| 保证一致性 | 保证意义 |
原书还给了个修剪成本的洞察:将来要降本降噪时,先删的是自动生成的库噪音, 你手写的业务 span 一定会留下——因为人是在那里排障的。
4.4 在 Kubernetes 里接线
服务发布了 /metrics,Prometheus 怎么知道来抓?两条路(名字留)21:
- 注解方式(简单):给 Pod/Service 加
prometheus.io/scrape: "true"和端口注解; - ServiceMonitor/PodMonitor(结构化,多团队友好):Prometheus Operator 的定制资源,按标签选服务、定抓取间隔(如 15 秒)。
追踪数据走 OpenTelemetry Collector:常见拓扑是每个节点跑一个 agent(DaemonSet, 本地缓存、抗网络抖动),再转发到中央 gateway(Deployment,统一做采样、脱敏、路由的策略)—— 以后想上调采样策略,只动 gateway,不用碰应用代码22。
4.5 采样:成本与信号的权衡
全量存 trace 太贵。两种采样,一对 trade-off23:
| 采样方式 | 在哪做 | 行为 | 代价 |
|---|---|---|---|
| 头部采样(head) | SDK(开发工具包)侧,数据一产生就定 | 便宜、快 | 可能丢掉稀有的慢请求——决定做得太早 |
| 尾部采样(tail) | Collector 侧,看完整段 span 再定 | 「错误和慢 trace 全留,其余抽 10%」做得到 | 要在 gateway 攒数据,复杂 |
原书的起步配方:ERROR trace 全留、p95 以上延迟的全留、正常流量抽 5–10%—— 信噪比高,存储也不淹24。
4.6 出错时的语义与三支柱联动
span 要替未来的你说清「什么坏了、为什么」:标 StatusCode.ERROR,附稳定的
error.type(如 db.timeout、payment.declined)和 error.message;异常记到 span 上,
不只是写日志25。三支柱之间的跳转要一键直达:日志自动注入 trace_id/span_id,
仪表盘面板带「查看 trace」深链,日志系统里 trace_id 是一等字段而不是埋在自由文本里——
事故中不用手抄 ID 来回粘贴,MTTR 才会真的降26。
4.7 SLO 对齐的仪表盘与「测试你的可观测性」
仪表盘不是装饰,是 SLO 的界面。五层结构(第 6 节还会展开): SLO 与错误预算燃烧率 → 关键路由的 RED → 依赖(DB、缓存、支付) → 容量(CPU、队列深度、GC) → 变更注解(部署、特性开关、schema 变更)。燃烧率告警用「多窗口、多燃烧率」—— 快窗口抓突发灾难,慢窗口抓缓慢渗漏,都不为噪音叫人27。
最有意思的是原书把可观测性当 API 来测试28:
- 契约测试:依赖挂了时打
/readyz,它是否真的报 not ready?/metrics是否暴露了该有的计数器和标签? - 集成测试:发一个请求,断言产生了一个带
http.route的 server span,且你手写的checkout.processspan 真的出现、带着order.id; - 混沌探针:注入延迟或故障,验证尾部采样真的留住了这些 trace、告警真的响了。
「不测就会漂移」——重构之后 trace 上下文丢了,只有测试能第一时间抓住。
4.8 迁移路线图与反模式
原书给了不用重写的八步路线:统一身份 → 加三个端点 → 部署 Collector(agent+gateway)→ 开自动追踪、验证跨两个服务的传播 → 日志注入 trace_id → 每个服务定三个业务指标并接 SLO 仪表盘 → 引入尾部采样 → 把契约固化进服务模板,新服务生来合规29。
五个反模式(全部高发过)30:DEBUG 日志泛滥(噪音淹没信号、成本翻倍);
高基数标签;在网关/消息队列剥掉 trace 头(链条断裂,端到端排障不可能);
命名不一致(ordersProcessed/orders_processed/order_count 并存,查询脆弱);
一张巨型仪表盘塞所有东西。
5. 按负载类型调监控:同一套契约,不同的重点
契约不变,但信号的优先级必须随负载变。原书分了四类,对照表(表 3.1)接住31:
| 负载 | 最要紧的指标 | 典型死法 | 典型 SLO |
|---|---|---|---|
| CPU 密集型(批处理、视频转码、高频交易) | 每核 CPU 利用率(别取平均,热点会被平均掉)、CPU 被限流时长、队列长度、延迟分布 | 负载下的延迟尖刺 | p95 延迟 < 200ms |
| 内存密集型(缓存层、内存数据库) | 工作集/RSS(实际驻留内存,不是申请量)、缓存命中率、GC 停顿、OOM 被杀次数 | OOM、缓存不命中 | 缓存命中率 > 95% |
| I/O 密集(日志采集、ETL、API 网关) | 磁盘 IOPS/延迟、网络吞吐(单位时间处理量)与丢包、下游依赖延迟/错误率 | 重试、队列堆积 | 吞吐 > X req/s,依赖延迟 < 100ms |
| AI/ML 推理 | GPU(显卡)利用率与显存(显卡内存)、推理延迟分布、模型准确率/漂移 | 显存耗尽、准确率退化 | p95 推理 < 100ms,准确率 ≥ 98% |
两条跨类的忠告:重试率常常掩盖 I/O 瓶颈(重试把「慢」伪装成「忙」); AI/ML 的独特之处是失败模式隐蔽——不是延迟尖刺,而是准确率漂移, 所以监控要把基础设施指标和模型级信号(预测分布、输入特征偏移)组合起来, GPU 指标用 NVIDIA DCGM 这类 exporter 暴露32。
6. 开发者拥有仪表盘:owning the glass
仪表盘曾被视为运维的物件:中央运维团队或 NOC(网络运行中心)盯着一墙屏幕, 开发者对自己代码的线上表现两眼一抹黑——交接慢、排障慢、优先级拧巴33。 本章的立场:写服务的人必须同时控制观察这个服务的镜头,这就是 owning the glass (拥有这块屏)34。
6.1 为什么是开发者的事
仪表盘是代码与开发者之间的直接反馈环:新版上线延迟涨了,应该立刻在仪表盘上看到; 配置改完错误率飙了,仪表盘应该把影响摆在你脸前35。它给四样东西: 可见性、可归责(最近这次发布到底伤没伤性能)、学习(真实流量怎么压你的设计)、 信心(部署能不能放心继续)。
6.2 四条设计原则
- 锚定 SLO:首屏回答「目标达到了吗」——SLO 是 99.9% 的结账请求 200ms 内完成, 第一块面板就必须答这件事;
- 极简:10–15 块精心挑选的面板,细节放下钻页——信息太多和信息太少一样坏;
- 跨服务一致:所有服务的错误率面板永远左上角、p95 永远右上角——事故中靠的是肌肉记忆,省的是分钟;
- 注解变化:部署、schema 迁移、特性开关直接标在时间轴上——大多数回归与变更相关,那就把变更画出来36。
外加一条:三支柱并排或互链,仪表盘是发射台,不是终点37。
6.3 业务信号只有开发者给得出
CPU 全绿、业务全挂,是原书反复警告的错配。每个服务要加业务特有的信号: 支付服务看支付成功率/拒付原因/每秒交易数;推荐服务看缓存命中率/推荐延迟/模型置信度分布; 批处理管道看每分钟处理记录数/滞后/吞吐趋势38。这些指标必须手工在代码里打点, 只有开发者能做。
一个结账服务仪表盘的五层样板:SLO 行(错误率、p95、可用性)→ RED 行(请求速率、 分路由错误率、延迟直方图)→ 依赖行(支付 API 延迟/错误、数据库查询时长、缓存命中率)→ 容量行(CPU、内存、队列深度)→ 注解行(部署、配置变更)39。
6.4 反模式与持有纪律
反模式四种:仪表盘蔓生(每服务好几张、无人维护、没有唯一真相源);虚荣仪表盘 (好看但无可行动的洞察);无主仪表盘(运维建的、开发者从不更新,很快过时); 没有上下文的告警(响了却不解释为什么,排查者还得跨工具拼故事)40。
持有纪律四条:建服务不收工直到仪表盘随服务一起发布;模板化、当代码管 (Grafana JSON 进 Git);拿仪表盘演练(事故模拟、game day 里只用仪表盘排障); 持续迭代41。
7. 案例:救回一次大促发布的收银台仪表盘
这是全书最锋利的一课,值得整段走完42:
第一幕(全绿但全挂):
零售公司上线新的收银微服务,监控归中央运维团队
→ 仪表盘上只有 CPU(50%)、内存(60%)、容器重启数,全绿
→ 大促开始几小时内:客诉涌入,支付失败,购物车超时,收入暴跌
→ 运维仪表盘依然全绿(CPU、内存稳稳的)
→ NOC 升级了事故,但没有应用级指标,诊断成了猜谜
→ 开发者被拉进来时,几小时过去,大额销售已损失
第二幕(仪表盘重构):
开发团队接管仪表盘,围绕收银服务的真正使命重构——
「又快又稳地处理交易」
→ 顶行:支付成功率 + 结账延迟分布
→ 次行:支付网关错误率、数据库查询性能
→ 注解面板:部署与配置变更
第三幕(几个月后,同样的高峰):
支付网关一个配置变更导致支付失败率隐蔽而尖锐地上升
→ 支付成功率面板变红(分钟级),依赖行清楚显示网关 API 错误尖刺
→ 团队 20 分钟内回滚了配置,避免又一次大事故
图说:基础设施指标回答「机器好不好」,业务指标回答「生意好不好」。
大促场景里,你两个答案都需要;但大多数组织的仪表盘只有第一个。8. 边界与局限
- 代码密度极高,但版本会漂移。 本章的 FastAPI/OTel/Prometheus 代码是按 2025–2026 年生态写的, 库名和端口号是当时的写法;学结构与字段,别背 API。
- 采样配方(留 ERROR、p95+、抽 5–10%)是经验值不是定理,原书自己也标了 illustrative; 高合规行业可能要求全量留痕,成本模型完全不同。
- 「契约」没有验收工具链的展开——lint 规则、模板固化各提一句,怎么做全靠读者自己补。
- 成本节(基数预算、保留分层)给的是原则,没有数字锚点——保留多久、预算是多少, 书里没有参照系。
- 章末的 MCQ/思考题(文件 20–21)是练习题,内容已被正文覆盖,不再逐题拆。
9. 可带走的
- 日志写成 JSON 键值对,带
event/order_id/reason/trace_id,裸文本日志等于没有日志; - 四种指标类型(Counter/Gauge/Histogram/Summary)是通用语;直方图桶让 p95 算得出来;
- 标签基数必须有限——
user_id进日志别进指标标签,这是成本失控第一大坑; - 可观测性契约三件套:身份坐标(service.name/version/environment)、
/healthz/readyz/metrics、三支柱各就其位; - 存活探针给平台看、就绪探针给流量看,混用=重启风暴或 5xx 洪水;
- trace_id 必须穿过消息队列,异步环节不传播上下文就是盲区;
- 自动插桩铺广度(80%),手动 span 标业务关键时刻(/checkout.process 这种);
- 采样起步配方:ERROR 全留、p95+ 全留、正常流量 5–10%;
- 仪表盘五层:SLO → RED → 依赖 → 容量 → 注解;10–15 块面板,跨服务同布局;
- 可观测性要当 API 测试:契约测试、集成断言、混沌探针,不测就会漂移。
10. 原文地图
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 结构化日志示例与查询 | Importance of structured and contextual logging | text/13-fm-importance-of-structured-and-contextual-logging.txt:37(搜「user_login_failed」) · text/13-fm-importance-of-structured-and-contextual-logging.txt:56(搜「specific IP address」) |
| 日志最佳实践(分级/关联 ID/脱敏) | 同上 | text/13-fm-importance-of-structured-and-contextual-logging.txt:121(搜「DEBUG」) · text/13-fm-importance-of-structured-and-contextual-logging.txt:153(搜「sensitive data」) |
| Python JSON 日志例子 | 同上 | text/13-fm-importance-of-structured-and-contextual-logging.txt:175(搜「JSONFormatter」) |
| 日志为何归开发者(值班/反馈环/合规) | 同上 | text/13-fm-importance-of-structured-and-contextual-logging.txt:267(搜「2 AM」) · text/13-fm-importance-of-structured-and-contextual-logging.txt:299(搜「legal requirement」) |
| 指标四类型与 Prometheus 例子 | Implementing metrics at code level | text/14-fm-implementing-metrics-at-code-level.txt:40(搜「Counters」) · text/14-fm-implementing-metrics-at-code-level.txt:122(搜「app_requests_total 42.0」) |
| 指标最佳实践(命名/基数/SLO) | 同上 | text/14-fm-implementing-metrics-at-code-level.txt:169(搜「consistent naming」) · text/14-fm-implementing-metrics-at-code-level.txt:172(搜「cardinality」) |
| 可观测性契约(身份/端点/三支柱) | Building observability into microservices | text/15-fm-building-observability-into-microservices.txt:14(搜「service.name」) · text/15-fm-building-observability-into-microservices.txt:23(搜「healthz」) · text/15-fm-building-observability-into-microservices.txt:34(搜「RED」) |
| 存活 vs 就绪 | 同上 | text/15-fm-building-observability-into-microservices.txt:29(搜「noisy restarts」) |
| W3C Trace Context 与传播 | 同上 | text/15-fm-building-observability-into-microservices.txt:45(搜「W3C Trace Context」) · text/15-fm-building-observability-into-microservices.txt:55(搜「blind spots」) |
| 自动 vs 手动插桩 | 同上 | text/15-fm-building-observability-into-microservices.txt:104(搜「auto-instrumentation」) · text/15-fm-building-observability-into-microservices.txt:114(搜「business risk」) |
| K8s 接线与 Collector 拓扑 | 同上 | text/15-fm-building-observability-into-microservices.txt:327(搜「prometheus.io/scrape」) · text/15-fm-building-observability-into-microservices.txt:370(搜「DaemonSet」) |
| 采样(头/尾)与起步配方 | 同上 | text/15-fm-building-observability-into-microservices.txt:394(搜「Head sampling」) · text/15-fm-building-observability-into-microservices.txt:400(搜「5–10%」) |
| 错误语义与三支柱联动 | 同上 | text/15-fm-building-observability-into-microservices.txt:410(搜「error.type」) · text/15-fm-building-observability-into-microservices.txt:427(搜「Log injection」) |
| 仪表盘五层与 PromQL | 同上 | text/15-fm-building-observability-into-microservices.txt:498(搜「Top row」) · text/15-fm-building-observability-into-microservices.txt:521(搜「histogram_quantile」) |
| 测试可观测性与迁移路线 | 同上 | text/15-fm-building-observability-into-microservices.txt:535(搜「Contract tests」) · text/15-fm-building-observability-into-microservices.txt:575(搜「Standardize identity」) |
| 反模式与多语言快速上手 | 同上 | text/15-fm-building-observability-into-microservices.txt:610(搜「Everything in DEBUG」) · text/15-fm-building-observability-into-microservices.txt:629(搜「Node.js」) |
| 负载类型监控与表 3.1 | Tailoring monitoring for different workloads | text/16-fm-tailoring-monitoring-for-different-workloads.txt:17(搜「per core」) · text/16-fm-tailoring-monitoring-for-different-workloads.txt:295(搜「Table 3.1」) |
| AI/ML 监控(漂移/DCGM) | 同上 | text/16-fm-tailoring-monitoring-for-different-workloads.txt:140(搜「drift」) · text/16-fm-tailoring-monitoring-for-different-workloads.txt:151(搜「DCGM」) |
| owning the glass 与四原则 | Developer ownership of service dashboards | text/17-fm-developer-ownership-of-service-dashboards.txt:7(搜「owning the glass」) · text/17-fm-developer-ownership-of-service-dashboards.txt:57(搜「SLO-driven」) |
| 业务信号与仪表盘样板 | 同上 | text/17-fm-developer-ownership-of-service-dashboards.txt:79(搜「Payment success rate」) · text/17-fm-developer-ownership-of-service-dashboards.txt:96(搜「Row 1」) |
| 仪表盘反模式与持有纪律 | 同上 | text/17-fm-developer-ownership-of-service-dashboards.txt:129(搜「Dashboard sprawl」) · text/17-fm-developer-ownership-of-service-dashboards.txt:155(搜「Grafana JSON in Git」) |
| 收银台案例三幕 | Case study of checkout dashboard that saved a launch | text/18-fm-case-study-of-checkout-dashboard-that-saved-a-la.txt:7(搜「all green」) · text/18-fm-case-study-of-checkout-dashboard-that-saved-a-la.txt:13(搜「20 minutes」) |
| 章结论 | Conclusion | text/19-fm-conclusion.txt:4(搜「core design principle」) |
Footnotes
-
出处:「Importance of structured and contextual logging」第 7 段(
text/13-fm-importance-of-structured-and-contextual-logging.txt:7,搜「practically useless」)与第 22 段(text/13-fm-importance-of-structured-and-contextual-logging.txt:22,搜「Elasticsearch」)。 ↩ -
出处:「Importance of structured and contextual logging」第 84–111 段(
text/13-fm-importance-of-structured-and-contextual-logging.txt:93,搜「payment_failed」;text/13-fm-importance-of-structured-and-contextual-logging.txt:111,搜「who was affected」)。 ↩ -
出处:「Importance of structured and contextual logging」第 52–66 段(
text/13-fm-importance-of-structured-and-contextual-logging.txt:56,搜「specific IP address」)。原书结论:「这一结构化方法把日志从原始文本变成可查询的数据。」 ↩ -
出处:「Importance of structured and contextual logging」第 138 段(
text/13-fm-importance-of-structured-and-contextual-logging.txt:138,搜「correlation ID」)。 ↩ -
出处:「Importance of structured and contextual logging」第 153 段(
text/13-fm-importance-of-structured-and-contextual-logging.txt:153,搜「raw passwords」)。 ↩ -
出处:「Importance of structured and contextual logging」第 166–232 段(
text/13-fm-importance-of-structured-and-contextual-logging.txt:175,搜「JSONFormatter」;text/13-fm-importance-of-structured-and-contextual-logging.txt:229,搜「9e3a」)。 ↩ -
出处:「Importance of structured and contextual logging」第 267 段(
text/13-fm-importance-of-structured-and-contextual-logging.txt:267,搜「2 AM」)与第 299 段(text/13-fm-importance-of-structured-and-contextual-logging.txt:299,搜「legal requirement」)。 ↩ -
出处:「Implementing metrics at code level」第 13 段(
text/14-fm-implementing-metrics-at-code-level.txt:13,搜「503 Service Unavailable」)。 ↩ -
出处:「Implementing metrics at code level」第 16 段(
text/14-fm-implementing-metrics-at-code-level.txt:16,搜「business and application-level metrics」)。 ↩ -
出处:「Implementing metrics at code level」第 62–113 段(
text/14-fm-implementing-metrics-at-code-level.txt:74,搜「app_requests_total」;text/14-fm-implementing-metrics-at-code-level.txt:101,搜「start_http_server」)。 ↩ -
出处:「Implementing metrics at code level」第 146 段(
text/14-fm-implementing-metrics-at-code-level.txt:146,搜「Grafana dashboards」)。 ↩ -
出处:「Implementing metrics at code level」第 166–178 段(
text/14-fm-implementing-metrics-at-code-level.txt:172,搜「unbounded label values」)。 ↩ -
出处:「Building observability into microservices」第 4 段(
text/15-fm-building-observability-into-microservices.txt:4,搜「architectural property」)。 ↩ -
出处:「Building observability into microservices」第 14–38 段(
text/15-fm-building-observability-into-microservices.txt:14,搜「service.name」;text/15-fm-building-observability-into-microservices.txt:27,搜「scrapable endpoint」)。 ↩ -
出处:「Building observability into microservices」第 29 段(
text/15-fm-building-observability-into-microservices.txt:29,搜「noisy restarts」)。原文:「把两者当一回事会造成吵闹的重启或 5xx 风暴。」 ↩ -
出处:「Building observability into microservices」第 38 段(
text/15-fm-building-observability-into-microservices.txt:38,搜「Consistency over cleverness」)。 ↩ -
出处:「Building observability into microservices」第 45 段(
text/15-fm-building-observability-into-microservices.txt:45,搜「W3C Trace Context」)。 ↩ -
出处:「Building observability into microservices」第 98 段(
text/15-fm-building-observability-into-microservices.txt:98,搜「fulfilled the order」)。 ↩ -
出处:「Building observability into microservices」第 52–61 段(
text/15-fm-building-observability-into-microservices.txt:55,搜「blind spots」;text/15-fm-building-observability-into-microservices.txt:61,搜「X-Correlation-Id」)。 ↩ -
出处:「Building observability into microservices」第 104–121 段(
text/15-fm-building-observability-into-microservices.txt:111,搜「80%」;text/15-fm-building-observability-into-microservices.txt:117,搜「Auto for consistency」)。 ↩ -
出处:「Building observability into microservices」第 317–366 段(
text/15-fm-building-observability-into-microservices.txt:327,搜「prometheus.io/scrape」;text/15-fm-building-observability-into-microservices.txt:344,搜「ServiceMonitor」)。 ↩ -
出处:「Building observability into microservices」第 370 段(
text/15-fm-building-observability-into-microservices.txt:370,搜「DaemonSet」)。 ↩ -
出处:「Building observability into microservices」第 394–397 段(
text/15-fm-building-observability-into-microservices.txt:394,搜「Head sampling」)。 ↩ -
出处:「Building observability into microservices」第 400 段(
text/15-fm-building-observability-into-microservices.txt:400,搜「keep ERROR traces」)。 ↩ -
出处:「Building observability into microservices」第 410–416 段(
text/15-fm-building-observability-into-microservices.txt:410,搜「error.type」)。 ↩ -
出处:「Building observability into microservices」第 423–433 段(
text/15-fm-building-observability-into-microservices.txt:427,搜「Log injection」)。 ↩ -
出处:「Building observability into microservices」第 498–525 段(
text/15-fm-building-observability-into-microservices.txt:498,搜「Top row」;text/15-fm-building-observability-into-microservices.txt:525,搜「multi-window」)。 ↩ -
出处:「Building observability into microservices」第 531–545 段(
text/15-fm-building-observability-into-microservices.txt:535,搜「Contract tests」;text/15-fm-building-observability-into-microservices.txt:531,搜「drifts」)。 ↩ -
出处:「Building observability into microservices」第 571–600 段(
text/15-fm-building-observability-into-microservices.txt:575,搜「Standardize identity」;text/15-fm-building-observability-into-microservices.txt:596,搜「service templates」)。 ↩ -
出处:「Building observability into microservices」第 610–622 段(
text/15-fm-building-observability-into-microservices.txt:610,搜「Everything in DEBUG」;text/15-fm-building-observability-into-microservices.txt:616,搜「Dropping context」)。 ↩ -
出处:「Tailoring monitoring for different workloads」第 13–26 段(
text/16-fm-tailoring-monitoring-for-different-workloads.txt:17,搜「per core」)与第 180–295 段(text/16-fm-tailoring-monitoring-for-different-workloads.txt:295,搜「Table 3.1」)。 ↩ -
出处:「Tailoring monitoring for different workloads」第 140–157 段(
text/16-fm-tailoring-monitoring-for-different-workloads.txt:140,搜「drift」;text/16-fm-tailoring-monitoring-for-different-workloads.txt:151,搜「DCGM」)。 ↩ -
出处:「Developer ownership of service dashboards」第 4 段(
text/17-fm-developer-ownership-of-service-dashboards.txt:4,搜「Network Operations Center」)。 ↩ -
出处:「Developer ownership of service dashboards」第 7 段(
text/17-fm-developer-ownership-of-service-dashboards.txt:7,搜「owning the glass」)。原文:「开发者不仅写服务,还控制观察服务健康的镜头。」 ↩ -
出处:「Developer ownership of service dashboards」第 13 段(
text/17-fm-developer-ownership-of-service-dashboards.txt:13,搜「feedback loop」)。 ↩ -
出处:「Developer ownership of service dashboards」第 42–51 段(
text/17-fm-developer-ownership-of-service-dashboards.txt:42,搜「anchored in SLOs」;text/17-fm-developer-ownership-of-service-dashboards.txt:51,搜「root cause of performance regressions」)。 ↩ -
出处:「Developer ownership of service dashboards」第 69 段(
text/17-fm-developer-ownership-of-service-dashboards.txt:69,搜「launchpad」)。 ↩ -
出处:「Developer ownership of service dashboards」第 79–89 段(
text/17-fm-developer-ownership-of-service-dashboards.txt:89,搜「manual instrumentation」)。 ↩ -
出处:「Developer ownership of service dashboards」第 96–108 段(
text/17-fm-developer-ownership-of-service-dashboards.txt:96,搜「Row 1」)。 ↩ -
出处:「Developer ownership of service dashboards」第 129–142 段(
text/17-fm-developer-ownership-of-service-dashboards.txt:129,搜「Dashboard sprawl」;text/17-fm-developer-ownership-of-service-dashboards.txt:138,搜「Alerts without context」)。 ↩ -
出处:「Developer ownership of service dashboards」第 152–161 段(
text/17-fm-developer-ownership-of-service-dashboards.txt:152,搜「part of development」;text/17-fm-developer-ownership-of-service-dashboards.txt:158,搜「game days」)。 ↩ -
出处:「Case study of checkout dashboard that saved a launch」第 4–16 段(
text/18-fm-case-study-of-checkout-dashboard-that-saved-a-la.txt:7,搜「all green」;text/18-fm-case-study-of-checkout-dashboard-that-saved-a-la.txt:13,搜「under 20 minutes」)。CPU 50%、内存 60% 为原书数字。 ↩