graphql 1.13.12 → 1.13.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90fcd1d4c840be80d47ed66bad6c4cdd4c16a4981b249b57e7e126a3ff5d5d6d
4
- data.tar.gz: 6d9f87843cd626dff3a9f46158fce7f1be22c3f1aa4131c8b2390b82f93edb52
3
+ metadata.gz: 2a586eb14f15e3215e732634aa6edd2204127fe1dbf356c7ff45a0b96b794832
4
+ data.tar.gz: 69acba1a940532a8010160fd0bbd4ab4d2a22d6985f4057d030815599f13f5fb
5
5
  SHA512:
6
- metadata.gz: 355972194b55f12d4bc43d610249c94ce6d73c574f12688863b01bf60ad4f2a9ad093ee19c76403f4b84371583ea5c236a3d7cfda72e3564a222dd9f12c1d0ea
7
- data.tar.gz: 5ebd795ac0884a46f413e4ede96165d3b2be2489266c36fbc06d90f0d940e69a2afa86c86417757716dc47ddc9c3bdbbe475c7f1547951c5cbe843a0ed7d45e5
6
+ metadata.gz: db2ab29ba5535a1f60ee549542bb528323af2cb8789cc0c3e05586bc20ebb02b11b67a1d3ee7224180f437ee07e52d59f76974e5d5a476a6add5e0142ea7557e
7
+ data.tar.gz: 6c5e5c0ada2c8a293c86e338ede7bf22dee1a699b0ac8aa866993ce849de95e0683a576e2459eb199d45d30b17d745654e4ce73a95bf77704d2cd5af0a31d50f
@@ -17,15 +17,21 @@ module GraphQL
17
17
  def platform_trace(platform_key, key, data)
18
18
  tracer.trace(platform_key, service: service_name) do |span|
19
19
  span.span_type = 'custom'
20
+ if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
21
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
22
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, key)
23
+ end
20
24
 
21
25
  if key == 'execute_multiplex'
22
26
  operations = data[:multiplex].queries.map(&:selected_operation_name).join(', ')
23
- span.resource = if operations.empty?
27
+
28
+ resource = if operations.empty?
24
29
  first_query = data[:multiplex].queries.first
25
30
  fallback_transaction_name(first_query && first_query.context)
26
31
  else
27
32
  operations
28
33
  end
34
+ span.resource = resource if resource
29
35
 
30
36
  # For top span of query, set the analytics sample rate tag, if available.
31
37
  if analytics_enabled?
@@ -39,6 +45,8 @@ module GraphQL
39
45
  span.set_tag(:query_string, data[:query].query_string)
40
46
  end
41
47
 
48
+ prepare_span(key, data, span)
49
+
42
50
  yield
43
51
  end
44
52
  end
@@ -47,6 +55,13 @@ module GraphQL
47
55
  options.fetch(:service, 'ruby-graphql')
48
56
  end
49
57
 
58
+ # Implement this method in a subclass to apply custom tags to datadog spans
59
+ # @param key [String] The event being traced
60
+ # @param data [Hash] The runtime data for this event (@see GraphQL::Tracing for keys for each event)
61
+ # @param span [Datadog::Tracing::SpanOperation] The datadog span for this event
62
+ def prepare_span(key, data, span)
63
+ end
64
+
50
65
  def tracer
51
66
  options.fetch(:tracer, Datadog.tracer)
52
67
  end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module Tracing
