news 2026/9/19 1:45:16

Grafana Tempo 可观测性指南:四大支柱、Trace 关联机制与落地实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Grafana Tempo 可观测性指南:四大支柱、Trace 关联机制与落地实践

Grafana Tempo 可观测性指南:四大支柱、Trace 关联机制与落地实践

【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo

可观测性(Observability)由指标(Metrics)、日志(Logs)、追踪(Traces)与性能剖析(Profiles)四大支柱构成,本指南以 Grafana Tempo 文档库中的《Traces and telemetry》为骨架,系统讲解四大信号各自的定位与相互关系,并深入 Tempo 仓库源码与配套文档,给出从指标跳转 Trace、从日志跳转 Trace 及反向关联的完整实践方案。读完本文,你将掌握四大支柱的协同原理,理解 Tempo 如何在自我追踪、指标生成(Exemplar)与自动日志记录等场景中打通信号间的关联,并能据此搭建自己的可观测性链路。

可观测性的四大支柱:各司其职的信号

Metrics、logs、traces 和 profiles 构成了可观测性的四大支柱。它们各自从不同维度回答"系统发生了什么"这一问题,而将这四类信号相互关联,才能形成对应用与基础设施的整体视图。这也是理解 Tempo 这类分布式追踪后端在整个可观测性体系中所处位置的前提。

指标(Metrics):量化系统状态的基石

指标从宏观层面描述系统的状态,是告警体系的基础,原因在于:

  • 指标是数值型数据,可以与已知阈值直接比较;
  • 告警规则可以在后台持续运行,当数值超出预期范围时触发通知;
  • 指标异常通常是第一信号,是问题发现(Discovery)的起点。

一句话概括:指标告诉你"有事情正在发生"(Metrics indicate that something is happening)。例如请求速率突然飙升、错误率越过阈值,都是通过指标最先感知的。

日志(Logs):单进程活动的审计轨迹

