graphql 1.13.12 → 1.13.13

Sign up to get free protection for your applications and to get access to all the features.
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