终端用户问答系列:将OTel与GraphQL结合使用

博客文章在发布后不会更新。这篇文章已经发布一年多了,其内容可能已过时,部分链接可能无效。在依赖任何信息之前,请务必核实。

Rynn Mancuso (Honeycomb) 和 Reese Lee (New Relic) 贡献。

2023 年 1 月 26 日,星期四,OpenTelemetry 终端用户工作组举办了 2023 年的首场月度终端用户问答环节。该系列活动每月邀请一支在生产环境中使用 OpenTelemetry 的团队进行一次非正式讨论。其目的是更多地了解他们的环境、成功经验和面临的挑战,并与社区分享,以便我们共同努力,让 OpenTelemetry 变得更加出色!

本月,Dynatrace 的 Henrik Rexed 与在一家金融服务公司工作的 J 进行了交流,讨论了他们如何使用 OpenTelemetry 和 GraphQL

概述

J 和他的团队开启 OpenTelemetry 之旅主要有两个原因:

  • J 的公司使用几种不同的可观测性后端。他的团队已经切换到一个供应商后端,该后端与他们交互的其他团队使用的后端不同。尽管使用了不同的供应商,OpenTelemetry 还是让他们能够继续获得端到端的追踪数据。
  • 他的团队正在使用 GraphQL,并且需要更好地了解其 GraphQL 调用背后发生的情况。

J 还分享了

  • 他的团队的 OpenTelemetry 设置
  • 他和他的团队如何帮助其他团队开始使用 OpenTelemetry
  • 他致力于使 OpenTelemetry 成为他组织的标准
  • 他和他的团队在 OpenTelemetry 之旅中遇到的挑战,以及一些改进建议。

问答

为什么选择 OpenTelemetry?

J 的公司拥有多样化的技术生态系统,从本地的传统大型机到 AWS 云和 Azure 云,他们运行 Windows 和 Linux 服务器。他们还使用多种语言,包括 Node.js.NETJava、C、C++ 和 PL/I(大型机)。

在整个组织中,不同的团队选择使用不同的可观测性平台来满足他们的需求,从而形成了开源和专有可观测性工具的混合。

J 的团队最近从一个可观测性后端迁移到了另一个。迁移后,他们开始出现追踪数据中的空白,因为他们集成的其他团队仍在使用的可观测性后端不同。结果,他们不再拥有追踪数据的端到端视图。解决方案是使用一种标准、供应商中立的方式来发出遥测数据:OpenTelemetry。

他的团队采用 OpenTelemetry 的另一个原因是 GraphQL,他们已经使用了四年。GraphQL 是一种用于查询和操作 API 的开源语言。使用 GraphQL,所有内容都包含在数据主体中:请求、响应和错误,因此所有内容都返回 HTTP 状态码 200,给人一种即使是失败也成功的印象。这意味着 J 和他的团队无法了解幕后发生的情况。

他们将大量数据传递到 GraphQL 响应中,因为他们有一个主网关,将所有不同的 GraphQL 端点整合到一个端点,因此看起来像一个巨大的查询。OpenTelemetry 暴露了来自其 GraphQL 系统的海量数据——追踪数据中包含多达 **三千到四千** 个跨度!已经对 Node.js GraphQL 系统进行了仪器化,并且也开始对他们的 .NET GraphQL 系统进行仪器化。

他们仍然面临的一个黑盒是关于 AWS 的,他们正在考虑为 LambdaECS 等组件添加一些分布式追踪。

应用程序如何部署到生产环境?

该团队使用 GitLab,并使用 GitLab 流水线进行 CI/CD,利用 Ansible Tower 来管理部署。GitLab 自定义流水线部署 Kubernetes YAML 文件(不使用 Helm)到 EKS 集群

该团队目前正处于计划使用 Amazon 的 cdk8s 来部署到 Kubernetes,并使用 Flagger 来管理这些部署(包括 金丝雀部署)的早期阶段。

GraphQL 中的查询是如何构建的?

有两种用于构建 GraphQL 网关的系统。一种是使用 Apollo Federation,另一种是通过 Schema Stitching。Schema stitching 允许用户运行跨越多个 GraphQL API 的单个查询。J 的团队选择了 Schema Stitching,因为与日益封闭的 Apollo 不同,它更加开源、灵活且专有性较低。

