Skip to content

Commit

Permalink
GraphQL integration can now be reconfigured
Browse files Browse the repository at this point in the history
  • Loading branch information
marcotc committed Aug 21, 2024
1 parent b7b99b2 commit a9ff163
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 116 deletions.
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,6 @@ end
#
# TODO: Remove this once the issue is resolved: https://github.com/ffi/ffi/issues/1107
gem 'ffi', '~> 1.16.3', require: false


gem 'graphql', '2.2.10'
16 changes: 4 additions & 12 deletions lib/datadog/tracing/contrib/graphql/patcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,23 @@ def target_version

def patch
if configuration[:with_deprecated_tracer]
TracingPatcher.patch!(schemas, trace_options)
TracingPatcher.patch!(schemas)
elsif Integration.trace_supported?
if configuration[:with_unified_tracer]
UnifiedTracePatcher.patch!(schemas, trace_options)
UnifiedTracePatcher.patch!(schemas)
else
TracePatcher.patch!(schemas, trace_options)
TracePatcher.patch!(schemas)
end
else
Datadog.logger.warn(
"GraphQL version (#{target_version}) does not support GraphQL::Tracing::DataDogTrace"\
'or Datadog::Tracing::Contrib::GraphQL::UnifiedTrace.'\
'Falling back to GraphQL::Tracing::DataDogTracing.'
)
TracingPatcher.patch!(schemas, trace_options)
TracingPatcher.patch!(schemas)
end
end

def trace_options
{
service: configuration[:service_name],
analytics_enabled: Contrib::Analytics.enabled?(configuration[:analytics_enabled]),
analytics_sample_rate: configuration[:analytics_sample_rate]
}
end

def configuration
Datadog.configuration.tracing[:graphql]
end
Expand Down
6 changes: 3 additions & 3 deletions lib/datadog/tracing/contrib/graphql/trace_patcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ module GraphQL
module TracePatcher
module_function

def patch!(schemas, options)
def patch!(schemas)
if schemas.empty?
::GraphQL::Schema.trace_with(::GraphQL::Tracing::DataDogTrace, **options)
::GraphQL::Schema.trace_with(::GraphQL::Tracing::DataDogTrace)
else
schemas.each do |schema|
schema.trace_with(::GraphQL::Tracing::DataDogTrace, **options)
schema.trace_with(::GraphQL::Tracing::DataDogTrace)
end
end
end
Expand Down
6 changes: 3 additions & 3 deletions lib/datadog/tracing/contrib/graphql/tracing_patcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ module GraphQL
module TracingPatcher
module_function

def patch!(schemas, options)
def patch!(schemas)
if schemas.empty?
::GraphQL::Schema.tracer(::GraphQL::Tracing::DataDogTracing.new(**options))
::GraphQL::Schema.tracer(::GraphQL::Tracing::DataDogTracing.new)
else
schemas.each do |schema|
if schema.respond_to? :use
schema.use(::GraphQL::Tracing::DataDogTracing, **options)
schema.use(::GraphQL::Tracing::DataDogTracing)
else
Datadog.logger.warn("Unable to patch #{schema}: Please migrate to class-based schema.")
end
Expand Down
17 changes: 8 additions & 9 deletions lib/datadog/tracing/contrib/graphql/unified_trace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,7 @@ module GraphQL
# which is required to use features such as API Catalog.
# DEV-3.0: This tracer should be the default one in the next major version.
module UnifiedTrace
# @param analytics_enabled [Boolean] Deprecated
# @param analytics_sample_rate [Float] Deprecated
# @param service [String|nil] The service name to be set on the spans
def initialize(*args, analytics_enabled: false, analytics_sample_rate: 1.0, service: nil, **kwargs)
@analytics_enabled = analytics_enabled
@analytics_sample_rate = analytics_sample_rate

@service_name = service
def initialize(*args, **kwargs)
@has_prepare_span = respond_to?(:prepare_span)
super
end
Expand Down Expand Up @@ -139,7 +132,13 @@ def platform_resolve_type_key(type, *args, **kwargs)
private

def trace(callable, trace_key, resource, **kwargs)
Tracing.trace("graphql.#{trace_key}", resource: resource, service: @service_name, type: 'graphql') do |span|
config = Datadog.configuration.tracing[:graphql]

Tracing.trace("graphql.#{trace_key}", type: 'graphql', resource: resource, service: config[:service_name]) do |span|
if Contrib::Analytics.enabled?(config[:analytics_enabled])
Contrib::Analytics.set_sample_rate(span, config[:analytics_sample_rate])
end

