Documentation
How Debugger Works ?

How GraphQL Debugger Works ?

GraphQL Debugger is a collection of integratable components when composed together provides a complete debugging solution for GraphQL. Leverging Open Telemetry and Open Source standards, GraphQL Debugger provides a way to instrument GraphQL servers and clients to collect and visualize the traces.

Trace Directive

The Trace GraphQL Directive wraps a resolver and collects instrumentation data. It is the most flexible way to trace your GraphQL API because you can apply it to any field you want to trace, however, it requires you to manually add the directive to your schema and add some boilerplate code to enable the directive at runtime.

directive @trace on FIELD_DEFINITION

You can apply the directive on a GraphQL Query or Mutation:

type Query {
  users: [User!]! @trace
}

Or on a GraphQL Field:

type User {
  name: String!
  email: String!
  balance: String! @trace # <--- Trace this field because its complex
}

Once applied, and picked up by your graphql runtime, the trace directive will essentally wrap that resolver and collect instrumentation data.

async function resolver() {
  const user = await getUserFromDb();
  return user;
}

Trace Schema

Using Trace Schema you can automatically add the Trace Directive to your schema and enable tracing for all fields. This is a great way to get started with tracing your GraphQL API as it requires no changes to your schema or resolvers plus it sets up Open Telemetry and Schema Exporters for you.

import { traceSchema } from '@graphql-debugger/trace-schema';
import { makeExecutableSchema } from 'graphql-tools';
 
const typeDefs = `
    type Query {
        users: [User!]!
    }
 
    type User {
        name: String!
        email: String!
        balance: String!
    }
`;
 
const schema = makeExecutableSchema({
    typeDefs,
    resolvers: {
        Query: {
            users: () => [{...}]
        }
    }
});
 
// Schema with tracing applied to all fields
const tracedSchema = traceSchema({
    schema,
    adapter: // <-- See Adapters
});
type Query {
  users: [User!]!
}
 
type User {
  name: String!
  email: String!
  balance: String!
}
 

Schema Exporter

When using Trace Schema, in the background, the schema will be hashed and exported to The Collector, this is done so that the Collector can identify the schema for each received trace.

You can disable Schema Export by passing shouldExportSchema: false to the traceSchema function.

const tracedSchema = traceSchema({
  schema,
  adapter,
  shouldExportSchema: false, // <-- Disable schema export
});

OTEL Setup

Alongside the Schema Exporter mechanism, Trace Schema will also setup the nessary Open Telemetry exporters and propagators using the standard API's. Using the options for Trace Schema you can configure what endpoint the traces should be sent to.

const tracedSchema = traceSchema({
    schema,
    adapter,
    exporterConfig: {
        url: 'https://trace-api.newrelic.com/trace/v1',
    }
});

Given that GraphQL Debugger Collector is a proxy over a Open Telemetry Collector, you can also point your GraphQL traces to any Open Telemetry compatible collector as showin in the example above.

Collector

The Collector is a service that listens for the traces propagated from the GraphQL API and stores them in a database. It contains endpoints that ingest the schema, traces and spans.

Schema Endpoint

  • /v1/schema

Trace Schema will hash and send the schema on startup to the collector. You can also send the schema manually using the endpoint, or the Client. Without a schema, debugger cannot visualize the traces and any exported traces wont be shown in the UI.

Traces Endpoint

  • /v1/traces

This is a Open Telemetry compatible endpoint that accepts traces in the OTLP HTTP format. This means you can send any traces from any Open Telemetry compatible client to the collector and it will be stored in the database, however, if the traces dont come from GraphQL Debugger, they wont be visualized in the UI.

Each GraphQL Debugger trace attaches a schemaHash attribute that reconciles the trace with the schema. That schemaHash is picked up in the traces endpoint and used to associate the trace with the schema.

UI

The UI is a React application that visualizes the traces stored in the database. It contains a dashboard that shows the traces and spans, and a trace viewer that shows the trace details. It communicates with The Backend via The GraphQL Schema using the The Client.

Learn more about the UI and how to get stated here.