这允许用户查询或 变更 任意数量的数据。GraphQL 的用途包括微服务开发和提取数据进行分析。

您是如何生成追踪数据的?

为了仪器化他们的代码,他们配置了 Node.js SDK,并使用一些 Node.js 自动仪器化插件。虽然该团队目前仅使用 自动仪器化 来生成追踪数据和 跨度,但他们偶尔会向跨度添加更多数据(例如 属性)。他们通过获取 上下文 来查找跨度,并将自定义属性注入到这些跨度中。

目前该团队没有创建自定义跨度的计划,事实上,J 目前正在劝阻团队创建自己的自定义跨度。由于他们进行了大量的异步编程,开发人员很难理解上下文在异步进程中的行为方式。

使用安装在其所有节点上的供应商的代理将追踪数据发送到他们的可观测性后端。

除了追踪数据,您还使用其他信号吗?

该团队实现了一个自定义 Node.js 插件,用于获取有关 GraphQL 的特定 指标 数据,例如弃用字段的使用情况和整体查询使用情况,这是他们从追踪数据中无法获得的。这些指标通过 OpenTelemetry CollectorOTLP 指标接收器 发送到可观测性后端。

有一个长期目标是将此插件贡献回 OpenTelemetry 社区。但目前,该插件仍与他们自己的系统耦合,需要修改以适应更通用的用例。此外,在插件可以与外部共享之前,还需要由组织内的开源软件组进行审查。

您有进行日志记录吗?

该团队使用 Amazon ElasticacheELK stack 进行日志记录。他们目前正在进行一个概念验证 (POC),将 .NET 日志迁移到他们的可观测性后端。最终目标是将 指标日志追踪 整合到一个平台。

他们目前已经能够使用 Node.js Bunyan 自动将追踪数据链接到 ELK 中的日志。他们希望利用 OpenTelemetry 的 Exemplars 来链接追踪数据和指标。

组织如何将遥测数据发送到各种可观测性后端?

J 的团队结合使用了专有后端代理和 OpenTelemetry Collector(用于指标)。他们是 J 公司主要的 OpenTelemetry 用户之一,他希望帮助更多团队切换过来。

谁可以访问仪器化数据?

追踪数据用于诊断目的。如果在生产环境中出现问题,追踪数据可以帮助开发人员确定问题的根源。

由于 GraphQL 主要返回 HTTP 200 状态码,它给人一种没有错误返回的印象,但实际上,后台可能潜藏着错误。拥有追踪数据可以使开发人员看到响应体中是否存在实际错误。例如,在访问数据库时,如果出现连接挂起,GraphQL 会报告 HTTP 200,但追踪数据会显示存在错误,以及错误的位置。

SRE 团队还使用可观测性数据来改进系统可靠性和性能。

您如何描述整体的 OpenTelemetry 采用体验?

该团队的初始采用速度非常快,并且很容易——他们 80% 的追踪需求立即得到了满足。接下来的 20% 需要一些额外的概念验证工作,这些工作也相对较快地完成。总的来说,这是一个非常积极的体验。

J 的团队已经说服了几个其他团队使用 OpenTelemetry;但是,他们遇到了一些挑战。例如,J 希望确保这些团队放弃使用专有软件,例如 Apollo Studio,因为 OpenTelemetry 已经满足了相同的需求。

有计划在整个组织中使用 OpenTelemetry 吗?

该团队最近一直在与他们的内部开源软件 (OSS) 和企业架构 (EA) 团队进行沟通,以使 OpenTelemetry 成为企业标准。他们希望利用他们在生产级 OpenTelemetry 系统方面的成功经验来阐述 OpenTelemetry 在整个组织中的优势。

您是否看到了在生产环境中使用 OpenTelemetry 和 GraphQL 的好处?

使用 Node.js 的 GraphQL OpenTelemetry 插件 使识别生产环境中出现问题的 GraphQL 解析器变得非常容易。

您使用的仪器化库生成的输出对您有意义吗,还是您需要进行调整?

在 Node.js 端,该团队对 HTTPExpressGraphQL 以及某些系统上的 AWS SDK 使用了自动仪器化。