日志来自单一进程,以原子事件的形式记录服务内部正在发生的事,提供丰富的上下文信息:

  • 指标是定量的(numeric)、结构化的;日志是定性的(textual)、非结构化或半结构化的
  • 日志细节丰富,但代价是显著更高的数据量(higher data volumes);
  • 日志告诉你"应用正在发生什么"(what's happening to your application)。

在排障时,日志能回答"具体报了什么错、参数是什么",但缺少跨组件的交互上下文。

追踪(Traces):数据通路上的分步地图

追踪在可观测性图景上更进一步,它告诉你数据通路中每一步发生了什么,相当于一张"哪里出了问题"的地图:

  • 一个 trace 以图形化方式展示数据流中每个步骤耗时多少,例如一次 HTTP 请求、一次数据库查询、一次第三方服务调用分别耗时多少;
  • 它能展示请求从哪里发起、在哪里结束,以及系统如何响应;
  • 这种能力帮助你在从未预料到的地方定位问题区域并评估影响——没有追踪能力,这些瓶颈往往难以发现。

关于 trace 与 span 的基础模型,可参考仓库中的 Trace structure 文档 与 Glossary:trace 由若干 span 组成,span 是 trace 中的工作单元,带起始时间、持续时长与操作名,并可通过 parent 引用形成 span 树。

性能剖析(Profiles):定位可优化代码行

剖析帮助理解应用如何利用 CPU 时间、内存等计算资源,进而定位具体的代码行或函数进行优化,提升性能与效率。它是四大支柱中最"微观"的一类信号。

为什么需要 Trace:单靠指标与日志无法根治复杂问题

  • 指标自身不足以定位根因:它只能告诉你"出问题了",无法告诉你"为什么";
  • 日志虽信息量大,但缺乏复杂环境中各组件之间交互与依赖的上下文
  • 每一类信号在根因定位上都有独特优势,要最大化可观测性战略的价值,必须把它们关联起来(correlate them)。

Trace 的独特能力在于展示服务之间的关系

  • 识别你的服务**上游(upstream)**有哪些服务——这有助于理解"当你的服务出问题时,哪些服务会受负面影响";
  • 识别你的服务**下游(downstream)**有哪些服务——由于你的应用依赖这些下游服务,它们的故障很可能正是你服务报错或延迟升高的根源;
  • 例如,你可以直接看到正在失败的数据库以及所有受影响的边缘端点。

换句话说,trace 是在微服务架构中把"指标异常"翻译成"服务依赖关系"的关键桥梁。

从指标到 Trace:Exemplar 关联机制

指标与 trace 的关联核心是Exemplar(示例)。借助 exemplar,你可以从某个指标数据点直接跳到与之关联的 trace,例如从"某个百分位延迟异常"直接打开对应的一次完整请求追踪。

在 Tempo 中,Exemplar 有两种典型来源:

1. metrics-generator 自动生成 Exemplar

Tempo 的 metrics-generator 组件在处理传入 span 时,会基于 span 计算 RED 指标(Rate 请求速率、Error 错误率、Duration 持续时长直方图),并自动生成 exemplar,从而支持"指标 → trace"的一键跳转。该能力在 Metrics from traces 文档中有明确说明。

从源码看,service graphs 处理器在观测直方图时会携带 trace ID:在 servicegraphs.go 中,处理器通过e.TraceID()取得当前 span 的 trace ID,并在ObserveBorrowed(..., traceID, ...)时将 trace ID 写入指标观测,这正是 exemplar 携带 trace 标识的实现路径。

在配置层面,你可以通过metrics_generator.processor.span_metrics.trace_id_label_name指定生成指标中保存 trace ID 的标签名(默认值为traceID),详见 configuration/_index.md;该标签名必须是合法的 Prometheus 标签名,校验逻辑位于 validation/fields.go。

2. TraceQL 指标查询中的 Exemplar

Tempo 的 TraceQL 指标(metrics queries)为所有 range 查询提供 exemplar 能力:你可以在 query-frontend 中通过参数query_frontend.metrics.max_exemplars配置(默认100,设置为0表示禁用,见 configuration/_index.md),也可以在查询中直接加 hint:

{ span:name = "GET /:endpoint" } | quantile_over_time(duration, .99) by (span.http.target) with (exemplars=true)

这样,查询返回的时间序列上就会带上具体 trace 的引用,点开数据点即可跳转到完整 trace。详细说明见 TraceQL metrics 文档。

从 Trace 到日志、从日志到 Trace:双向跳转

除指标外,trace 与日志之间同样需要双向关联:

  • 从 trace 到日志:查看某一次请求的 trace 时,能看到沿途服务产生的日志条目,从而补充 trace 之外的异常细节;
  • 从日志到 trace:在日志中发现可疑的 trace ID 后,直接跳转到该 trace 查看完整调用链。

在 Tempo 生态中,实现日志 ↔ trace 关联最典型的手段是Grafana Alloy 的自动日志记录(Automatic logging)。其原理与配置在 automatic-logging.md 中有完整说明:

  • 自动日志记录通过otelcol.connector.spanlogs连接器从 trace span 生成日志行,每个 span/root/process 生成一条logfmt风格的日志,包含svc(服务名)、span(span 名)、dur(span 时长,纳秒)、tid(trace ID)、status(显式状态)等默认键;
  • 该连接器不会转发原始 trace,因此必须同时把 trace 发送给 trace 后端(如 Tempo),避免丢数据;
  • 生成的日志可写入 Loki,配合 Grafana 的 Loki 数据源Derived fields配置(匹配tid字段并指向 Tempo 数据源),即可在日志界面点击跳转到对应 trace。

例如下面的 Alloy 配置将 root span 记录为日志并发送到 OTLP 端点,同时把 trace 转发给同一端点:

otelcol.receiver.otlp "default" { grpc {} http {} output { traces = [ otelcol.connector.spanlogs.default.input, otelcol.exporter.otlp.default.input, ] } } otelcol.connector.spanlogs "default" { roots = true output { logs = [otelcol.exporter.otlp.default.input] } } otelcol.exporter.otlp "default" { client { endpoint = env("OTLP_ENDPOINT") } }

生成的 root span 日志行示例:

span="HTTP GET" dur=150200000ns http.method=GET http.target=/api/v1/query svc=my-service tid=7bba9f33312b3dbb8b2c2c62bb7abe2d

也可以直接用 LogQL 查询自动日志,例如筛选慢请求:

{traces="root"} | logfmt | dur > 2s and svc="my-service"

值得说明的是,Tempo 原生也提供等价的 TraceQL 搜索(无需 Loki),例如{ resource.service.name = "my-service" && span:duration > 2s }即可实现同样的慢请求发现。

让 Tempo 自己成为观测对象:自追踪与元监控

理解了四大支柱之后,一个自然的延伸问题是:追踪系统本身如何被观测?Tempo 仓库提供了两个层面的实践:

Tempo 自追踪(Self-tracing)

Tempo 使用 OpenTelemetry SDK 对自身进行插桩,可以通过环境变量导出自身产生的 trace(详见 self-tracing.md)。其底层初始化逻辑在 pkg/tracing/tracing.go 中实现:

  • InstallOTelOrJaegerFromEnvOTel 或 Jaeger 环境变量初始化全局 tracer,两者都未配置时为空操作(no-op);
  • 服务名默认为tempo-<target><target>-target标志的值),可用OTEL_SERVICE_NAMEJAEGER_SERVICE_NAME覆盖,且JAEGER_SERVICE_NAME优先(见 tracing.go);
  • 该函数由 cmd/tempo/main.go 在启动早期调用,并传入config.SpanProfiling以决定是否启用 span profiling。

关键环境变量包括:

类别环境变量说明
OTelOTEL_EXPORTER_OTLP_ENDPOINTOTLP 端点 URL,例如http://tempo:4318
OTelOTEL_EXPORTER_OTLP_TRACES_ENDPOINT仅 traces 的端点,覆盖上述端点
OTelOTEL_TRACES_EXPORTERtraces 导出器,默认otlp,设为none时仅传播上下文不导出
OTelOTEL_TRACES_SAMPLER/OTEL_TRACES_SAMPLER_ARG采样器与参数,支持always_onalways_offtraceidratioparentbased_*以及jaeger_remote
OTelOTEL_PROPAGATORS上下文传播器,默认tracecontextbaggagejaeger
OTelOTEL_RESOURCE_ATTRIBUTES附加的自定义 resource 属性
JaegerJAEGER_AGENT_HOST/JAEGER_ENDPOINTJaeger agent 主机 / collector 端点
JaegerJAEGER_SAMPLER_TYPE/JAEGER_SAMPLER_PARAM采样类型(constprobabilisticremote)与参数
JaegerJAEGER_AGENT_PORTJaeger agent 端口,默认6831
JaegerJAEGER_TAGSkey1=value1,key2=value2格式附加 resource 属性

仓库中的 tracing_test.go 对采样行为做了直接验证:例如always_on采样所有 trace、always_off不采样、traceidratio按比例采样,以及jaeger_remote/parentbased_jaeger_remoteinitialSamplingRate的解析与非法参数(缺少endpoint)的报错校验。

此外还支持强制采样单次请求:在请求上设置Jaeger-Debug-IdHTTP 头,Tempo 将无视采样配置强制采样该请求,并把头值作为jaeger-debug-idspan 属性写入(需激活jaeger传播器)。Span profiling 则可通过配置span_profiling: true--span-profiling标志开启,为 span 附加 pprof goroutine 标签与pyroscope.profile.id属性,将 trace span 与运行期间采集的 profile 关联起来——这正对应四大支柱中trace 与 profile 的关联

Tempo 元监控(Metamonitoring)

若想完整观测 Tempo 自身的指标与日志,可使用 set-up-monitoring.md 与共享文档 metamonitoring.md 描述的方案:通过 Grafana Kubernetes Helm chart(k8s-monitoring)配置 Grafana Alloy 抓取 Tempo 的prom-metrics端口指标与 Pod 日志,分别 remote-write 到 Prometheus/Mimir 与 Loki。其values.yml核心片段如下:

integrations: tempo: instances: - name: "traces" # instance 标签名 namespaces: - traces # 搜索 Tempo 实例的命名空间 metrics: enabled: true portName: prom-metrics logs: enabled: true labelSelectors: app.kubernetes.io/name: tempo destinations: - name: "metrics" type: prometheus url: "<url>" # 例如 https://<prometheus host>/api/prom/push - name: "logs" type: loki url: "<url>" # 例如 https://<loki host>/loki/api/v1/push

之后可从仓库的operations/tempo-mixin-compiled目录导入 8 个监控 Dashboard(如tempo-operational.json),并使用mimirtool上传rules.yamlalerts.yaml(分别对应 recording rules 与告警规则),实现"指标 → 告警 → 日志 → trace"的完整闭环监控。Mixin 源文件位于 operations/tempo-mixin,编译产物位于 operations/tempo-mixin-compiled。

总结:让四类信号协同工作

可观测性的价值不在于单个信号,而在于关联

信号回答的问题与其他信号的关联方式
Metrics是否有事情发生?Exemplar 跳转到 trace
Logs具体发生了什么?trace ID(tid)跳转到 trace,反之 trace 可下钻日志
Traces在哪一步、哪个服务出了问题?关联上下游服务、关联指标与日志
Profiles哪些代码需要优化?通过 span profiling 与 trace span 关联

Tempo 在整个体系中扮演 trace 的存储、检索与关联枢纽:借助 metrics-generator 与 TraceQL 指标生成携带 exemplar 的指标、借助自动日志记录打通日志侧入口、借助自追踪让自身也被四类信号观测。在实际部署中,建议结合 部署模式文档 与 架构文档 规划组件形态,再按本文所述逐步配置信号关联,最终形成"指标发现问题 → trace 定位链路 → 日志补充细节 → profile 优化性能"的完整排障工作流。

【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 1:40:52

MCP、Skill、Plugin 别再混用:Agent 扩展的三层选型与协作

上周有个做后端的哥们儿在群里问&#xff0c;他想让手里的 agent 能查公司内部接口文档&#xff0c;顺带按团队规范生成代码。有人让他写 MCP&#xff0c;有人说写个 Skill 就够了&#xff0c;还有人直接甩了篇 Plugin 开发教程过来。三份文档他都看了&#xff0c;结果比看之前…

作者头像 李华
网站建设 2026/9/19 1:39:47

Windows下Maven环境变量配置与mvn命令不被识别排查指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 1:37:55

轮式机器人直线控制:陀螺仪+PID航向闭环实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 1:36:39

Kotatsu 保姆级指南:Android 漫画阅读器从安装到离线追更

Kotatsu 保姆级指南&#xff1a;Android 漫画阅读器从安装到离线追更 【免费下载链接】Kotatsu Manga reader for Android 项目地址: https://gitcode.com/GitHub_Trending/ko/Kotatsu Kotatsu 是一款免费开源的 Android 漫画阅读器&#xff0c;内置 1200 多个漫画源&am…

作者头像 李华