yield(span) if block_given?

prepare_span(trace_key, kwargs, span) if @has_prepare_span
Expand Down
6 changes: 3 additions & 3 deletions lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ module GraphQL
module UnifiedTracePatcher
module_function

def patch!(schemas, options)
def patch!(schemas)
if schemas.empty?
::GraphQL::Schema.trace_with(UnifiedTrace, **options)
::GraphQL::Schema.trace_with(UnifiedTrace)
else
schemas.each do |schema|
schema.trace_with(UnifiedTrace, **options)
schema.trace_with(UnifiedTrace)
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/datadog/tracing/contrib/patcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def patch
# @param e [Exception]
def on_patch_error(e)
# Log the error
# Yes!
Datadog.logger.error("Failed to apply #{patch_name} patch. Cause: #{e} Location: #{Array(e.backtrace).first}")

@patch_error_result = {
Expand Down
72 changes: 14 additions & 58 deletions spec/datadog/tracing/contrib/graphql/patcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@
RSpec.describe Datadog::Tracing::Contrib::GraphQL::Patcher do
around do |example|
remove_patch!(:graphql)
Datadog.configuration.reset!
Datadog.configuration.tracing[:graphql].reset!

without_warnings do
example.run
end

remove_patch!(:graphql)
Datadog.configuration.reset!
Datadog.configuration.tracing[:graphql].reset!
end

Expand All @@ -26,10 +24,7 @@
context 'with default configuration' do
it 'patches GraphQL' do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(true)
expect(Datadog::Tracing::Contrib::GraphQL::TracePatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracePatcher).to receive(:patch!).with( [] )

Datadog.configure do |c|
c.tracing.instrument :graphql
Expand All @@ -40,10 +35,7 @@
context 'with with_deprecated_tracer enabled' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(true)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with([])

Datadog.configure do |c|
c.tracing.instrument :graphql, with_deprecated_tracer: true
Expand All @@ -54,10 +46,7 @@
context 'with with_deprecated_tracer disabled' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(true)
expect(Datadog::Tracing::Contrib::GraphQL::TracePatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracePatcher).to receive(:patch!).with( [] )

Datadog.configure do |c|
c.tracing.instrument :graphql, with_deprecated_tracer: false
Expand All @@ -68,10 +57,7 @@
context 'with with_unified_tracer enabled' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(true)
expect(Datadog::Tracing::Contrib::GraphQL::UnifiedTracePatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::UnifiedTracePatcher).to receive(:patch!).with( [] )

Datadog.configure do |c|
c.tracing.instrument :graphql, with_unified_tracer: true
Expand All @@ -82,10 +68,7 @@
context 'with with_unified_tracer disabled' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(true)
expect(Datadog::Tracing::Contrib::GraphQL::TracePatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracePatcher).to receive(:patch!).with( [] )

Datadog.configure do |c|
c.tracing.instrument :graphql, with_unified_tracer: false
Expand All @@ -96,10 +79,7 @@
context 'with with_unified_tracer enabled and with_deprecated_tracer enabled' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(true)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with( [] )

Datadog.configure do |c|
c.tracing.instrument :graphql, with_unified_tracer: true, with_deprecated_tracer: true
Expand All @@ -110,10 +90,7 @@
context 'with given schema' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(true)
expect(Datadog::Tracing::Contrib::GraphQL::TracePatcher).to receive(:patch!).with(
[TestGraphQLSchema],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracePatcher).to receive(:patch!).with( [TestGraphQLSchema] )

Datadog.configure do |c|
c.tracing.instrument :graphql, schemas: [TestGraphQLSchema]
Expand All @@ -126,10 +103,7 @@
context 'with default configuration' do
it 'patches GraphQL' do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(false)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with( [] )
expect_any_instance_of(Datadog::Core::Logger).to receive(:warn)
.with(/Falling back to GraphQL::Tracing::DataDogTracing/)

Expand All @@ -142,10 +116,7 @@
context 'with with_deprecated_tracer enabled' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(false)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with( [])
expect_any_instance_of(Datadog::Core::Logger).not_to receive(:warn)

Datadog.configure do |c|
Expand All @@ -157,10 +128,7 @@
context 'with with_deprecated_tracer disabled' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(false)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with([])
expect_any_instance_of(Datadog::Core::Logger).to receive(:warn)
.with(/Falling back to GraphQL::Tracing::DataDogTracing/)

Expand All @@ -173,10 +141,7 @@
context 'with with_unified_tracer enabled' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(false)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with([] )
expect_any_instance_of(Datadog::Core::Logger).to receive(:warn)
.with(/Falling back to GraphQL::Tracing::DataDogTracing/)

Expand All @@ -189,10 +154,7 @@
context 'with with_unified_tracer disabled' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(false)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with( [] )
expect_any_instance_of(Datadog::Core::Logger).to receive(:warn)
.with(/Falling back to GraphQL::Tracing::DataDogTracing/)

Expand All @@ -205,10 +167,7 @@
context 'with with_unified_tracer enabled and with_deprecated_tracer enabled' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(false)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with(
[],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with( [] )

Datadog.configure do |c|
c.tracing.instrument :graphql, with_unified_tracer: true, with_deprecated_tracer: true
Expand All @@ -219,10 +178,7 @@
context 'with given schema' do
it do
allow(Datadog::Tracing::Contrib::GraphQL::Integration).to receive(:trace_supported?).and_return(false)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with(
[TestGraphQLSchema],
hash_including(:analytics_enabled, :analytics_sample_rate, :service)
)
expect(Datadog::Tracing::Contrib::GraphQL::TracingPatcher).to receive(:patch!).with( [TestGraphQLSchema] )
expect_any_instance_of(Datadog::Core::Logger).to receive(:warn)
.with(/Falling back to GraphQL::Tracing::DataDogTracing/)

Expand Down
24 changes: 3 additions & 21 deletions spec/datadog/tracing/contrib/graphql/test_schema_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ class TestGraphQLSchema < ::GraphQL::Schema
end

RSpec.shared_examples 'graphql default instrumentation' do
around do |example|
Datadog::GraphQLTestHelpers.reset_schema_cache!(::GraphQL::Schema)
Datadog::GraphQLTestHelpers.reset_schema_cache!(TestGraphQLSchema)

example.run

Datadog::GraphQLTestHelpers.reset_schema_cache!(::GraphQL::Schema)
Datadog::GraphQLTestHelpers.reset_schema_cache!(TestGraphQLSchema)
end

describe 'query trace' do
subject(:result) { TestGraphQLSchema.execute('{ user(id: 1) { name } }') }

Expand Down Expand Up @@ -71,16 +61,6 @@ class TestGraphQLSchema < ::GraphQL::Schema
end

RSpec.shared_examples 'graphql instrumentation with unified naming convention trace' do
around do |example|
Datadog::GraphQLTestHelpers.reset_schema_cache!(::GraphQL::Schema)
Datadog::GraphQLTestHelpers.reset_schema_cache!(TestGraphQLSchema)

example.run

Datadog::GraphQLTestHelpers.reset_schema_cache!(::GraphQL::Schema)
Datadog::GraphQLTestHelpers.reset_schema_cache!(TestGraphQLSchema)
end

describe 'query trace' do
subject(:result) do
TestGraphQLSchema.execute(query: 'query Users($var: ID!){ user(id: $var) { name } }', variables: { var: 1 })
Expand All @@ -104,6 +84,8 @@ class TestGraphQLSchema < ::GraphQL::Schema
['graphql.validate', 'Users']
].compact

let(:service) { defined?(super) ? super() : tracer.default_service }

# graphql.source for execute_multiplex is not required in the span attributes specification
spans_with_source = ['graphql.parse', 'graphql.validate', 'graphql.execute']

Expand All @@ -117,7 +99,7 @@ class TestGraphQLSchema < ::GraphQL::Schema

expect(span.name).to eq(name)
expect(span.resource).to eq(resource)
expect(span.service).to eq(tracer.default_service)
expect(span.service).to eq(service)
expect(span.type).to eq('graphql')

if spans_with_source.include?(name)
Expand Down
8 changes: 6 additions & 2 deletions spec/datadog/tracing/contrib/graphql/trace_patcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@
context 'with empty schema configuration' do
it_behaves_like 'graphql default instrumentation' do
before do
described_class.patch!([], {})
Datadog.configure do |c|
c.tracing.instrument :graphql
end
end
end
end

context 'with specified schemas configuration' do
it_behaves_like 'graphql default instrumentation' do
before do
described_class.patch!([TestGraphQLSchema], {})
Datadog.configure do |c|
c.tracing.instrument :graphql, schemas: [TestGraphQLSchema]
end
end
end
end
Expand Down
Loading

0 comments on commit a9ff163

Please sign in to comment.