Other integrations

OpenTelemetry with GraphQL Yoga and Hive Gateway

Set up OpenTelemetry tracing for GraphQL Yoga or Hive Gateway and send traces to Hive Console.

OpenTelemetry tracing in Hive Console is currently in preview. Submit a support ticket to enable it for your organization.

The @graphql-hive/plugin-opentelemetry package instruments incoming HTTP requests, the GraphQL execution lifecycle, and outgoing subgraph requests. You can use it with GraphQL Yoga or a programmatic Hive Gateway deployment.

This guide configures the plugin in a Node.js application. You can send traces only to Hive Console or add Hive Console as a second destination alongside Datadog, Grafana, Honeycomb, or another existing OpenTelemetry backend. For more configuration options, see the Hive Gateway Monitoring and Tracing guide.

Prerequisites

Create an access token with permission to send traces and find your target reference. The target can be a slug in the format $organizationSlug/$projectSlug/$targetSlug or a target UUID.

Make both values available to your application:

HIVE_TARGET="my-organization/my-project/production"
HIVE_TRACING_ACCESS_TOKEN="your-access-token"

Installation

npm i @graphql-hive/plugin-opentelemetry @opentelemetry/context-async-hooks

Initialize OpenTelemetry

Create a module that registers the OpenTelemetry context manager, trace provider, and Hive exporter:

telemetry.ts
import { hiveTracingSetup } from "@graphql-hive/plugin-opentelemetry/setup";
import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-hooks";

hiveTracingSetup({
  contextManager: new AsyncLocalStorageContextManager(),
  target: process.env["HIVE_TARGET"]!,
  accessToken: process.env["HIVE_TRACING_ACCESS_TOKEN"]!,
  resource: {
    serviceName: "my-graphql-service",
  },
  // Optional for self-hosted Hive:
  // endpoint: process.env["HIVE_TRACING_ENDPOINT"],
});

Import this module before importing and creating Yoga or Hive Gateway. Call hiveTracingSetup only once in each process because it registers global OpenTelemetry APIs.

hiveTracingSetup configures where spans are exported. useOpenTelemetry instruments requests and creates the spans. Both steps are required unless your application already initializes an OpenTelemetry SDK and exporter.

Keep your existing OpenTelemetry backend

Probably your applications already send traces to an observability provider like DataDog. You do not need to replace that setup to try Hive Console. Use one OpenTelemetry provider and configure it with a span processor for each destination.

Do not call hiveTracingSetup or register a second provider in this case. Add HiveTracingSpanProcessor to your existing SDK configuration before starting the provider:

npm i @opentelemetry/exporter-trace-otlp-http @opentelemetry/sdk-node
telemetry.ts
import { HiveTracingSpanProcessor } from "@graphql-hive/plugin-opentelemetry/setup";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { NodeSDK, tracing } from "@opentelemetry/sdk-node";

const sdk = new NodeSDK({
  // Keep your existing resource, instrumentations, and other SDK options here.
  spanProcessors: [
    // Your existing backend. This exporter can also use the standard OTEL_EXPORTER_* variables.
    new tracing.BatchSpanProcessor(
      new OTLPTraceExporter({
        url: process.env["EXISTING_OTLP_TRACES_ENDPOINT"],
      }),
    ),
    // HiveTracingSpanProcessor batches and exports a copy of each Hive trace to Hive Console.
    new HiveTracingSpanProcessor({
      endpoint:
        process.env["HIVE_TRACING_ENDPOINT"] ??
        "https://api.graphql-hive.com/otel/v1/traces",
      target: process.env["HIVE_TARGET"]!,
      accessToken: process.env["HIVE_TRACING_ACCESS_TOKEN"]!,
    }),
  ],
});

sdk.start();

Your existing backend continues receiving all spans. The Hive processor selects and transforms Hive request traces before sending them to Hive Console. Use this same telemetry.ts as the first import in the Yoga or Gateway examples below.

Add the plugin

Import the setup module first, then add useOpenTelemetry to Yoga's plugins:

server.ts
import "./telemetry";
import { createServer } from "node:http";
import { useOpenTelemetry } from "@graphql-hive/plugin-opentelemetry";
import { createYoga } from "graphql-yoga";
import { schema } from "./schema";

const yoga = createYoga({
  schema,
  plugins: [
    useOpenTelemetry({
      traces: true,
    }),
  ],
});

createServer(yoga).listen(4000);

When running Hive Gateway from a configuration file, use its openTelemetry option. Gateway adds useOpenTelemetry internally and supplies its runtime context to the plugin:

gateway.config.ts
import "./telemetry";
import { defineConfig } from "@graphql-hive/gateway";

export const gatewayConfig = defineConfig({
  openTelemetry: {
    traces: true,
  },
});

The Gateway package also re-exports the setup utility from @graphql-hive/gateway/opentelemetry/setup. The direct plugin import used in this guide works for both Yoga and programmatic Gateway applications.

When creating the Gateway runtime programmatically, add the plugin directly. Spread the runtime context into the options so the plugin can instrument Gateway-specific operations and use the Gateway logger:

gateway.ts
import "./telemetry";
import { createGatewayRuntime } from "@graphql-hive/gateway-runtime";
import { useOpenTelemetry } from "@graphql-hive/plugin-opentelemetry";

