Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GraphQL: Instrument with GraphQL::Tracing::DataDogTrace #3417

Merged
merged 1 commit into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions docs/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -848,24 +848,26 @@ The `instrument :graphql` method accepts the following parameters. Additional op
| Key | Description | Default |
| --- | ----------- | ------- |
| `schemas` | Array of `GraphQL::Schema` objects (that support class-based schema only) to trace. If you do not provide any, then tracing will applied to all the schemas. | `[]` |
| `with_deprecated_tracer` | Enable to instrument with deprecated `GraphQL::Tracing::DataDogTracing`. Default is `false`, using `GraphQL::Tracing::DataDogTrace` | `false` |
| `service_name` | Service name used for graphql instrumentation | `'ruby-graphql'` |

**Manually configuring GraphQL schemas**

If you prefer to individually configure the tracer settings for a schema (e.g. you have multiple schemas with different service names), in the schema definition, you can add the following [using the GraphQL API](http://graphql-ruby.org/queries/tracing.html):
If you prefer to individually configure the tracer settings for a schema (e.g. you have multiple schemas), in the schema definition, you can add the following [using the GraphQL API](http://graphql-ruby.org/queries/tracing.html):

With `GraphQL::Tracing::DataDogTrace`

```ruby
# Class-based schema
class YourSchema < GraphQL::Schema
use(GraphQL::Tracing::DataDogTracing)
trace_with GraphQL::Tracing::DataDogTrace
end
```

Or you can modify an already defined schema:
or with `GraphQL::Tracing::DataDogTracing` (deprecated)

```ruby
# Class-based schema
YourSchema.use(GraphQL::Tracing::DataDogTracing)
class YourSchema < GraphQL::Schema
use(GraphQL::Tracing::DataDogTracing)
end
```

**Note**: This integration does not support define-style schemas. Only class-based schemas are supported.
Expand Down
5 changes: 5 additions & 0 deletions lib/datadog/tracing/contrib/graphql/configuration/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ class Settings < Contrib::Configuration::Settings
end

option :service_name

option :with_deprecated_tracer do |o|
o.type :bool
o.default false
end
end
end
end
Expand Down
7 changes: 5 additions & 2 deletions lib/datadog/tracing/contrib/graphql/integration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ def self.version
end

def self.loaded?
!defined?(::GraphQL).nil? \
&& !defined?(::GraphQL::Tracing::DataDogTracing).nil?
!defined?(::GraphQL).nil?
end

# Breaking changes are introduced in `2.2.6` and have been backported to
Expand All @@ -37,6 +36,10 @@ def self.compatible?
)
end

def self.trace_supported?
version >= Gem::Version.new('2.0.19')
end

def new_configuration
Configuration::Settings.new
end
Expand Down
26 changes: 15 additions & 11 deletions lib/datadog/tracing/contrib/graphql/patcher.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
require_relative '../analytics'
require_relative '../patcher'
require_relative 'tracing_patcher'
require_relative 'trace_patcher'

module Datadog
module Tracing
Expand All @@ -16,18 +18,16 @@ def target_version
end

def patch
schemas = configuration[:schemas]

if schemas.empty?
::GraphQL::Schema.tracer(::GraphQL::Tracing::DataDogTracing.new(**trace_options))
if configuration[:with_deprecated_tracer]
TracingPatcher.patch!(schemas, trace_options)
elsif Integration.trace_supported?
TracePatcher.patch!(schemas, trace_options)
else
schemas.each do |schema|
if schema.respond_to? :use
schema.use(::GraphQL::Tracing::DataDogTracing, **trace_options)
else
Datadog.logger.warn("Unable to patch #{schema}, please migrate to class-based schema.")
end
end
Datadog.logger.warn(
"GraphQL version (#{target_version}) does not support GraphQL::Tracing::DataDogTrace. "\
'Falling back to GraphQL::Tracing::DataDogTracing.'
)
TracingPatcher.patch!(schemas, trace_options)
end
end

Expand All @@ -42,6 +42,10 @@ def trace_options
def configuration
Datadog.configuration.tracing[:graphql]
end

def schemas
configuration[:schemas]
end
end
end
end
Expand Down
24 changes: 24 additions & 0 deletions lib/datadog/tracing/contrib/graphql/trace_patcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

module Datadog
module Tracing
module Contrib
module GraphQL
# Provides instrumentation for `graphql` through with GraphQL's trace
module TracePatcher
module_function

def patch!(schemas, options)
if schemas.empty?
::GraphQL::Schema.trace_with(::GraphQL::Tracing::DataDogTrace, **options)
else
schemas.each do |schema|
schema.trace_with(::GraphQL::Tracing::DataDogTrace, **options)
end
end
end
end
end
end
end
end
28 changes: 28 additions & 0 deletions lib/datadog/tracing/contrib/graphql/tracing_patcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

module Datadog
module Tracing
module Contrib
module GraphQL
# Provides instrumentation for `graphql` through the GraphQL's tracing
module TracingPatcher
module_function

def patch!(schemas, options)
if schemas.empty?
::GraphQL::Schema.tracer(::GraphQL::Tracing::DataDogTracing.new(**options))
else
schemas.each do |schema|
if schema.respond_to? :use
schema.use(::GraphQL::Tracing::DataDogTracing, **options)
else
Datadog.logger.warn("Unable to patch #{schema}: Please migrate to class-based schema.")
end
end
end
end
end
end
end
end
end
11 changes: 11 additions & 0 deletions sig/datadog/tracing/contrib/graphql/trace_patcher.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Datadog
module Tracing
module Contrib
module GraphQL
module TracePatcher
def self?.patch!: (::Array[untyped] schemas, ::Hash[Symbol, untyped] options) -> untyped
end
end
end
end
end
12 changes: 12 additions & 0 deletions sig/datadog/tracing/contrib/graphql/tracing_patcher.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Datadog
module Tracing
module Contrib
module GraphQL
module TracingPatcher

def self?.patch!: (::Array[untyped] schemas, ::Hash[Symbol, untyped] options) -> untyped
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,30 @@
end
end
end

describe 'with_deprecated_tracer' do
context 'when default' do
it do
settings = described_class.new

expect(settings.with_deprecated_tracer).to eq(false)
end
end

context 'when given `true`' do
it do
settings = described_class.new(with_deprecated_tracer: true)

expect(settings.with_deprecated_tracer).to eq(true)
end
end

context 'when given `false`' do
it do
settings = described_class.new(with_deprecated_tracer: false)

expect(settings.with_deprecated_tracer).to eq(false)
end
end
end
end
26 changes: 16 additions & 10 deletions spec/datadog/tracing/contrib/graphql/integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,19 @@
describe '.loaded?' do
subject(:loaded?) { described_class.loaded? }

context 'when neither GraphQL or GraphQL::Tracing::DataDogTracing are defined' do
context 'when GraphQL is not defined' do
before do
hide_const('GraphQL')
hide_const('GraphQL::Tracing::DataDogTracing')
end

it { is_expected.to be false }
end

context 'when only GraphQL is defined' do
context 'when GraphQL is defined' do
before do
stub_const('GraphQL', Class.new)
hide_const('GraphQL::Tracing::DataDogTracing')
end

it { is_expected.to be false }
end

context 'when GraphQL::Tracing::DataDogTracing is defined' do
before { stub_const('GraphQL::Tracing::DataDogTracing', Class.new) }

it { is_expected.to be true }
end
end
Expand Down Expand Up @@ -96,6 +88,20 @@
it { is_expected.to be(true) }
end

describe '.trace_supported?' do
subject(:trace_supported) { described_class.trace_supported? }

context 'with version `2.0.19`' do
include_context 'loaded gems', graphql: '2.0.19'
it { is_expected.to be true }
end

context 'with version `2.0.18`' do
include_context 'loaded gems', graphql: decrement_gem_version('2.0.19')
it { is_expected.to be false }
end
end

describe '#default_configuration' do
subject(:default_configuration) { integration.default_configuration }

Expand Down
Loading
Loading