深夜,你家小区突然停电。保安通过对讲机喊了一句“3 号楼停电了”——这是监控,它告诉你“出事了”。但如果你是物业经理,想真正解决停电问题,你需要三样东西:配电房的运行记录(什么时候跳闸、谁报修过)、电压电流的实时读数(是过载还是短路)、以及电工顺着线路从总闸一路查到 3 号楼配电箱的排查路径。这三样东西,对应到云原生系统里,就是可观测性三大支柱:日志、指标与追踪。 日志记录系统在何时、何地、发生了什么;指标把系统健康状态量化成体温、血压一样的连续数字;追踪则像一张病灶扩散地图,让你看清一次请求如何穿越层层微服务。三者配合,SRE(站点可靠性工程师)才能像医生一样,在系统“生病”时快速诊断出根因,而不是只会对着报警铃干瞪眼。这篇文章会用一次“系统全身体检”的故事,带你完整认识三大支柱。
掌握日志、指标、追踪三大支柱,你就能从“系统坏了只能等告警”进化到“十分钟定位根因”——这是 SRE、云架构师与 DevOps 工程师最核心的排障能力。
可视化演示
展示日志/指标/追踪三大支柱数据模型、采集流水线及跨支柱关联分析时序。
本节配有交互动效(进入视口后自动加载,约 3KB)。
三大支柱:日志/指标/追踪数据模型 日志记录离散事件,数据量最大,适合根因定位与审计追踪 追踪记录请求链路,数据量最低,适合性能瓶颈与依赖分析 Observability=Logs∪Metrics∪Traces 三大支柱互补关联,共同构建系统全栈可观测性
可观测性概述
小区里养一只看门狗,陌生人靠近它就叫,但不会告诉你“这个人是快递员还是小偷”。监控就是这只看门狗——它能发出“系统出问题了”的报警,却答不出“为什么出问题”。而可观测性(Observability)是一位真正的医生:它通过系统的外部输出,推断出系统内部的状态。这里的“外部输出”,就是三大支柱:日志、指标与追踪。
从控制理论中走出来的“可观测性”一词,在云原生语境里被赋予了更具体的使命:只靠外部数据,还原系统内部发生了什么。日志回答“发生了什么”,指标回答“当前数据状态如何”,追踪回答“请求经历了什么路径”。三者互为补充,组合起来才能完成一次完整的“病情诊断”。
注意,监控与可观测性不是替代关系,而是上下层关系:监控是建立在可观测数据之上的告警能力。一套完整排障工作流是:告警触发 → 查指标看趋势变化 → 查日志找异常线索 → 查追踪定位跨服务链路。整个流程浓缩成一个公式:
从“看门狗”进化到“医生”,不是换一只更聪明的狗,而是给整个小区装上病历、监护仪和检查单——这正是三大支柱各自要承担的角色。
- 恢复总时长从故障发生到服务完全恢复的总时间,是衡量排障效率最直接的指标。
- 发现时间从故障发生到告警触发的间隔,依赖指标采集频率与告警规则是否灵敏。
- 定位时间从收到告警到确认根因的间隔,这一项决定排障成败,是三大支柱的主战场。
- 处理时间根因确认后执行修复动作的间隔,依赖预案完备度与自动化能力。
日志数据模型
医生看病,第一件事是翻病历本:上次发烧是什么时候、吃了什么药、有没有过敏史。日志(Logs)就是系统的病历本,忠实记录每一次“就诊事件”。一条日志说“2024-05-01 10:03:02 订单服务报错:数据库连接超时”,这就是一次完整的事件叙述。
日志是带时间戳的离散事件记录。生产环境里,日志通常以结构化 JSON 输出,字段必须规范化,方便机器检索。常见字段包括时间戳(timestamp)、级别(level)、服务名(service)、消息体(message)以及关联用的 trace_id。级别从 DEBUG 到 FATAL 依次加重,生产环境一般保留 INFO 及以上,ERROR 级别应单独对接告警。
日志的采集方式很有讲究。在 Kubernetes 中部署应用时,惯例是让应用把日志打到标准输出(stdout),再部署一个采集 Agent(如 Fluent Bit、Filebeat)从容器里“偷听”输出流,解析后转发到日志平台。日志天然信息密集但噪音极大,一个大规模集群每秒可产生百万条日志,所以要分级存储:热数据进搜索引擎供全文检索,冷数据压缩后进对象存储。日志五元组可以写成:
病历本写得越规范,医生越容易快速翻到关键页。日志结构越统一,排障时的检索效率就越高——这是第一条支柱的核心价值。
- 时间索引日志发生的那一刻,精确到毫秒,是所有时间对齐和排序的基准。
- 日志级别DEBUG/INFO/WARN/ERROR/FATAL 五档,决定日志的重要程度和处理优先级。
- 服务归属哪台机器、哪个服务产生的,排障时第一时间锁定责任方。
- 关联钥匙请求的唯一标识,让这条日志能被“拼回”完整的调用链。
指标数据结构
重症监护室的墙上挂着一台监护仪,心率、血压、血氧饱和度汇成一条条连续曲线,护士扫一眼就知道病人状态是否稳定。指标(Metrics)就扮演这个角色:它们是可聚合的数值序列,以固定时间间隔采集,回答“现在数值是多少”。
指标有四种核心类型,就像体检报告上的不同项目。Counter(计数器) 只增不减,适合统计累计量,比如“今天总请求数 12 万次”;Gauge(仪表) 可增可减,描述当前瞬时状态,比如“当前 CPU 使用率 73%”;Histogram(直方图) 把样本分桶,用于计算延迟分布;Summary(汇总) 直接在客户端算好分位数。有了这些类型,监控系统才能在告警时回答“慢了”——至于“为什么慢”,需要交给另外两根支柱。
Prometheus 是当前指标领域的事实标准,采用拉取模型:应用暴露一个 /metrics 端点,Prometheus 定期“上门取样”。通过 PromQL 查询语言,可以即时算出每秒请求数。比如,一分钟内计数器增长了 6000,那么 QPS 就是 100。公式表达如下:
监护仪的优点是数据量小、存储便宜、趋势直观,最适合做告警触发器。但它只能告诉你“病人心率飙到 180 了”,说不清是紧张、发烧还是失血——查明原因,需要看追踪。
- 计数器累计型指标,记录从启动至今的总数,比如总请求数。
- 求差值取两个时间点读数的差,得到这段时间内的新增量。
- 时间窗口两次读数之间的间隔,可以是 1 分钟或 5 分钟。
- 除法求速率用新增量除以时间,得到平均每秒的请求速率。
链路追踪模型
医生怀疑病灶已经扩散,会开一张增强 CT 检查单:往血管里注入造影剂,然后追踪造影剂流经全身器官的影像路径。链路追踪(Tracing)就是这个思路——给一次请求注入“造影剂”(TraceID),观察它流经每个微服务时留下的“影像”(Span)。
Trace 是一条端到端的请求链,代表“一次从用户点到应用”的完整旅程。Span 是旅程中的单个步骤:网关收到了请求、订单服务查了一次数据库、支付服务调了一次外部 API,各自都是一个 Span。Span 之间通过 parent_id 形成树形结构——支付 Span 的父节点是订单服务里发起调用的那个 Span。一条 Trace 就是这棵树的合集:
关键技术是上下文传播:请求进入第一个服务时生成 TraceID,之后通过 HTTP Header(W3C Trace Context 的 traceparent 字段)逐跳携带,每经过一个服务就追加一个 Span。由于请求量巨大,全量追踪的存储成本难以承受,生产环境通常采用采样策略——只保留 1% 到 10% 的请求追踪,头部采样按入口决定,尾部采样则优先保留出错请求。OpenTelemetry 是行业标准 SDK,一次埋点即可输出三大支柱数据。
造影剂流到哪里,病灶的扩散路径就清晰到哪里。有了这张路径图,排查跨二十个微服务的慢请求,不再需要靠猜。
- 操作跨度Span 是调用链中的一个具体操作,承载服务名、操作名、开始时间与耗时。
- 集合符号大括号表示“一组 Span 的集合”,说明 Trace 是多个操作拼出的完整旅程。
- 端到端链路从入口到出口的所有 Span 组合起来,就是一次请求的完整路径。
关联分析技术
医生的办公桌上摊着三份材料:病历本(日志)、监护仪曲线(指标)、CT 影像(追踪)。单独看任何一份都难以确诊,把三份叠在一个灯箱上,病灶才无所遁形。排障的过程,本质是一场关联分析。
最核心的关联键是 TraceID:日志平台从日志字段中提取 TraceID,点击即可跳转到对应追踪链路;反过来,从追踪链路的某个 Span 也能一键查看该服务在那几毫秒打出的相关日志。第二个关联维度是时间:指标曲线显示 10:03:02 出现延迟尖峰,就去日志系统检索这 30 秒窗口内的 ERROR 日志,这种“指标先锁定、日志再深挖”的打法非常高效。
一个标准排障故事是这样的:Prometheus 告警“订单服务 P99 延迟超阈值” → Grafana 看指标锁定异常窗口 → Loki 查该窗口日志,发现大量“数据库连接池耗尽” → 点击 TraceID 跳转 Tempo,看到慢请求全部命中同一条数据库调用链。三大支柱的关联可以用关系运算表达:
三份材料叠在一起,才是一张完整的诊断报告。三大支柱不是三个孤岛,而是建在同一套 TraceID 之上的三块透视镜。
- 日志数据集全部日志记录构成的集合。
- 选择运算σ 像聚光灯,只保留满足条件的记录,这里条件是 trace_id 匹配。
- 追踪数据集全部 Span 记录构成的集合。
- 自然连接⋈ 符号表示把两堆记录按同一个字段(trace_id)拼成一张大表——日志和链路由此打通。
采集管道工具
抽完血之后,样本要打包、贴码、物流转运、实验室分拣,最后才出现在检验报告上。可观测性的采集管道就是这套体检物流系统,负责把三大支柱的数据从“产生地”安全、高效地运到“查询端”。
完整管道要过四关。第一关采集:每个节点部署 Agent(如 Fluent Bit、Vector、OpenTelemetry Collector),从容器 stdout、系统文件、网络探针中侧写数据。第二关缓冲:数据先进入内存队列或 Kafka,防止突发流量压垮下游。第三关处理:解析 JSON、丢弃 DEBUG 日志、按 TraceID 采样、脱敏敏感字段。第四关存储与查询:日志进入 Loki 这类低成本全文索引,指标进入 Prometheus,追踪进入 Tempo/Jaeger,前端通过 Grafana 统一呈现。
管道设计的关键是采样闸门,否则成本会失控。日志通常全量保存(因为需要查细节),指标天然紧凑所以全量采集,追踪则严格控制采样率。每条数据都要算存储账:
物流系统通畅,医生才能十分钟内拿到全部报告。采集管道的目标不是把所有数据搬到存储——而是以可承受的成本,把最关键的数据在关键时刻送到该出现的地方。
- 产生速率每秒产生多少条日志或指标点,取决于系统规模。
- 单条体积一条日志或一个指标点占多少字节,JSON 日志通常几百字节。
- 保留时长数据要存多久,热数据 7 天、冷数据 90 天是常见配置。
- 采样率0 到 1 之间的系数,1 表示全量保留,0.01 表示只留 1%。
- 求和汇总把日志、指标、追踪三类数据的成本逐项相加,得出总存储预算。
SRE实践落地
体检中心不只要出报告,还要根据报告给客户定制健康管理方案。SRE(站点可靠性工程)干的正是这件事:把三大支柱的原始数据,转化成一整套系统健康管理制度。
第一件工具是黄金四信号:延迟(Latency)、流量(Traffic)、错误(Errors)、饱和度(Saturation)。这四项是系统的“生命体征”,对应体检必测的心率、血压、体温和血氧。第二件工具是 SLO 与错误预算:SLO(服务等级目标)是给系统定的健康红线,比如“99.9% 的请求延迟低于 500ms”;SLI(服务等级指标)是实际达成率的测量值;错误预算则是允许超标的额度。发布新版本就像病人试吃新菜——如果错误预算被快速消耗,说明身体吃不消,必须停止发布,优先恢复稳定:
第三件工具是告警分级:页面级告警要求立即处理(打电话、影响用户);票据级告警生成工单(不影响主流程);通知级告警进周报(仅供观察)。每条告警都必须附上对应指标的链接和日志的查询入口,让接收人一步进入排障现场。
好的体检套餐不是越贵越好,而是覆盖了最重要的指标、形成了“体检—诊断—治疗—复查”的闭环。SRE 的终极目标,就是把排障变成一道流水线——数据自动汇聚,告警自动携带上下文,恢复动作自动执行。
- 服务目标SLO 是服务可靠性承诺,用百分比或时延阈值表达。
- 余量计算从 100% 中减去承诺值,剩余部分就是允许出错的空间。
- 预算消耗每次故障、每个超时请求都在消耗预算,消耗速度就是系统健康度的警告灯。
AI 应用场景
微服务故障定位
阶段:故障诊断与根因分析
解决的问题:传统排障靠 SSH 登录服务器翻日志,一次请求跨越 20 个微服务,平均定位耗时 3 小时。接入三大支柱后,指标告警锁定时间窗口,日志定位报错服务,追踪还原完整调用链,排障效率从小时级提升到分钟级。
具体案例:某电商平台大促期间“订单提交缓慢”。Prometheus 指标曲线显示 10:03 延迟陡增,Loki 检索该时间窗内订单服务日志,发现大量“数据库连接池耗尽”,点击日志中的 TraceID 跳转 Tempo,看到请求打到数据库服务后排队 2 秒。最终定位为促销脚本打满了连接池。
容量规划与扩容决策
阶段:性能分析与容量规划
解决的问题:凭经验扩容容易过度采购或容量不足。利用指标的长期趋势数据预测峰值流量,结合历史大促数据估算需要扩容的规模,让每一台服务器都花在刀刃上。
具体案例:云厂商运维团队导出 Prometheus 中 90 天的 QPS、CPU 和连接数曲线,叠加业务增长曲线,预测下一季度的流量峰值,提前扩容并验证瓶颈服务。追踪数据进一步揭示哪些链路占用了最多资源,为架构优化提供依据。
发布质量管控
阶段:变更管理与发布管控
解决的问题:应用上线后出现问题难以第一时间发现,或无法快速决策是否回滚。用 SLO/错误预算量化发布对稳定性的冲击,配合追踪对比新旧版本的延迟与错误率,让发布决策从“拍脑袋”变成“看数据”。
具体案例:某团队做 10% 灰度发布时,实时监控新版本的 P99 延迟和错误率指标,同时对比新旧版本链路的追踪数据。发现新版本在支付环节错误率上升导致错误预算加速消耗,系统自动暂停灰度并触发告警,避免了全量故障。
Python 演示
import randomfrom collections import defaultdict class Span: """追踪里的一个跨度,代表一次服务调用""" def __init__(self, trace_id, span_id, parent_id, service): self.trace_id = trace_id self.span_id = span_id self.parent_id = parent_id self.service = service self.duration_ms = 0 class Logger: """日志采集器:所有服务把事件写入这里""" def __init__(self): self.lines = [] def write(self, trace_id, level, service, msg, duration_ms): self.lines.append({ "trace_id": trace_id, "level": level, "service": service, "msg": msg, "duration_ms": duration_ms }) class Metrics: """指标采集器:计数器和延迟观测""" def __init__(self): self.counter = defaultdict(int) self.observations = defaultdict(list) def count(self, name, value): self.counter[name] += value def observe(self, name, value): self.observations[name].append(value) def generate_trace(chain, logger, metrics): """模拟一次请求生成追踪链路""" trace_id = "t%d" % random.randint(100000, 999999) spans = [] parent_id = None for i, service in enumerate(chain): span = Span(trace_id, "s%d" % i, parent_id, service) parent_id = span.span_id duration = random.uniform(5, 60) if service == "payment": duration = random.uniform(80, 300) span.duration_ms = duration if i == 0: metrics.count("requests_total", 1) metrics.observe("latency_ms", duration) if service == "order" and duration > 50: logger.write(trace_id, "ERROR", service, "timeout", duration) else: logger.write(trace_id, "INFO", service, "ok", duration) spans.append(span) if spans: total_ms = sum(s.duration_ms for s in spans) logger.write(trace_id, "INFO", "gateway", "total", total_ms) return trace_id, spans def percent_99(values): """计算 P99 分位数""" values = sorted(values) return values[int(len(values) * 0.99) - 1] def main(): logger = Logger() metrics = Metrics() chain = ["gateway", "order", "payment"] for _ in range(300): generate_trace(chain, logger, metrics) total_requests = metrics.counter["requests_total"] p99 = percent_99(metrics.observations["latency_ms"]) errors = [line for line in logger.lines if line["level"] == "ERROR"] trace_map = defaultdict(list) for line in logger.lines: trace_map[line["trace_id"]].append(line) slowest = sorted(trace_map.items(), key=lambda kv: kv[1][-1]["duration_ms"], reverse=True)[:3] print("总请求数:", total_requests, "P99延迟: %.1f ms" % p99) print("ERROR日志数:", len(errors)) for trace_id, lines in slowest: print("慢请求", trace_id, "总耗时 %.1f ms" % lines[-1]["duration_ms"]) for line in lines[:-1]: print(" ", line["service"], line["msg"], "%.1f ms" % line["duration_ms"]) if __name__ == "__main__": main()
span = Span(trace_id, "s%d" % i, parent_id, service)每经过一个服务就创建一个 Span,parent_id 形成调用树结构,相当于追踪链路的一个节点。logger.write(trace_id, "ERROR", service, "timeout", duration)日志必须带上 trace_id 和耗时,这是后续关联分析的“钥匙”。metrics.observe("latency_ms", duration)把每个 Span 的耗时存进观测列表,供最后计算 P99 分位数。trace_map[line["trace_id"]].append(line)按 trace_id 把日志分组,实现日志与追踪的关联,这就是“拼图游戏”在代码里的落地。sorted(trace_map.items(), key=lambda kv: kv[1][-1]["duration_ms"], reverse=True)[:3]按每条链路的网关汇总耗时排序,找出最慢的三个请求。values[int(len(values) * 0.99) - 1]延迟样本排序后取第 99 百分位的下标,就是 P99 延迟。
常见误区
误区我已经上了 Prometheus 指标监控,CPU、内存、QPS 都能看到,日志和追踪没必要再搞了,纯属浪费钱。
正解指标是“体温计”,能告诉你发烧了,却说不出是病毒还是细菌感染。日志记录症状细节,追踪绘制病灶传播路径。只靠指标排障,就像只盯着监护仪却拒绝看病历和 CT,效率极低。三大支柱不是可选项,而是互补的必选项。
为何常见:指标最容易接入、存储成本低、告警效果立竿见影,让人误以为“有了告警就等于有了一切”。
误区日志是排障的“真相”,删了怕出事的时候找不到,所以全部保留,越多越安心。
正解日志是海量事件流,全量保存的成本呈线性爆炸。正确做法是分层:热数据 7 天进搜索引擎,冷数据压缩后进对象存储。同时日志在采集端就要过滤采样——DEBUG 日志直接丢弃,ERROR 日志全量保留。存“最可能有用”的日志,而不是“所有”日志。
为何常见:排障时遇到“日志被采样掉了”的懊恼经历,让运维走向另一个极端。
误区我们配了告警规则,告警也能正常发出,所以系统已经具备可观测性了。
正解监控回答“是否出问题”,可观测性回答“为什么出问题”。告警只是可观测性数据的上层应用。真正的可观测性要求数据能跨支柱关联——告警发出后,接收人能不能十分钟内找到根因?不能的话,就还停留在监控阶段。
为何常见:二者在日常语境中经常混用,工具链也高度重叠,让新人误以为是一回事。
误区追踪就是查“哪个服务慢了”,平时没慢请求的时候完全用不上。
正解追踪的价值远不止性能排查。它生成的调用拓扑可以用于服务依赖分析(发现隐藏的循环调用)、容量规划(找出瓶颈节点)、安全审计(还原异常请求的完整路径)。把追踪看成“系统地图”,而不是“交警测速仪”。
为何常见:多数人第一次接触追踪正是从“慢接口排查”开始的,容易把工具的价值窄化。
误区日志进 ES,指标进 Prometheus,追踪进 Jaeger,各查各的,互不相通,反正都能查到数据。
正解可观测性的核心价值在于关联。日志里的 TraceID 跳不到追踪,指标尖峰对不上日志时间窗,三大支柱就退化成三个孤立的“查看器”。度量一个可观测性平台的好坏,不是看数据全不全,而是看关联顺不顺。
为何常见:搭建期按组件分别落地最容易,团队缺乏统一设计,导致建完才发现数据之间“没有接线”。
面试题
Q1. 监控与可观测性的核心区别是什么?
- A.监控关注是否异常,可观测关注为何异常← 正确答案
- B.监控只采集指标,可观测只采集日志
- C.可观测性必须使用开源工具才能实现
- D.监控适合单体,可观测适合微服务
答案:A。监控是看门狗,负责报警“出事了”;可观测性是医生,负责诊断“为什么出事”。A 精确描述了两者的核心区别。B 错在把数据源割裂,两者都依赖三类数据;C 与工具选型无关;D 与架构形态无关。
Q2. 生产环境中日志最常见的采集方式是什么?
- A.应用直接输出到标准输出再捕获← 正确答案
- B.日志需要人工手动复制到报表系统
- C.日志只能通过数据库备份来实现
- D.日志采集必须依赖商业软件才能做
答案:A。Kubernetes 场景下,应用把日志打到 stdout,采集 Agent 从容器输出流捕获转发,这是云原生标准做法,对应“护士从病房收集标本送检”。B 没有自动化;C 混淆日志与数据备份;D 开源工具遍地都是。
Q3. Counter 类型的指标有什么特征?
- A.只增不减,适合统计累计总量← 正确答案
- B.可增可减,用于描述当前状态
- C.只记录字符串,不记录数值信息
- D.只记录当前值,不记录历史数据
答案:A。Counter 像跑步计数器,只向前累计,如“总请求量”。B 描述的是 Gauge 的特征;C 指标必须是数值类型;D 与类型定义无关,任何指标都按时间序列落库。
Q4. 关于 Trace 与 Span 的关系,下列说法正确的是?
- A.一个 Trace 由多个 Span 组成← 正确答案
- B.Span 之间可以有父子关系← 正确答案
- C.Span 数量必须与容器数量相同
- D.TraceID 贯穿所有相关调用← 正确答案
答案:ABD。Trace 是一次请求的完整旅程,Span 是旅程中的每一步,一个 Trace 由多个 Span 组成(A 对)。Span 通过 parent_id 形成树形父子结构(B 对)。TraceID 作为“造影剂”贯穿整条链路(D 对)。C 错在 Span 与容器数量无关,一个服务可产生多个 Span。
Q5. P99 延迟指标的含义是什么?
- A.99% 的请求延迟不超过该值← 正确答案
- B.每秒最多能处理 99 个请求
- C.系统可靠性达到了 99% 的水平
- D.99% 的日志都是错误日志
答案:A。把一千个请求的延迟从小到大排序,第 990 个的延迟就是 P99——它代表“绝大多数请求都落在这个时间内”。B 混淆延迟与吞吐;C 混淆性能指标与可靠性目标;D 与日志完全无关。
Q6. 请求上下文跨服务传播依靠什么机制?
- A.通过 HTTP 请求头传递标记← 正确答案
- B.通过文件系统共享全局变量
- C.通过数据库定时同步来实现
- D.通过重启服务来重新初始化
答案:A。TraceID 借 HTTP Header(如 W3C Trace Context 的 traceparent 字段)逐服务传递,像“接力棒”一样跑到终点。B、C 都不符合无状态服务的调用方式;D 更是南辕北辙。
Q7. 以下哪些属于 SRE 实践中的黄金四信号?
- A.延迟,比如请求响应耗时← 正确答案
- B.流量,比如每秒请求数量← 正确答案
- C.错误,比如请求失败占比← 正确答案
- D.饱和度,比如队列积压程度← 正确答案
答案:ABCD。黄金四信号是 Google SRE 定义的四个核心维度:延迟(Latency)、流量(Traffic)、错误(Errors)和饱和度(Saturation),相当于系统的生命体征四项,恰好对应体检单上的心率、血压、体温和血氧。
Q8. 错误预算(Error Budget)的计算方式是什么?
- A.100% 减去 SLO 目标值← 正确答案
- B.SLO 目标值乘以请求总量
- C.错误日志数除以告警总数
- D.99.9% 是固定的错误预算值
答案:A。错误预算是允许系统不达标的时间额度。若 SLO 定为 99.9% 可用,错误预算就是 0.1%——一年约 8.76 小时。预算耗尽就冻结发布,优先做稳定性。B 没有依据;C 与错误预算无关;D 把 SLO 常见值错当成固定预算。
Q9. 日志与追踪进行关联分析的主要方式有哪些?
- A.在日志中写入 TraceID← 正确答案
- B.按时间窗口对齐查找← 正确答案
- C.用正则匹配所有错误堆栈
- D.通过 SpanID 反向关联日志← 正确答案
答案:ABD。日志带上 TraceID,就能与追踪链路互相跳转(A 对);指标曲线锁定时间窗后去日志里搜该窗口是常用打法(B 对);SpanID 也可以作为细粒度关联键(D 对)。C 只是日志解析手段,不构成关联分析。
Q10. 追踪采样率设为 10%,对总请求量做统计时需要注意什么?
- A.统计结果仍需按采样率放大← 正确答案
- B.追踪数据丢失概率是百分之十
- C.日志必须全部保留不能采样
- D.采样只影响延迟不影响请求
答案:A。采样只保留了 10% 的追踪数据,若想用样本量化全量请求的特征(如错误率),需要把统计值除以采样率做放大推算,像“抽查质检后按比例估算整批良品率”。B 混淆采样与丢失;C 日志与追踪策略独立;D 采样对各类统计都有影响。