export const gateway = createGatewayRuntime({
  plugins: (context) => [
    useOpenTelemetry({
      ...context,
      traces: true,
    }),
  ],
});

Verify the setup

Start the server and send a GraphQL operation through its HTTP endpoint. Open the target's Traces view in Hive Console and select a recent operation. The trace should contain the HTTP and GraphQL lifecycle spans. Gateway traces also contain spans for subgraph requests.

If no traces appear, verify that:

  • telemetry.ts is imported before the server or Gateway is created.
  • The access token can send traces to the configured target.
  • HIVE_TARGET points to the same target you opened in Hive Console.
  • A self-hosted HIVE_TRACING_ENDPOINT is reachable from the application.
  • OTEL_SDK_DISABLED is not set to true.

For sampling, custom exporters, context propagation, span filters, and custom attributes, see the OpenTelemetry Traces reference.

Send traces without the JavaScript plugin

Servers and routers written in other languages can send OTLP over HTTP directly to Hive Console:

POST https://api.graphql-hive.com/otel/v1/traces
Authorization: Bearer <HIVE_TRACING_ACCESS_TOKEN>
X-Hive-Target-Ref: <ORGANIZATION>/<PROJECT>/<TARGET>

Use the normal OTLP protobuf or JSON request format. The target header also accepts a target UUID.

Operation root span

Hive Console treats a parentless span with a truthy hive.graphql attribute as a GraphQL operation root. This marker is the only attribute required for ingestion, but the supporting attributes below are needed for useful labels, filters, error status, and federation views.

Emit one operation root for every executed GraphQL operation with this minimum shape:

parent span ID: empty
span name: graphql.operation
attributes:
  hive.graphql: true
  graphql.operation.type: query
  graphql.operation.name: GetProducts
  graphql.document: query GetProducts { products { id name } }
  http.status_code: 200

If your instrumentation creates an HTTP server span above the operation, either export the operation as the parentless Hive trace root or reproduce the transformation performed by HiveTracingSpanProcessor: remove the operation's parent, copy the HTTP attributes to it, and use the HTTP request's start and end times. This makes the operation discoverable while preserving the full request duration.

Hive attributes

Use native OTLP booleans, integers, strings, and string arrays rather than encoding values as JSON strings.

AttributeTypeSpanDescription
hive.graphqlbooleanOperation rootRequired marker for a GraphQL operation trace. Set it to true.
hive.graphql.operation.hashstringOperation rootStable identity of the normalized operation. Used to correlate and filter repeated operations.
hive.graphql.error.countintegerOperation rootTotal GraphQL parse, validation, and execution errors. Omit it or set it to 0 when there are no errors.
hive.graphql.error.codesstring[]Operation rootValues of error.extensions.code for GraphQL errors that provide a code.
hive.client.namestringOperation rootClient application name, commonly read from graphql-client-name or x-graphql-client-name.
hive.client.versionstringOperation rootClient version, commonly read from graphql-client-version or x-graphql-client-version.
hive.request.idstringOperation rootApplication request ID for correlation with logs and other telemetry.
hive.gateway.operation.subgraph.namesstring[]Operation rootNames of all subgraphs contacted while executing a federated operation.
hive.gateway.upstream.subgraph.namestringSubgraph client spanName of the subgraph represented by this span.
hive.upstreambooleanSubgraph client spanMarks a logical subgraph execution. Set it to true.
hive.requestbooleanHTTP server spanMarks the plugin's HTTP request span for processing. Not needed when emitting the final operation root.

The JavaScript plugin's operation hash is a lowercase MD5 digest of the normalized operation body, selected operation name, and sorted unique schema coordinates. Its normalization removes aliases, normalizes literal values, and sorts definitions, selections, arguments, directives, and variables. Other implementations may provide their own stable hash, but matching this algorithm keeps operation identities consistent across services using the JavaScript plugin.

For a federated trace, make each logical subgraph execution a child client span of the operation. Set both hive.upstream and hive.gateway.upstream.subgraph.name on that span, then make the outgoing HTTP request span its child. Also add the complete list of contacted subgraphs to hive.gateway.operation.subgraph.names on the operation root.

GraphQL attributes

These attributes are not in the hive.* namespace, but Hive Console uses them as first-class operation metadata:

AttributeTypeDescription
graphql.documentstringPrinted GraphQL document. Also enables the operation source view.
graphql.operation.namestringSelected operation name. Omit it for an anonymous operation.
graphql.operation.typestringOne of query, mutation, or subscription.

HTTP attributes

Copy these HTTP server span attributes to the operation root. Hive Console currently uses these exact attribute names for trace filters and success classification:

AttributeTypeDescription
http.status_codeintegerHTTP response status code.
http.methodstringHTTP request method.
http.hoststringRequest host.
http.routestringMatched server route.
http.urlstringFull request URL.

Set the standard OpenTelemetry span status to ERROR for failures. You can also record standard exception events with exception.type, exception.message, and exception.stacktrace; Hive Console renders these in the span details.

Set service.name and service.version as standard OpenTelemetry resource attributes. All other resource attributes, span attributes, links, and events remain available in the detailed trace view.