最有用的仪器化是 GraphQL 和 AWS SDK。尽管 GraphQL 自动仪器化非常有用,但仍有一些需要改进的地方,例如添加忽略某些字段的功能。J 已经为此提交了一个 Pull Request

该团队认为 HTTP 和 Express 的自动仪器化带来的好处不大。他们认为 HTTP 仪器化有点过于冗余。Express 的使用非常有限,因此其仪器化没有带来实际价值。此外,该团队计划在不久的将来从 Express 迁移到 GraphQL Yoga。他们预计迁移到 GraphQL Yoga 时会存在一些仪器化差距,因此计划为其编写一个 OpenTelemetry 插件,并打算将其贡献给 OpenTelemetry 社区。

您是否计划对大型机代码进行仪器化?

J 的团队使用的可观测性后端为大型机提供了原生仪器化。J 和他的团队本想使用 OpenTelemetry 来仪器化大型机代码。不幸的是,目前没有适用于 PL/I(以及 FORTRANCOBOL 等大型机语言)的 OpenTelemetry SDK。该团队很希望 OpenTelemetry 能够支持大型机,但不知道是否有足够的意愿来承担这项工作。

注意: 如果有人对此感兴趣或最终创建了适用于大型机的 OpenTelemetry 实现,请联系我们!

挑战/前进方向

在与 J 的对话中,他还分享了一些需要改进的领域和建议。

JavaScript 维护

OpenTelemetry 的语言维护者数量很少,因此他们没有足够的精力来处理所有事情。因此,他们目前专注于跟上规范变更,以更新 SDK 和 API。这意味着他们通常没有时间(有时甚至没有专业知识)来管理 contrib 仓库(例如 GraphQL)。这是一个已知问题,目前还没有解决方案。OpenTelemetry 社区欢迎任何改进建议!

此外,还在大力关注 稳定语义约定,作为该工作的一部分,维护者计划审查现有的仪器化库,并确保它们都与最新的约定保持一致。虽然某些语言(如 Java)维护得非常好,但其他语言(如 Node.js)则不然。

JavaScript 环境堪比开发领域的蛮荒之地,原因如下:

  • 多重维度:Web 端 vs 服务器端
  • 多种语言:JavaScript、TypeScript、Elm
  • 两种相似但不同的服务器端运行时:Node.js 和 Deno

J 的一个建议是将 OTel JavaScript 视为一个层级结构,从一个核心 JavaScript 团队开始,该团队分为两个子组:前端 Web 组和后端组。前端和后端又会进一步细分。例如,对于后端,要有单独的 Deno 和 Node.js 组。

另一个建议是设立一个 contrib 维护者小组,独立于核心 SDK 和 API 维护者小组。

JavaScript 贡献

OpenTelemetry JavaScript 的贡献有时进展缓慢,尤其是在插件方面。大部分插件的维护依赖于插件的原始所有者;然而,在许多情况下,原始所有者已不在,或者维护者不经常检查 GitHub,因此某些 Pull Request (PR) 的进展非常缓慢。一种缓解方法是让更多贡献者参与进来,这可能会吸引更多贡献者。

文档

J 和他的团队在文档方面也遇到了一些挑战,并指出在线文档存在一些不足之处:

  • 在 JavaScript 的指标部分,完全没有提到 Observable Gauge。J 只好查看代码才找到它。
  • 有一些简短、非常高级的指标 API 示例。这些示例目前没有显示需要引入哪些库。它也没有说明如何导出项目。
  • 在 .NET 中,由于大量的 async/await 以及在线程之间跳转,很难在工作中保持追踪。 .NET 文档在这一点上的上下文传播细节有所欠缺。

最后的想法

OpenTelemetry 关乎社区,没有我们的贡献者、维护者和用户,我们就不会有今天的成就。听到 OpenTelemetry 如何在现实生活中实现的案例只是图景的一部分。我们重视用户反馈,并鼓励所有用户与我们分享您的经验,以便我们能够继续改进 OpenTelemetry。❣️

如果您有关于您如何在组织中使用 OpenTelemetry 的故事要分享,我们很乐意倾听!分享方式

请务必在 MastodonTwitter 上关注 OpenTelemetry,并使用 #OpenTelemetry 标签分享您的故事!