Apollo Federation 中的 OpenTelemetry
配置您的联邦图以发出日志、跟踪和指标
OpenTelemetry 是一组用于以通用和一致的方式从不同系统生成和处理遥测数据(如日志、跟踪和指标)的开源工具集合。
您可以为您的网关、单独的子图,甚至是一个单体 Apollo Server 实例来发出与 GraphQL 操作相关的遥测。
此外,@apollo/gateway
库提供了内置的 OpenTelemetry 仪表用于发出 网关特定跨度 以支持 操作 跟踪。
如果您使用 GraphOS Router,它已预装了对 OpenTelemetry 的支持 概述。
ⓘ 注意
GraphOS Studio 当前无法消费 OpenTelemetry 格式的数据。要将跟踪数据推送到 Studio,请参阅 联邦跟踪数据。
设置
1. 安装所需的库
要在您的应用程序中使用OpenTelemetry,您需要安装一组@opentelemetry
Node.js库。这一组合根据您是在设置联邦网关还是子图/单体而有所不同。
最重要的是,子图和单体必须安装@opentelemetry/instrumentation-graphql
,而网关则不需要安装。
如上所示,大多数@opentelemetry
库已达到1.0
版本。上述的仪器包在本写作时是兼容的。
更新 @apollo/gateway
如果您在使用联盟网关中的OpenTelemetry,请更新库 @apollo/gateway
到版本0.31.1
或更晚版本以添加对网关特定span的支持。
2. 配置工具
接下来,更新您的应用程序以便在应用程序的执行过程中尽早配置OpenTelemetry工具。此步骤必须在导入@apollo/server
、express
或http
之前完成。否则,您的跟踪数据将是不完整的。
我们建议将此配置放入其自己的文件中,并在index.js
文件的顶部导入。以下是一个示例文件(注意以下应删除或取消注释的行):
// Import required symbolsconst { Resource } = require('@opentelemetry/resources');const { SimpleSpanProcessor, ConsoleSpanExporter } = require ("@opentelemetry/sdk-trace-base");const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");const { registerInstrumentations } = require('@opentelemetry/instrumentation');const { HttpInstrumentation } = require ('@opentelemetry/instrumentation-http');const { ExpressInstrumentation } = require ('@opentelemetry/instrumentation-express');// DELETE IF SETTING UP A GATEWAY, UNCOMMENT OTHERWISE// const { GraphQLInstrumentation } = require ('@opentelemetry/instrumentation-graphql');// Register server-related instrumentationregisterInstrumentations({instrumentations: [new HttpInstrumentation(),new ExpressInstrumentation(),// DELETE IF SETTING UP A GATEWAY, UNCOMMENT OTHERWISE//new GraphQLInstrumentation()]});// Initialize provider and identify this particular service// (in this case, we're implementing a federated gateway)const provider = new NodeTracerProvider({resource: Resource.default().merge(new Resource({// Replace with any string to identify this service in your system"service.name": "gateway",})),});// Configure a test exporter to print all traces to the consoleconst consoleExporter = new ConsoleSpanExporter();provider.addSpanProcessor(new SimpleSpanProcessor(consoleExporter));// Register the provider to begin tracingprovider.register();
截至目前,此代码不会将跟踪数据推送到外部系统。相反,它将其打印到控制台以进行调试。
在您对应用程序做出这些更改后,本地启动它。它应该开始打印类似以下跟踪数据
很好!接下来,我们可以修改此代码,以开始将跟踪数据推送到外部服务,例如Zipkin或Jaeger。
3. 将跟踪数据推送到跟踪系统
接下来,让我们修改上一步骤中的代码,将其推送到本地上运行的实例Zipkin。
ⓘ 注意
要在本地运行Zipkin,请查看快速入门指南。如果您想使用不同的跟踪系统,请参阅该系统的文档。
首先,我们需要将ConsoleSpanExporter
(将跟踪输出到终端)替换为ZipkinExporter
,它专门将跟踪数据推送到运行的Zipkin实例。
安装以下库
然后,将ZipkinExporter
导入您的专用 OpenTelemetry 文件:
const { ZipkinExporter } = require("@opentelemetry/exporter-zipkin");
现在我们可以将我们的 ConsoleSpanExporter
替换为 ZipkinExporter
。将上一步代码中第 31-34 行替换为以下内容:
// Configure an exporter that pushes all traces to Zipkin// (This assumes Zipkin is running on localhost at the// default port of 9411)const zipkinExporter = new ZipkinExporter({// url: set_this_if_not_running_zipkin_locally});provider.addSpanProcessor(new SimpleSpanProcessor(zipkinExporter));
现在,请在浏览器中打开 Zipkin,地址为 https://127.0.0.1:9411
。您现在应该能够在 UI 中查询最近的追踪数据!
您可以通过展开任何操作查看其详情,并按 span 对其处理时间线进行细分。
4. 准备生产更新
我们的示例遥测配置假定 Zipkin 本地运行,并且我们希望逐个处理每个发出的 span。
为了准备生产,我们将希望通过将我们的追踪发送到 OpenTelemetry Collector来优化性能,OTLPTraceExporter
并用 SimpleSpanProcessor
替换我们的 BatchSpanProcessor
。Collector 应部署为本地的边车代理,在发送到最后目的地之前缓冲追踪数据。请参阅 入门文档了解概述。
然后,在您的专用 OpenTelemetry
文件中导入 OTLPTraceExporter
和 BatchSpanProcessor
。
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base");
现在我们可以将我们的 ZipkinExporter
替换为 OTLPTraceExporter
。我们还可以将我们的 SimpleSpanProcessor
替换为 BatchSpanProcessor
。将上一步代码中第 4-9 行替换为以下内容:
// Configure an exporter that pushes all traces to a Collector// (This assumes the Collector is running on the default url// of https://127.0.0.1:4318/v1/traces)const collectorTraceExporter = new OTLPTraceExporter();provider.addSpanProcessor(new BatchSpanProcessor(collectorTraceExporter, {maxQueueSize: 1000,scheduledDelayMillis: 1000,}),);
您可以在 仪器文档中了解更多关于使用 OTLPTraceExporter
的信息。
GraphQL 特定的 spans
The @opentelemetry/instrumentation-graphql
库允许子图和单体应用在 OpenTelemetry 跟踪 中发出以下跟踪信息:
名称 | 描述 |
---|---|
graphql.parse | 服务器解析操作字符串花费的时间。 |
graphql.validate | 服务器验证操作字符串花费的时间。 |
graphql.execute | 服务器执行操作的总时间。 |
graphql.resolve | 服务器解析特定字段花费的时间。 |
请注意,并非每个 GraphQL 跟踪都在每个 跟踪信息中。这是因为在 Apollo 服务器 中,如果该字符串已存在于操作缓存中,可以跳过解析或验证该操作字符串。
ⓘ 注意
联邦网关不允许安装 @opentelemetry/instrumentation-graphql
库,因此这些跟踪信息不包括在其跟踪信息中。
特定于网关的跟踪信息
@apollo/gateway
库在 OpenTelemetry 跟踪 中发出以下跟踪信息:
名称 | 描述 |
---|---|
gateway.request | 网关处理请求的总时间。 |
gateway.validate | 网关验证 GraphQL 操作字符串花费的时间。 |
gateway.plan | 网关为已验证操作生成查询计划花费的时间。 |
gateway.execute | 网关在子图中执行操作花费的时间。 |
gateway.fetch | 网关从特定子图中获取数据花费的时间。 |
gateway.postprocessing | 网关合成完整响应从单个子图响应花费的时间。 |