理解 Grafana Tempo 中的 Trace 结构:Span 树、Intrinsics 与四类 Attributes

发布时间:2026/9/18 12:47:50
理解 Grafana Tempo 中的 Trace 结构:Span 树、Intrinsics 与四类 Attributes 理解 Grafana Tempo 中的 Trace 结构Span 树、Intrinsics 与四类 Attributes【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempoGrafana Tempo 以分布式追踪数据Trace为核心对象而理解 Trace 的树形结构与 Span 的字段体系是掌握 TraceQL 查询语言、构建高效追踪数据模型的前提。本文基于 Tempo 仓库共享文档docs/sources/tempo/shared/trace-structure.md展开结合 TraceQL 引擎源码系统讲解 Trace 树、Span 的固有属性Intrinsics与四类 Attributes帮助你准确理解能查什么、怎么查以及字段背后在 Tempo 中的真实实现。Trace 是一棵由 Span 组成的树追踪数据Trace在结构上是一棵树。一棵 Trace 树由若干个 Span 组成其中存在一个根 Spanroot span根 Span 可以有零到多个分支这些分支被称为子 Spanchild span而每个子 Span 又可以继续作为父 Span拥有一个或多个子 Span如此层层嵌套最终形成一棵完整的追踪树。用伪代码可以这样描述一棵 Trace 树Trace └── Root Span ├── Child Span A │ ├── Child Span A.1 │ └── Child Span A.2 └── Child Span B这种树形结构并非偶然它忠实反映了分布式系统中一次请求的真实执行过程根 Span 代表入口操作例如 HTTP 网关请求子 Span 代表被调用的下游服务、数据库访问、消息队列投递等子操作。正因为 Trace 是树TraceQL 才能基于父子关系兄弟关系祖先-后代关系等结构语义进行查询——这一点在pkg/traceql/enum_attributes.go中体现为IntrinsicStructuralDescendant、IntrinsicStructuralSibling、IntrinsicStructuralChild等结构型固有属性的定义见 enum_attributes.go。提示原共享文档引用的示意图trace-tree-structures-and-spans.png位于 Grafana 文档站的/media/docs/tempo/traceql/目录不随本仓库源码分发因此在阅读本仓库时可直接以Trace 树 根 Span 层层子 Span的模型理解。Span 的核心字段四个 Intrinsics在 Tempo 与 TraceQL 的具体语境下一个 Span 带有以下关联字段字段含义nameSpan 名称描述该 Span 所代表的操作durationSpan 的结束时间与开始时间之差即操作耗时status枚举类型取值为{ok, error, unset}kind枚举类型取值为{server, client, producer, consumer, internal, unspecified}Attributes键值对形式的自定义元数据见下文前四个属性被称为Intrinsics固有属性。Intrinsics 是 Span 与 Trace 身份和生命周期中最核心的内置字段由 OpenTelemetry 规范定义始终存在于每个 Span 中描述了分布式追踪数据的基本结构。Intrinsics 在 Tempo 源码中的体现在 Tempo 的 TraceQL 引擎中Intrinsics 被定义为一个完整的枚举类型位于pkg/traceql/enum_attributes.gotype Intrinsic int8 const ( IntrinsicNone Intrinsic iota IntrinsicDuration // duration IntrinsicName // name IntrinsicStatus // status IntrinsicStatusMessage // statusMessage IntrinsicKind // kind ... )见 enum_attributes.go除了文档重点介绍的name、duration、status、kind四个基础固有属性Tempo 的固有属性体系还扩展了大量可查询字段例如Span 级span:childCount子 Span 数量、span:id、span:parentIDTrace 级trace:duration、trace:rootName根 Span 名称、trace:rootService根 Span 服务名事件与链接event:name、event:timeSinceStart、link:spanID、link:traceID插桩信息instrumentation:name、instrumentation:version。这些字符串形式的固有属性名与枚举值之间的映射关系由intrinsicFromString()函数统一维护见 enum_attributes.go。也就是说你在 TraceQL 查询里写下的每个固有字段名最终都会经过该映射函数落到具体的枚举常量上再进入存储层的读取逻辑。status 与 kind 的取值验证关于 status 的枚举值{ok, error, unset}与 kind 的枚举值{server, client, producer, consumer, internal, unspecified}可以从 TraceQL 的单元测试中看到实际使用证据。在pkg/traceql/ast_test.go中StatusOk、StatusError、StatusUnset与KindClient、KindServer、KindUnspecified、KindInternal、KindConsumer等常量被大量用于静态值的构造、比较与序列化测试见 ast_test.go。例如测试代码将StatusUnset映射为整数值2、KindUnspecified对应0、KindClient对应2印证了这些枚举在 Tempo 内部是以确定的整型编码存储与比较的。AttributesSpan 的自定义键值对元数据与始终存在的 Intrinsics 不同Attributes属性是 Span 的自定义元数据以键值对key-value pairs形式存在。Tempo 将 Attributes 划分为四种类型Span Attributes、Resource Attributes、Event Attributes、Link Attributes。这四种作用域在 TraceQL 词法分析器中都有对应的语法前缀见pkg/traceql/lexer.goresource.: RESOURCE_DOT, span.: SPAN_DOT, event.: EVENT_DOT, link.: LINK_DOT,见 lexer.go同时pkg/traceql/enum_attributes.go中的AttributeScope枚举完整列出了 TraceQL 支持的全部属性作用域type AttributeScope int8 const ( AttributeScopeNone AttributeScope iota AttributeScopeTrace // trace AttributeScopeResource // resource AttributeScopeSpan // span AttributeScopeEvent // event AttributeScopeLink // link AttributeScopeInstrumentation // instrumentation ... )见 enum_attributes.goSpan Attributes标注被追踪操作的信息Span Attributes是键值对包含可用于给 Span 添加注解的元数据用来承载它所追踪操作的相关信息。例如在一个电商应用中如果一个 Span 追踪向用户购物车添加商品这一操作那么用户 ID、被添加的商品 ID 以及购物车 ID 都可以被捕获并作为 Span Attributes 附加到该 Span 上span.add item to cart ├── user_id u_1024 ├── item_id sku_778 └── cart_id cart_3301在 TraceQL 中这类属性通过span.前缀访问例如{ span.user_id u_1024 }。Resource Attributes描述产生 Span 的实体Resource Attributes表示关于产生该 Span 的实体的信息。例如一个由 Kubernetes 部署的容器中运行的进程创建的 Span可以关联一个描述集群名、命名空间、Pod 名和容器名的 Resourceresource ├── k8s.cluster.name prod-eu-1 ├── k8s.namespace.name checkout ├── k8s.pod.name checkout-api-7d9f8 └── k8s.container.name checkout-apiResource Attributes 是描述 Resource 的元数据键值对。它的典型特征是同源共享同一进程或同一容器、同一主机创建的所有 Span 通常共享同一组 Resource Attributes因此在 Tempo 的存储与查询层面Resource Attributes 往往与 Span 主体分开存放查询时通过resource.前缀统一访问例如{ resource.k8s.namespace.name checkout }。Event AttributesSpan 生命周期内的时间点Event Attributes表示 Span 持续期间的一个独特时间点。事件Event本身是发生在 Span 时间轴上的独立节点例如收到响应头发生重试出现异常等每个事件可以携带自己的名称、时间戳与键值对属性。在 TraceQL 中可以通过event:前缀的固有字段如event:name、event:timeSinceStart和event.作用域前缀对事件数据进行查询。Link Attributes跨 Span 的因果关联Link Attributes允许你在 Span 中查询链接Link数据。Span Link 将一个 Span 与一个或多个其他 Span 关联起来表达它们之间的因果关系causal relationship。典型场景包括批量任务一个父任务 Span 链接到它发起的多个子任务 Span消息队列生产者 Span 链接到消费者 Span跨越不同的 Trace。在 TraceQL 中链接数据通过link:固有字段如link:spanID、link:traceID与link.作用域前缀访问。Semantic Conventions跨语言统一的属性命名规范OpenTelemetry 规范为 Span 和 Resource 定义了Semantic Conventions语义约定。Semantic Span Attributes 是一套在语言、框架和运行时之间共享的属性命名方案——例如 HTTP 相关属性统一命名为http.request.method、http.response.status_code数据库相关属性统一为db.system.name、db.operation.name等。这套命名规范的价值在于可移植性无论使用哪种语言的 SDK 上报数据同一种语义的字段名保持一致跨组件关联Tempo 可以将来自不同技术栈、不同服务的 Span 放在同一棵 Trace 树下基于统一的属性名做关联查询TraceQL 可预测你不需要为每个服务单独记忆属性命名遵循语义约定的字段可以直接在查询中复用。在 TraceQL 中综合运用从结构到查询将上面的概念映射到实际查询就是 TraceQL 对 Trace 结构能力的具体体现。根据共享文档docs/sources/tempo/shared/traceql-query-structure.md的说明TraceQL 查询可以基于三类条件选择 TraceSpan 属性、时间与耗时例如{ span.user_id u_1024 duration 100ms }Span 之间的结构关系例如利用父子、兄弟等结构语义进行筛选Trace 内 Span 的聚合数据例如按根 Span 名称、服务名聚合统计。一个最简单的 TraceQL 查询{ }表示不设置任何过滤条件理论上返回所有 Span 及其所属 Trace实际运行时查询还会受时间区间相对如最近 3 小时或绝对时间范围、Limit返回的 Trace 数量上限和Span Limit每个 spanset 中 Span 数量上限的约束。关于 TraceQL 查询语法的完整构造方法可继续阅读本仓库中的 construct-traceql-queries.md本主题配套的查询结构说明见共享文档 traceql-query-structure.md。小结Trace 是树形结构的遥测数据由根 Span 与层层子 Span 组成Span 的四个固有属性Intrinsics——name、duration、status、kind——由 OpenTelemetry 定义且始终存在在 Tempo 中通过pkg/traceql/enum_attributes.go的枚举体系完整实现Attributes 分为 Span、Resource、Event、Link 四类分别描述被追踪操作、产生 Span 的实体、Span 内的时间点与跨 Span 的因果关联对应 TraceQL 中的span.、resource.、event.、link.作用域前缀Semantic Conventions 提供了跨语言统一的属性命名规范让不同技术栈的追踪数据能够在 Tempo 中被一致地关联与查询。理解这套结构体系是使用 TraceQL 检索复杂分布式系统问题、设计高质量追踪埋点的基础也是深入阅读 Tempo 查询引擎源码pkg/traceql/的起点。【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询