尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

使用 Grafana Tempo 打造自定义服务图:从 metrics-generator 指标到 Node Graph 面板

使用 Grafana Tempo 打造自定义服务图:从 metrics-generator 指标到 Node Graph 面板 使用 Grafana Tempo 打造自定义服务图从 metrics-generator 指标到 Node Graph 面板【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo导读Grafana Tempo 的 metrics-generator 会从 trace 中推导出服务与服务之间的调用关系并输出traces_service_graph_request_total等 Prometheus 指标。本文讲解如何基于这些指标在 Grafanav10 及以上中使用Node graph 面板手工构建自定义服务图从准备前置条件、创建仪表盘变量、编写label_join查询到处理面板局限并结合 Tempo 仓库源码解释底层指标的产生机制帮助你完全掌控服务图的查询与展示逻辑。1. 什么是自定义服务图Tempo 内置的服务图Service Graph视图由 Grafana 数据源插件自动渲染而自定义服务图允许你脱离插件默认行为直接用 metrics-generator 产出的指标在 Grafana 中自行组织查询与可视化。正如 服务图总览 所述服务图是分布式系统中各服务之间相互关系的可视化表达能帮助推断分布式系统拓扑系统越复杂服务图越有助于理清结构提供系统健康状态的高层概览展示错误率、延迟及相关数据提供系统拓扑的历史视图观察系统随时间的演进。自定义服务图正是把这一可视化能力交到你自己手中——不依赖预置面板而是直接用 PromQL 从服务图指标中提取边edge再交给 Node graph 面板绘制。1.1 指标从哪来metrics-generator自定义服务图的全部数据都来自 metrics-generator。该组件在 Tempo 内部处理 trace识别具有父子关系的 span 对并输出服务图指标。仓库源码中定义了全部指标名称常量见 modules/generator/processor/servicegraphs/servicegraphs.goconst ( metricRequestTotal traces_service_graph_request_total metricRequestFailedTotal traces_service_graph_request_failed_total metricRequestServerSeconds traces_service_graph_request_server_seconds metricRequestClientSeconds traces_service_graph_request_client_seconds metricRequestMessagingSystemSeconds traces_service_graph_request_messaging_system_seconds metricConnectionInfo traces_service_graph_connection_info )其中traces_service_graph_request_total是自定义服务图的核心输入它携带两类关键信息服务间关系通过client和server标签表达谁调用了谁服务间请求总数Counter 类型的计数值可用increase()求增量。此外每条序列还带有connection_type标签其取值包括unset、virtual_node、messaging_system、database。仓库中同一文件内的 onComplete 回调 展示了这三个基础标签的写入逻辑builder.Add(client, e.ClientService) builder.Add(server, e.ServerService) builder.Add(connection_type, string(e.ConnectionType))关于如何开启 metrics-generator 的service-graphs处理器请参考 启用服务图生成后如何在内置视图查看可参考 服务图视图。2. 开始前的准备在动手构建自定义服务图前需要确认以下三样东西就绪依赖项说明Tempo metrics-generator负责从 trace 生成服务图指标并写入 Prometheus 兼容的指标存储Grafana v10 及以上提供 Node graph 面板能力v10 起 Node graph 进入正式可用状态Grafana Node graph 面板服务图的可视化载体通过边edges连接节点nodes展示调用拓扑前置的链路是Tempo 接收 trace → metrics-generator 产出服务图指标 → 指标落入 Prometheus → Grafana 查询指标并渲染 Node graph。若尚未启用服务图先参照 启用服务图 完成 Tempo 侧与 Grafana 数据源侧的配置。3. 创建 Grafana 仪表盘3.1 新建仪表盘在 Grafana 中创建一个新仪表盘作为自定义服务图的面板容器。之后我们需要为它添加两个变量让服务图可以按数据源和服务进行动态过滤。3.2 添加变量一数据源变量添加第一个变量类型为Prometheus的数据源Datasource变量变量项取值建议变量类型DatasourceTypePrometheusName例如datasource可自行命名该变量用于让面板在多个 Prometheus 数据源之间切换指向承载 metrics-generator 指标的那个数据源。3.3 添加变量二服务变量添加第二个变量类型为Label values用于动态列出可选的server/client服务名变量项取值建议变量类型Label valuesQuery typeLabel values数据源选择步骤 3.2 中的数据源变量Labelserver查询traces_service_graph_request_total的 server 标签多值Multi-value启用开启**多值选项multi-value**后你可以一次选中多个服务让服务图同时展示多个服务间的调用关系。该变量将贯穿后续查询中的$service引用。4. 添加服务图面板4.1 创建面板与查询在仪表盘中添加一个新面板然后按如下步骤配置创建面板其中包含一个名为edges的单一查询查询的数据源选择承载 metrics-generator 指标的 Prometheus 数据源或选择第 3 节中的$datasource变量使用下面的 PromQL 查询查询类型选择Instant瞬时查询。核心查询如下label_join( label_join( label_join( sum(increase(traces_service_graph_request_total{server~$service}[5m])) by (server, client) 0 or sum(increase(traces_service_graph_request_total{client~$service}[5m])) by (server, client) 0, source, , client), target, , server), id, -, server, client)该查询利用 Prometheus 的label_join操作符完成所有数据变换把指标标签整理成 Node graph 面板要求的id、source、target三个字段。4.2 查询逐层拆解理解这条查询需要从内到外看它的四层结构第一层聚合与过滤sum(increase(traces_service_graph_request_total{server~$service}[5m])) by (server, client) 0 or sum(increase(traces_service_graph_request_total{client~$service}[5m])) by (server, client) 0increase(...[5m])计算最近 5 分钟内两个服务之间的请求增量sum(...) by (server, client)按server与client分组聚合 0过滤掉没有流量的边查询被写了两次并用OR连接第一段筛选被选中服务作为服务端server的请求第二段筛选被选中服务作为调用端client的请求二者合并即可得到所有进出所选服务的请求组合——这正是 Node graph 中边的数据来源。第二层生成 source 字段label_join(..., source, , client)label_join将client标签的值复制到新字段source。Node graph 面板要求每条边有一个source指明边的起点因此这里把发起请求的服务client映射为 source。第三层生成 target 字段label_join(..., target, , server)同理server标签被复制到target代表边的终点被调用的服务。第四层生成 id 字段label_join(..., id, -, server, client)id是 Node graph 面板必需的字段用于唯一标识每条边。这里用-作为分隔符把server与client拼接成唯一 ID例如checkout-api-payment-api。注意label_join的第二个参数是字段名第三个参数是拼接分隔符从第四个参数起是要拼接的标签名。4.3 排错建议切换到 Table 视图如果面板没有按预期渲染可以先把可视化方式切换到Table表格数据视图检查查询返回的数据结构是否符合预期。Node graph 面板对数据形状有严格要求必须包含id、source、target等字段Table 视图能让你直观看到返回的字段名与取值便于定位问题。5. 查询方案的局限上述label_join查询大部分情况下可以完成任务但作者明确说明这些局限即使借助 Grafana 的数据变换transform data功能也无法弥补。具体包括无法为节点和边附加请求统计信息例如每秒请求数req/sec和错误率无法为节点设置自定义图标。也就是说纯 PromQL Node graph 面板的组合只能画出谁调用了谁的拓扑骨架无法在节点和边上富化延迟、错误率等指标也无法定制节点图标来区分服务类型。5.1 源码侧印证节点统计信息为何缺失从 modules/generator/processor/servicegraphs/servicegraphs.go 的onComplete实现可以看到服务图处理器确实分别记录了请求总数与失败数serviceGraphRequestTotal/serviceGraphRequestFailedTotal见 L440-L445客户端与服务端两侧的延迟直方图serviceGraphRequestServerSecondsHistogram/serviceGraphRequestClientSecondsHistogram见 L447-L462。这些指标以独立的序列存在与traces_service_graph_request_total是平行关系。要在服务图上展示 req/sec、错误率需要把多条指标序列在查询/变换层合并到同一条边上——而 Node graph 面板加label_join的简单组合并不具备这种多指标合并进边的能力这正是局限的根源。5.2 进阶方案REST API 包装 Infinity 数据源要突破上述局限官方给出的方向是把 Prometheus 查询包装成一个 REST API在 API 层完成更灵活的结果数据变换合并请求数、错误率、延迟等指标以及为不同服务附加图标元数据然后在 Grafana 中使用Infinity 数据源yesoreyeram-infinity-datasource插件从 REST API 拉取数据并交给 Node graph 面板渲染。这个方案的要点是在 REST API 内部执行多条 PromQL请求数、失败数、延迟直方图等在 API 层将结果按(server, client)边合并输出 Node graph 期望的id、source、target结构并附上req/s、error rate等附加字段若需要自定义节点图标可在 API 响应中为节点增加图标元数据字段Grafana 侧用 Infinity 数据源配置该 API 端点直接渲染 Node graph。这样既绕开了label_join只能搬运标签的限制也绕开了 Grafana transform 无法跨序列关联的瓶颈。6. 深入服务图指标的底层数据模型理解了查询语法后进一步了解指标的产生机制能帮你写出更精准的查询。6.1 处理器如何配对 span服务图处理器会检查每条 span 的span.kind直接请求出站 span 为client入站 span 为server消息系统请求出站为producer入站为consumer源码中由 isClient/isServer 统一归并producer 按 client 处理、consumer 按 server 处理数据库请求包含db.namespace、db.name、db.system或db.system.name属性的 client span。处理器把每个可能配对成功的 span 保存在内存 store中直到对应的另一端 span 到达或超过最大等待时间wait后把边记入指标并从本地 store 移除。仓库默认配置见 config.go 的 RegisterFlagsAndApplyDefaultswait默认 10 秒、max_items默认 10,000、workers默认 10、延迟直方图 bucket 采用指数桶起点 0.1、倍率 2、共 8 个。注意服务图处理器必须处理一条 trace 的全部 span才能正确配对边的两侧。如果同一条 trace 的 span 分散在多个 metrics-generator 实例上处理器将无法可靠配对。6.2 虚拟节点virtual node当边的一侧永远等不到时处理器会在 onExpire 中判断是否属于虚拟节点未被埋点、超出可观测范围的服务例如外部支付服务或未埋点的前端未埋点的客户端缺少 client span根 span 为 server/consumer 且无匹配 client。Tempo metrics-generator 会先检查peer_attributes命中则用作客户端节点名否则默认命名为user未埋点的服务端缺少 server spanclient span 带有 peer 属性默认依次为peer.service、db.name、db.system、db.system.name以第一个命中的属性值作为虚拟服务端节点名。这些边会被标记为connection_typevirtual_node在服务图中体现为无法观测的中间节点。6.3 全部服务图指标一览下表汇总了 metrics-generator 输出的全部服务图指标出自 服务图总览指标类型标签说明traces_service_graph_request_totalCounterclient, server, connection_type两个节点之间的请求总数traces_service_graph_request_failed_totalCounterclient, server, connection_type两个节点之间的失败请求总数traces_service_graph_request_server_secondsHistogramclient, server, connection_type从服务端视角观察的请求耗时traces_service_graph_request_client_secondsHistogramclient, server, connection_type从客户端视角观察的请求耗时traces_service_graph_request_messaging_system_secondsHistogramclient, server, connection_type默认关闭消息系统发布与消费之间的耗时traces_service_graph_connection_infoGaugeclient, server, connection_type默认关闭服务间边的关系存在信号活跃边取值为 1traces_service_graph_unpaired_spans_totalCounterclient, server, connection_type未配对 span 总数traces_service_graph_dropped_spans_totalCounterclient, server, connection_type被丢弃 span 总数自定义服务图进阶提示若想在你的查询里加入错误率可使用traces_service_graph_request_failed_total与traces_service_graph_request_total相除若想展示延迟可结合traces_service_graph_request_server_seconds直方图的histogram_quantile。这些都可以在 REST API 包装层完成作为第 5.2 节进阶方案的一部分。6.4 按需开启指标子处理器服务图指标默认全部生成但也可以通过 overrides 配置按类别开关详见 服务图总览service-graphs-request仅启用request_total与request_failed_total两个计数器service-graphs-latency仅启用服务端/客户端延迟直方图消息系统延迟直方图还需额外开启enable_messaging_system_latency_histogramservice-graphs-connection-info仅启用connection_info存在性 gauge默认关闭必须显式列出。裸名service-graphs兼容性开启 Request 与 Latency 两类把service-graphs-connection-info与裸名并列可叠加启用而不影响原有 RED 指标。仓库中 subprocessors.go 定义了这三类子处理器的解析逻辑servicegraphs_test.go中的 TestServiceGraphs_defaultDatabaseAttributeOrder 等测试锁定了默认属性顺序等行为。7. 从自定义查询到生产可用实践清单最后把以上内容整理成一份可直接照做的实施清单确认前置metrics-generator 已启用并产出traces_service_graph_request_totalGrafana ≥ v10Prometheus 数据源已连接。建仪表盘新建 Dashboard添加 Prometheus 数据源变量与 Label values 服务变量开启 multi-value。加面板创建edges查询选 Instant 查询类型粘贴第 4.1 节的label_join查询即可看到基础服务拓扑。排错面板空白时切到 Table 视图核对id、source、target字段是否存在且非空。进阶增强需要 req/sec、错误率或自定义节点图标时把 PromQL 包装成 REST API并用 Grafana Infinity 数据源接入渲染。监控开销服务数很多时注意指标基数cardinality问题可参考 metrics-from-traces 中的基数治理 进行评估与优化。总结自定义服务图的价值在于把服务图可视化从插件内置升级为完全可控底层数据来自 Tempo metrics-generator 的traces_service_graph_request_total等指标中间用 PromQLlabel_join完成 Node graph 所需字段的变换遇到指标富化与图标定制需求时则用 REST API Infinity 数据源方案兜底。理解服务图指标的产生机制span 配对、虚拟节点、连接类型、子处理器开关你就能写出更精准、更丰富的自定义服务图查询。【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表