Tracing

GraphQL::Tracing::Trace provides hooks to observe and modify events during runtime. Tracing hooks are methods, defined in modules and mixed in with Schema.trace_with.

module CustomTrace
  def parse(query_string:)
    # measure, log, etc
    super
  end

  # ...
end

To include a trace module when running queries, add it to the schema with trace_with:

# Run `MyCustomTrace` for all queries
class MySchema < GraphQL::Schema
  trace_with(MyCustomTrace)
end

For a full list of methods and their arguments, see GraphQL::Tracing::Trace.

By default, GraphQL-Ruby makes a new trace instance when it runs a query. You can pass an existing instance as context: { trace: ... }. Also, GraphQL.parse( ..., trace: ...) accepts a trace instance.

Trace Modes

You can attach a trace module to run only in some circumstances by using mode:. For example, to add detailed tracing for only some requests:

trace_with DetailedTrace, mode: :detailed_metrics

Then, to opt into that trace, use context: { trace_mode: :detailed_metrics, ... } when executing queries.

Any custom trace modes also include the default trace_with ... modules (that is, those added without any particular mode: ... configuration).

ActiveSupport::Notifications

You can emit events to ActiveSupport::Notifications with an experimental tracer, ActiveSupportNotificationsTrace.

To enable it, install the tracer:

# Send execution events to ActiveSupport::Notifications
class MySchema < GraphQL::Schema
  trace_with(GraphQL::Tracing::ActiveSupportNotificationsTrace)
end

Monitoring

Several monitoring platforms are supported out-of-the box by GraphQL-Ruby (see platforms below).

Leaf fields are not monitored (to avoid high cardinality in the metrics service).

AppOptics

AppOptics instrumentation will be automatic starting with appoptics_apm-4.11.0.gem. For earlier gem versions please add appoptics_apm tracing as follows:

require 'appoptics_apm'

class MySchema < GraphQL::Schema
  trace_with GraphQL::Tracing::AppOpticsTrace
end

Appsignal

To add AppSignal instrumentation:

class MySchema < GraphQL::Schema
  trace_with GraphQL::Tracing::AppsignalTrace
end

New Relic

To add New Relic instrumentation:

class MySchema < GraphQL::Schema
  trace_with GraphQL::Tracing::NewRelicTrace
  # Optional, use the operation name to set the new relic transaction name:
  # trace_with GraphQL::Tracing::NewRelicTrace, set_transaction_name: true
end

Scout

To add Scout APM instrumentation:

class MySchema < GraphQL::Schema
  trace_with GraphQL::Tracing::ScoutTrace
end

Skylight

To add Skylight instrumentation, you may either enable the GraphQL probe or use ActiveSupportNotificationsTracing.

# config/application.rb
config.skylight.probes << "graphql"

GraphQL instrumentation for Skylight is available in versions >= 4.2.0.

Datadog

To add Datadog instrumentation:

class MySchema < GraphQL::Schema
  trace_with GraphQL::Tracing::DataDogTrace
end

For more details about Datadog’s tracing API, check out the Ruby documentation or the APM documentation for more product information.

Prometheus

To add Prometheus instrumentation:

require 'prometheus_exporter/client'

class MySchema < GraphQL::Schema
  trace_with GraphQL::Tracing::PrometheusTrace
end

The PrometheusExporter server must be run with a custom type collector that extends GraphQL::Tracing::PrometheusTracing::GraphQLCollector:

# lib/graphql_collector.rb
if defined?(PrometheusExporter::Server)
  require 'graphql/tracing'

  class GraphQLCollector < GraphQL::Tracing::PrometheusTrace::GraphQLCollector
  end
end
bundle exec prometheus_exporter -a lib/graphql_collector.rb

Sentry

To add Sentry instrumentation:

class MySchema < GraphQL::Schema
  trace_with GraphQL::Tracing::SentryTrace
end

Statsd

You can add Statsd instrumentation by initializing a statsd client and passing it to GraphQL::Tracing::StatsdTrace:

$statsd = Statsd.new 'localhost', 9125
# ...

class MySchema < GraphQL::Schema
  use GraphQL::Tracing::StatsdTrace, statsd: $statsd
end

Any Statsd client that implements .time(name) { ... } will work.