终端用户问答系列:使用OTel和GraphQL

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

在2023年1月26日星期四,OpenTelemetry终端用户工作组主办了2023年的第一个月度终端用户问答会议。该系列活动是一个月度的非正式讨论会,与正在生产中使用OpenTelemetry的团队进行交流。目标是了解他们的环境、成功经验和面临的挑战,并与社区分享,以便我们共同努力使OpenTelemetry更加出色!

本月,Dynatrace的Henrik Rexed与J进行了对话,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,他们正计划在LambdasECS等组件周围添加一些分布式跟踪。

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

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

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

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

在GraphQL中,有两种构建网关的系统。一种是使用Apollo Federation,另一种是通过模式拼接。模式拼接允许用户运行跨多个GraphQL API的单个查询。J的团队选择了模式拼接,因为与越来越受限制的Apollo相比,它更加开源、灵活和非专有。

这允许用户查询或修改所需的所有数据。GraphQL的用法包括微服务开发和提取数据进行分析。

如何生成跟踪?

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

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

跟踪被发送到他们的可观察性后端,并使用该供应商的代理程序安装在他们的所有节点上。

除了跟踪之外,您还使用其他信号吗?

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

长期目标是将此插件贡献给OpenTelemetry社区。然而,目前该插件与他们自己的系统耦合在一起,需要根据更通用的用例进行修改。此外,该插件需要在组织的开源软件组审核后才能在外部共享。

是否进行任何日志记录?

该团队使用Amazon ElasticacheELK堆栈进行日志记录。他们目前正在进行将.NET日志迁移到他们的可观察性后端的概念验证(POC)工作。最终目标是将指标日志跟踪集中在一个平台上。

他们目前已经能够使用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方面,该团队为HTTP、Express、GraphQL和一些系统使用了自动仪表化。最有用的仪表是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有少量的语言维护人员,因此他们可能没有足够的时间(有时甚至没有足够的专业知识)来管理贡献存储库(如GraphQL)。这是一个已知的问题,目前尚未找到解决方案。OpenTelemetry社区欢迎任何改进建议!

还有一个巨大的重点是稳定语义约定,作为这一努力的一部分,维护人员计划检查现有的仪表化包,确保它们都与最新的约定保持一致。虽然某些语言(如Java)的维护工作非常出色,但对于其他语言(如Node.js)来说并非如此。

由于以下原因,JavaScript环境类似于开发的“西部荒野”:

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

J的建议之一是将OTel JavaScript视为层次结构,从Core JavaScript团队开始,分为两个子组:前端Web组和后端组。前端和后端又可以细分。例如,对于后端,设立一个独立的Deno和Node.js组。

另一个建议是设立一个贡献者维护组,与核心SDK和API维护组分开。

JavaScript贡献

在某些情况下,进行OpenTelemetry JavaScript贡献变得缓慢,特别是在插件方面。许多插件的维护工作依赖于插件的原始所有者;然而,在许多情况下,原始所有者已经离职,或者维护者不经常检查GitHub,因此,某些拉取请求(PR)的进展非常缓慢。缓解这种情况的一种方法是让贡献者更多地参与进来,这可能有助于吸引更多的贡献者。

文档

J和他的团队也遇到了一些文档方面的挑战,注意到在线文档中存在一些空白:

  • 在JavaScript的指标部分,根本没有提及Observable Gauge。J不得不查找代码才找到它。
  • 有一些很短的非常高级的指标API示例。这些示例目前不显示需要引入的库。它也没有谈论如何导出项目。
  • 在.NET中,在工作中保持跟踪非常困难,因为存在大量的异步/等待和它们在线程之间的跳转。在这种特殊情况下,.NET文档缺少一些有关上下文传播的详细信息。

最后的想法

OpenTelemetry的一切都建立在社区基础上,没有贡献者、维护者和用户的支持,我们无法取得今天的成就。听到OpenTelemetry在实际应用中的故事只是了解的一部分。我们重视用户的反馈,并鼓励所有用户与我们分享您的经验,以便我们可以继续改进OpenTelemetry。❣️

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

确保在MastodonTwitter上关注OpenTelemetry,并使用**#OpenTelemetry**标签分享您的故事!