5
+ class OpenTelemetryTracing < PlatformTracing
6
+ self.platform_keys = {
7
+ 'lex' => 'graphql.lex',
8
+ 'parse' => 'graphql.parse',
9
+ 'validate' => 'graphql.validate',
10
+ 'analyze_query' => 'graphql.analyze_query',
11
+ 'analyze_multiplex' => 'graphql.analyze_multiplex',
12
+ 'execute_query' => 'graphql.execute_query',
13
+ 'execute_query_lazy' => 'graphql.execute_query_lazy',
14
+ 'execute_multiplex' => 'graphql.execute_multiplex'
15
+ }
16
+
17
+ def platform_trace(platform_key, key, data)
18
+ return yield if platform_key.nil?
19
+
20
+ tracer.in_span(platform_key, attributes: attributes_for(key, data)) do |span, _context|
21
+ yield.tap do |response|
22
+ errors = response[:errors]&.compact&.map { |e| e.to_h }&.to_json if key == 'validate'
23
+ unless errors.nil?
24
+ span.add_event(
25
+ 'graphql.validation.error',
26
+ attributes: {
27
+ 'message' => errors
28
+ }
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ def platform_field_key(type, field)
36
+ "#{type.graphql_name}.#{field.graphql_name}"
37
+ end
38
+
39
+ def platform_authorized_key(type)
40
+ "#{type.graphql_name}.authorized"
41
+ end
42
+
43
+ def platform_resolve_type_key(type)
44
+ "#{type.graphql_name}.resolve_type"
45
+ end
46
+
47
+ private
48
+
49
+ def tracer
50
+ OpenTelemetry::Instrumentation::GraphQL::Instrumentation.instance.tracer
51
+ end
52
+
53
+ def config
54
+ OpenTelemetry::Instrumentation::GraphQL::Instrumentation.instance.config
55
+ end
56
+
57
+ def platform_key_enabled?(ctx, key)
58
+ return false unless config[key]
59
+
60
+ ns = ctx.namespace(:opentelemetry)
61
+ return true if ns.empty? # restores original behavior so that keys are returned if tracing is not set in context.
62
+ return false unless ns.key?(key) && ns[key]
63
+
64
+ return true
65
+ end
66
+
67
+ def attributes_for(key, data)
68
+ attributes = {}
69
+ case key
70
+ when 'execute_query'
71
+ attributes['selected_operation_name'] = data[:query].selected_operation_name if data[:query].selected_operation_name
72
+ attributes['selected_operation_type'] = data[:query].selected_operation.operation_type
73
+ attributes['query_string'] = data[:query].query_string
74
+ end
75
+ attributes
76
+ end
77
+
78
+ def cached_platform_key(ctx, key, trace_phase)
79
+ cache = ctx.namespace(self.class)[:platform_key_cache] ||= {}
80
+
81
+ cache.fetch(key) do
82
+ cache[key] = if trace_phase == :field
83
+ return unless platform_key_enabled?(ctx, :enable_platform_field)
84
+
85
+ yield
86
+ elsif trace_phase == :authorized
87
+ return unless platform_key_enabled?(ctx, :enable_platform_authorized)
88
+
89
+ yield
90
+ elsif trace_phase == :resolve_type
91
+ return unless platform_key_enabled?(ctx, :enable_platform_resolve_type)
92
+
93
+ yield
94
+ else
95
+ raise "Unknown trace phase"
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -10,6 +10,10 @@ module GraphQL
10
10
  class PlatformTracing
11
11
  class << self
12
12
  attr_accessor :platform_keys
13
+
14
+ def inherited(child_class)
15
+ child_class.platform_keys = self.platform_keys
16
+ end
13
17
  end
14
18
 
15
19
  def initialize(options = {})
@@ -41,7 +45,7 @@ module GraphQL
41
45
 
42
46
  platform_key = if trace_field
43
47
  context = data.fetch(:query).context
44
- cached_platform_key(context, field) { platform_field_key(data[:owner], field) }
48
+ cached_platform_key(context, field, :field) { platform_field_key(data[:owner], field) }
45
49
  else
46
50
  nil
47
51
  end
@@ -57,14 +61,14 @@ module GraphQL
57
61
  when "authorized", "authorized_lazy"
58
62
  type = data.fetch(:type)
59
63
  context = data.fetch(:context)
60
- platform_key = cached_platform_key(context, type) { platform_authorized_key(type) }
64
+ platform_key = cached_platform_key(context, type, :authorized) { platform_authorized_key(type) }
61
65
  platform_trace(platform_key, key, data) do
62
66
  yield
63
67
  end
64
68
  when "resolve_type", "resolve_type_lazy"
65
69
  type = data.fetch(:type)
66
70
  context = data.fetch(:context)
67
- platform_key = cached_platform_key(context, type) { platform_resolve_type_key(type) }
71
+ platform_key = cached_platform_key(context, type, :resolve_type) { platform_resolve_type_key(type) }
68
72
  platform_trace(platform_key, key, data) do
69
73
  yield
70
74
  end
@@ -135,7 +139,7 @@ module GraphQL
135
139
  # If the key isn't present, the given block is called and the result is cached for `key`.
136
140
  #
137
141
  # @return [String]
138
- def cached_platform_key(ctx, key)
142
+ def cached_platform_key(ctx, key, trace_phase)
139
143
  cache = ctx.namespace(self.class)[:platform_key_cache] ||= {}
140
144
  cache.fetch(key) { cache[key] = yield }
141
145
  end
@@ -9,6 +9,7 @@ require "graphql/tracing/scout_tracing"
9
9
  require "graphql/tracing/skylight_tracing"
10
10
  require "graphql/tracing/statsd_tracing"
11
11
  require "graphql/tracing/prometheus_tracing"
12
+ require "graphql/tracing/opentelemetry_tracing"
12
13
 
13
14
  if defined?(PrometheusExporter::Server)
14
15
  require "graphql/tracing/prometheus_tracing/graphql_collector"
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.13.12"
3
+ VERSION = "1.13.13"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.12
4
+ version: 1.13.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-14 00:00:00.000000000 Z
11
+ date: 2022-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -659,6 +659,7 @@ files:
659
659
  - lib/graphql/tracing/data_dog_tracing.rb
660
660
  - lib/graphql/tracing/new_relic_tracing.rb
661
661
  - lib/graphql/tracing/notifications_tracing.rb
662
+ - lib/graphql/tracing/opentelemetry_tracing.rb
662
663
  - lib/graphql/tracing/platform_tracing.rb
663
664
  - lib/graphql/tracing/prometheus_tracing.rb
664
665
  - lib/graphql/tracing/prometheus_tracing/graphql_collector.rb