graphql 2.0.20 → 2.0.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/backtrace/trace.rb +96 -0
  3. data/lib/graphql/backtrace.rb +6 -1
  4. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  5. data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -3
  6. data/lib/graphql/execution/interpreter/runtime.rb +200 -161
  7. data/lib/graphql/execution/interpreter.rb +1 -1
  8. data/lib/graphql/filter.rb +7 -2
  9. data/lib/graphql/language/document_from_schema_definition.rb +25 -9
  10. data/lib/graphql/language/nodes.rb +2 -2
  11. data/lib/graphql/language/parser.rb +475 -458
  12. data/lib/graphql/language/parser.y +5 -1
  13. data/lib/graphql/pagination/connection.rb +5 -5
  14. data/lib/graphql/query/context.rb +13 -12
  15. data/lib/graphql/query/null_context.rb +1 -1
  16. data/lib/graphql/query.rb +9 -5
  17. data/lib/graphql/schema/argument.rb +7 -9
  18. data/lib/graphql/schema/build_from_definition.rb +15 -3
  19. data/lib/graphql/schema/enum_value.rb +2 -5
  20. data/lib/graphql/schema/field.rb +14 -13
  21. data/lib/graphql/schema/field_extension.rb +1 -4
  22. data/lib/graphql/schema/find_inherited_value.rb +2 -7
  23. data/lib/graphql/schema/member/has_arguments.rb +1 -1
  24. data/lib/graphql/schema/member/has_directives.rb +4 -6
  25. data/lib/graphql/schema/member/has_fields.rb +80 -36
  26. data/lib/graphql/schema/member/has_validators.rb +2 -2
  27. data/lib/graphql/schema/resolver.rb +4 -4
  28. data/lib/graphql/schema/validator.rb +1 -1
  29. data/lib/graphql/schema/warden.rb +3 -1
  30. data/lib/graphql/schema.rb +40 -11
  31. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  32. data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
  33. data/lib/graphql/tracing/appsignal_trace.rb +6 -0
  34. data/lib/graphql/tracing/legacy_trace.rb +65 -0
  35. data/lib/graphql/tracing/notifications_trace.rb +2 -1
  36. data/lib/graphql/tracing/platform_trace.rb +21 -19
  37. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
  38. data/lib/graphql/tracing/trace.rb +75 -0
  39. data/lib/graphql/tracing.rb +3 -123
  40. data/lib/graphql/version.rb +1 -1
  41. data/lib/graphql.rb +4 -0
  42. metadata +5 -2
@@ -145,18 +145,41 @@ module GraphQL
145
145
 
146
146
  def trace_class(new_class = nil)
147
147
  if new_class
148
- @trace_class = new_class
149
- elsif !defined?(@trace_class)
150
- parent_trace_class = if superclass.respond_to?(:trace_class)
151
- superclass.trace_class
148
+ trace_mode(:default, new_class)
149
+ backtrace_class = Class.new(new_class)
150
+ backtrace_class.include(GraphQL::Backtrace::Trace)
151
+ trace_mode(:default_backtrace, backtrace_class)
152
+ end
153
+ trace_class_for(:default)
154
+ end
155
+
156
+ # @return [Class] Return the trace class to use for this mode, looking one up on the superclass if this Schema doesn't have one defined.
157
+ def trace_class_for(mode)
158
+ @trace_modes ||= {}
159
+ @trace_modes[mode] ||= begin
160
+ base_class = if superclass.respond_to?(:trace_class_for)
161
+ superclass.trace_class_for(mode)
162
+ elsif mode == :default_backtrace
163
+ GraphQL::Backtrace::DefaultBacktraceTrace
152
164
  else
153
165
  GraphQL::Tracing::Trace
154
166
  end
155
- @trace_class = Class.new(parent_trace_class)
167
+ Class.new(base_class)
156
168
  end
157
- @trace_class
158
169
  end
159
170
 
171
+ # Configure `trace_class` to be used whenever `context: { trace_mode: mode_name }` is requested.
172
+ # `:default` is used when no `trace_mode: ...` is requested.
173
+ # @param mode_name [Symbol]
174
+ # @param trace_class [Class] subclass of GraphQL::Tracing::Trace
175
+ # @return void
176
+ def trace_mode(mode_name, trace_class)
177
+ @trace_modes ||= {}
178
+ @trace_modes[mode_name] = trace_class
179
+ nil
180
+ end
181
+
182
+
160
183
  # Returns the JSON response of {Introspection::INTROSPECTION_QUERY}.
161
184
  # @see {#as_json}
162
185
  # @return [String]
@@ -221,7 +244,7 @@ module GraphQL
221
244
  end
222
245
 
223
246
  def default_filter
224
- GraphQL::Filter.new(except: default_mask)
247
+ GraphQL::Filter.new(except: default_mask, silence_deprecation_warning: true)
225
248
  end
226
249
 
227
250
  def default_mask(new_mask = nil)
@@ -936,10 +959,10 @@ module GraphQL
936
959
  end
937
960
 
938
961
  def tracer(new_tracer)
939
- if defined?(@trace_class) && !(@trace_class < GraphQL::Tracing::LegacyTrace)
962
+ if defined?(@trace_modes) && !(trace_class_for(:default) < GraphQL::Tracing::LegacyTrace)
940
963
  raise ArgumentError, "Can't add tracer after configuring a `trace_class`, use GraphQL::Tracing::LegacyTrace to merge legacy tracers into a trace class instead."
941
- elsif !defined?(@trace_class)
942
- @trace_class = Class.new(GraphQL::Tracing::LegacyTrace)
964
+ else
965
+ trace_mode(:default, Class.new(GraphQL::Tracing::LegacyTrace))
943
966
  end
944
967
 
945
968
  own_tracers << new_tracer
@@ -968,7 +991,13 @@ module GraphQL
968
991
  if defined?(@trace_options)
969
992
  options = trace_options.merge(options)
970
993
  end
971
- trace_class.new(**options)
994
+ trace_mode = if (target = options[:query] || options[:multiplex]) && target.context[:backtrace]
995
+ :default_backtrace
996
+ else
997
+ :default
998
+ end
999
+ trace = trace_class_for(trace_mode).new(**options)
1000
+ trace
972
1001
  end
973
1002
 
974
1003
  def query_analyzer(new_analyzer)
@@ -26,11 +26,19 @@ module GraphQL
26
26
  msg = if resolved_type.nil?
27
27
  nil
28
28
  elsif resolved_type.kind.scalar? && ast_node.selections.any?
29
- if ast_node.selections.first.is_a?(GraphQL::Language::Nodes::InlineFragment)
30
- "Selections can't be made on scalars (%{node_name} returns #{resolved_type.graphql_name} but has inline fragments [#{ast_node.selections.map(&:type).map(&:name).join(", ")}])"
31
- else
32
- "Selections can't be made on scalars (%{node_name} returns #{resolved_type.graphql_name} but has selections [#{ast_node.selections.map(&:name).join(", ")}])"
29
+ selection_strs = ast_node.selections.map do |n|
30
+ case n
31
+ when GraphQL::Language::Nodes::InlineFragment
32
+ "\"... on #{n.type.name} { ... }\""
33
+ when GraphQL::Language::Nodes::Field
34
+ "\"#{n.name}\""
35
+ when GraphQL::Language::Nodes::FragmentSpread
36
+ "\"#{n.name}\""
37
+ else
38
+ raise "Invariant: unexpected selection node: #{n}"
39
+ end
33
40
  end
41
+ "Selections can't be made on scalars (%{node_name} returns #{resolved_type.graphql_name} but has selections [#{selection_strs.join(", ")}])"
34
42
  elsif resolved_type.kind.fields? && ast_node.selections.empty?
35
43
  "Field must have selections (%{node_name} returns #{resolved_type.graphql_name} but has no selections. Did you mean '#{ast_node.name} { ... }'?)"
36
44
  else
@@ -9,7 +9,7 @@ module GraphQL
9
9
  # without ambiguity.
10
10
  #
11
11
  # Original Algorithm: https://github.com/graphql/graphql-js/blob/master/src/validation/rules/OverlappingFieldsCanBeMerged.js
12
- NO_ARGS = {}.freeze
12
+ NO_ARGS = GraphQL::EmptyObjects::EMPTY_HASH
13
13
 
14
14
  Field = Struct.new(:node, :definition, :owner_type, :parents)
15
15
  FragmentSpread = Struct.new(:name, :parents)
@@ -323,7 +323,7 @@ module GraphQL
323
323
  end
324
324
  end
325
325
 
326
- NO_SELECTIONS = [{}.freeze, [].freeze].freeze
326
+ NO_SELECTIONS = [GraphQL::EmptyObjects::EMPTY_HASH, GraphQL::EmptyObjects::EMPTY_ARRAY].freeze
327
327
 
328
328
  def fields_and_fragments_from_selection(node, owner_type:, parents:)
329
329
  if node.selections.empty?
@@ -55,6 +55,12 @@ module GraphQL
55
55
  end
56
56
  end
57
57
 
58
+ def platform_resolve_type(platform_key)
59
+ Appsignal.instrument(platform_key) do
60
+ yield
61
+ end
62
+ end
63
+
58
64
  def platform_field_key(field)
59
65
  "#{field.owner.graphql_name}.#{field.graphql_name}.graphql"
60
66
  end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module Tracing
4
+ # This trace class calls legacy-style tracer with payload hashes.
5
+ # New-style `trace_with` modules significantly reduce the overhead of tracing,
6
+ # but that advantage is lost when legacy-style tracers are also used (since the payload hashes are still constructed).
7
+ class LegacyTrace < Trace
8
+ def lex(query_string:)
9
+ (@multiplex || @query).trace("lex", { query_string: query_string }) { super }
10
+ end
11
+
12
+ def parse(query_string:)
13
+ (@multiplex || @query).trace("parse", { query_string: query_string }) { super }
14
+ end
15
+
16
+ def validate(query:, validate:)
17
+ query.trace("validate", { validate: validate, query: query }) { super }
18
+ end
19
+
20
+ def analyze_multiplex(multiplex:)
21
+ multiplex.trace("analyze_multiplex", { multiplex: multiplex }) { super }
22
+ end
23
+
24
+ def analyze_query(query:)
25
+ query.trace("analyze_query", { query: query }) { super }
26
+ end
27
+
28
+ def execute_multiplex(multiplex:)
29
+ multiplex.trace("execute_multiplex", { multiplex: multiplex }) { super }
30
+ end
31
+
32
+ def execute_query(query:)
33
+ query.trace("execute_query", { query: query }) { super }
34
+ end
35
+
36
+ def execute_query_lazy(query:, multiplex:)
37
+ multiplex.trace("execute_query_lazy", { multiplex: multiplex, query: query }) { super }
38
+ end
39
+
40
+ def execute_field(field:, query:, ast_node:, arguments:, object:)
41
+ query.trace("execute_field", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }) { super }
42
+ end
43
+
44
+ def execute_field_lazy(field:, query:, ast_node:, arguments:, object:)
45
+ query.trace("execute_field_lazy", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }) { super }
46
+ end
47
+
48
+ def authorized(query:, type:, object:)
49
+ query.trace("authorized", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
50
+ end
51
+
52
+ def authorized_lazy(query:, type:, object:)
53
+ query.trace("authorized_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
54
+ end
55
+
56
+ def resolve_type(query:, type:, object:)
57
+ query.trace("resolve_type", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
58
+ end
59
+
60
+ def resolve_type_lazy(query:, type:, object:)
61
+ query.trace("resolve_type_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
62
+ end
63
+ end
64
+ end
65
+ end
@@ -6,7 +6,6 @@ module GraphQL
6
6
  # ActiveSupport::Notifications or Dry::Monitor::Notifications)
7
7
  # with a `graphql` suffix.
8
8
  module NotificationsTrace
9
- include PlatformTrace
10
9
  # Initialize a new NotificationsTracing instance
11
10
  #
12
11
  # @param engine [#instrument(key, metadata, block)] The notifications engine to use
@@ -36,6 +35,8 @@ module GraphQL
36
35
  end
37
36
  RUBY
38
37
  end
38
+
39
+ include PlatformTrace
39
40
  end
40
41
  end
41
42
  end
@@ -29,28 +29,30 @@ module GraphQL
29
29
  child_class.instance_method(:platform_execute_field).arity != 1
30
30
 
31
31
  [:execute_field, :execute_field_lazy].each do |field_trace_method|
32
- child_class.module_eval <<-RUBY, __FILE__, __LINE__
33
- def #{field_trace_method}(query:, field:, ast_node:, arguments:, object:)
34
- return_type = field.type.unwrap
35
- trace_field = if return_type.kind.scalar? || return_type.kind.enum?
36
- (field.trace.nil? && @trace_scalars) || field.trace
37
- else
38
- true
39
- end
40
- platform_key = if trace_field
41
- @platform_field_key_cache[field]
42
- else
43
- nil
44
- end
45
- if platform_key && trace_field
46
- platform_#{field_trace_method}(platform_key#{pass_data_to_execute_field ? ", { query: query, field: field, ast_node: ast_node, arguments: arguments, object: object }" : ""}) do
32
+ if !child_class.method_defined?(field_trace_method)
33
+ child_class.module_eval <<-RUBY, __FILE__, __LINE__
34
+ def #{field_trace_method}(query:, field:, ast_node:, arguments:, object:)
35
+ return_type = field.type.unwrap
36
+ trace_field = if return_type.kind.scalar? || return_type.kind.enum?
37
+ (field.trace.nil? && @trace_scalars) || field.trace
38
+ else
39
+ true
40
+ end
41
+ platform_key = if trace_field
42
+ @platform_field_key_cache[field]
43
+ else
44
+ nil
45
+ end
46
+ if platform_key && trace_field
47
+ platform_#{field_trace_method}(platform_key#{pass_data_to_execute_field ? ", { query: query, field: field, ast_node: ast_node, arguments: arguments, object: object }" : ""}) do
48
+ super
49
+ end
50
+ else
47
51
  super
48
52
  end
49
- else
50
- super
51
53
  end
52
- end
53
- RUBY
54
+ RUBY
55
+ end
54
56
  end
55
57
 
56
58
 
@@ -5,7 +5,7 @@ module GraphQL
5
5
  class PrometheusTracing < PlatformTracing
6
6
  class GraphQLCollector < ::PrometheusExporter::Server::TypeCollector
7
7
  def initialize
8
- @graphql_gauge = PrometheusExporter::Metric::Summary.new(
8
+ @graphql_gauge = PrometheusExporter::Metric::Base.default_aggregation.new(
9
9
  'graphql_duration_seconds',
10
10
  'Time spent in GraphQL operations, in seconds'
11
11
  )
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module Tracing
4
+ # This is the base class for a `trace` instance whose methods are called during query execution.
5
+ # "Trace modes" are subclasses of this with custom tracing modules mixed in.
6
+ #
7
+ # A trace module may implement any of the methods on `Trace`, being sure to call `super`
8
+ # to continue any tracing hooks and call the actual runtime behavior. See {GraphQL::Backtrace::Trace} for example.
9
+ #
10
+ class Trace
11
+ # @param multiplex [GraphQL::Execution::Multiplex, nil]
12
+ # @param query [GraphQL::Query, nil]
13
+ def initialize(multiplex: nil, query: nil, **_options)
14
+ @multiplex = multiplex
15
+ @query = query
16
+ end
17
+
18
+ def lex(query_string:)
19
+ yield
20
+ end
21
+
22
+ def parse(query_string:)
23
+ yield
24
+ end
25
+
26
+ def validate(query:, validate:)
27
+ yield
28
+ end
29
+
30
+ def analyze_multiplex(multiplex:)
31
+ yield
32
+ end
33
+
34
+ def analyze_query(query:)
35
+ yield
36
+ end
37
+
38
+ def execute_multiplex(multiplex:)
39
+ yield
40
+ end
41
+
42
+ def execute_query(query:)
43
+ yield
44
+ end
45
+
46
+ def execute_query_lazy(query:, multiplex:)
47
+ yield
48
+ end
49
+
50
+ def execute_field(field:, query:, ast_node:, arguments:, object:)
51
+ yield
52
+ end
53
+
54
+ def execute_field_lazy(field:, query:, ast_node:, arguments:, object:)
55
+ yield
56
+ end
57
+
58
+ def authorized(query:, type:, object:)
59
+ yield
60
+ end
61
+
62
+ def authorized_lazy(query:, type:, object:)
63
+ yield
64
+ end
65
+
66
+ def resolve_type(query:, type:, object:)
67
+ yield
68
+ end
69
+
70
+ def resolve_type_lazy(query:, type:, object:)
71
+ yield
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,4 +1,7 @@
1
1
  # frozen_string_literal: true
2
+ require "graphql/tracing/trace"
3
+ require "graphql/tracing/legacy_trace"
4
+
2
5
  # Legacy tracing:
3
6
  require "graphql/tracing/active_support_notifications_tracing"
4
7
  require "graphql/tracing/platform_tracing"
@@ -26,131 +29,8 @@ end
26
29
 
27
30
  module GraphQL
28
31
  module Tracing
29
- class Trace
30
- # @param multiplex [GraphQL::Execution::Multiplex, nil]
31
- # @param query [GraphQL::Query, nil]
32
- def initialize(multiplex: nil, query: nil, **_options)
33
- @multiplex = multiplex
34
- @query = query
35
- end
36
-
37
- def lex(query_string:)
38
- yield
39
- end
40
-
41
- def parse(query_string:)
42
- yield
43
- end
44
-
45
- def validate(query:, validate:)
46
- yield
47
- end
48
-
49
- def analyze_multiplex(multiplex:)
50
- yield
51
- end
52
-
53
- def analyze_query(query:)
54
- yield
55
- end
56
-
57
- def execute_multiplex(multiplex:)
58
- yield
59
- end
60
-
61
- def execute_query(query:)
62
- yield
63
- end
64
-
65
- def execute_query_lazy(query:, multiplex:)
66
- yield
67
- end
68
-
69
- def execute_field(field:, query:, ast_node:, arguments:, object:)
70
- yield
71
- end
72
-
73
- def execute_field_lazy(field:, query:, ast_node:, arguments:, object:)
74
- yield
75
- end
76
-
77
- def authorized(query:, type:, object:)
78
- yield
79
- end
80
-
81
- def authorized_lazy(query:, type:, object:)
82
- yield
83
- end
84
-
85
- def resolve_type(query:, type:, object:)
86
- yield
87
- end
88
-
89
- def resolve_type_lazy(query:, type:, object:)
90
- yield
91
- end
92
- end
93
-
94
32
  NullTrace = Trace.new
95
33
 
96
- class LegacyTrace < Trace
97
- def lex(query_string:, &block)
98
- (@multiplex || @query).trace("lex", { query_string: query_string }, &block)
99
- end
100
-
101
- def parse(query_string:, &block)
102
- (@multiplex || @query).trace("parse", { query_string: query_string }, &block)
103
- end
104
-
105
- def validate(query:, validate:, &block)
106
- query.trace("validate", { validate: validate, query: query }, &block)
107
- end
108
-
109
- def analyze_multiplex(multiplex:, &block)
110
- multiplex.trace("analyze_multiplex", { multiplex: multiplex }, &block)
111
- end
112
-
113
- def analyze_query(query:, &block)
114
- query.trace("analyze_query", { query: query }, &block)
115
- end
116
-
117
- def execute_multiplex(multiplex:, &block)
118
- multiplex.trace("execute_multiplex", { multiplex: multiplex }, &block)
119
- end
120
-
121
- def execute_query(query:, &block)
122
- query.trace("execute_query", { query: query }, &block)
123
- end
124
-
125
- def execute_query_lazy(query:, multiplex:, &block)
126
- multiplex.trace("execute_query_lazy", { multiplex: multiplex, query: query }, &block)
127
- end
128
-
129
- def execute_field(field:, query:, ast_node:, arguments:, object:, &block)
130
- query.trace("execute_field", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }, &block)
131
- end
132
-
133
- def execute_field_lazy(field:, query:, ast_node:, arguments:, object:, &block)
134
- query.trace("execute_field_lazy", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }, &block)
135
- end
136
-
137
- def authorized(query:, type:, object:, &block)
138
- query.trace("authorized", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
139
- end
140
-
141
- def authorized_lazy(query:, type:, object:, &block)
142
- query.trace("authorized_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
143
- end
144
-
145
- def resolve_type(query:, type:, object:, &block)
146
- query.trace("resolve_type", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
147
- end
148
-
149
- def resolve_type_lazy(query:, type:, object:, &block)
150
- query.trace("resolve_type_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
151
- end
152
- end
153
-
154
34
  # Objects may include traceable to gain a `.trace(...)` method.
155
35
  # The object must have a `@tracers` ivar of type `Array<<#trace(k, d, &b)>>`.
156
36
  # @api private
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.0.20"
3
+ VERSION = "2.0.21"
4
4
  end
data/lib/graphql.rb CHANGED
@@ -69,6 +69,10 @@ This is probably a bug in GraphQL-Ruby, please report this error on GitHub: http
69
69
 
70
70
  NOT_CONFIGURED = Object.new
71
71
  private_constant :NOT_CONFIGURED
72
+ module EmptyObjects
73
+ EMPTY_HASH = {}.freeze
74
+ EMPTY_ARRAY = [].freeze
75
+ end
72
76
  end
73
77
 
74
78
  # Order matters for these:
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: 2.0.20
4
+ version: 2.0.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-30 00:00:00.000000000 Z
11
+ date: 2023-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -303,6 +303,7 @@ files:
303
303
  - lib/graphql/backtrace.rb
304
304
  - lib/graphql/backtrace/inspect_result.rb
305
305
  - lib/graphql/backtrace/table.rb
306
+ - lib/graphql/backtrace/trace.rb
306
307
  - lib/graphql/backtrace/traced_error.rb
307
308
  - lib/graphql/backtrace/tracer.rb
308
309
  - lib/graphql/coercion_error.rb
@@ -555,6 +556,7 @@ files:
555
556
  - lib/graphql/tracing/appsignal_tracing.rb
556
557
  - lib/graphql/tracing/data_dog_trace.rb
557
558
  - lib/graphql/tracing/data_dog_tracing.rb
559
+ - lib/graphql/tracing/legacy_trace.rb
558
560
  - lib/graphql/tracing/new_relic_trace.rb
559
561
  - lib/graphql/tracing/new_relic_tracing.rb
560
562
  - lib/graphql/tracing/notifications_trace.rb
@@ -568,6 +570,7 @@ files:
568
570
  - lib/graphql/tracing/scout_tracing.rb
569
571
  - lib/graphql/tracing/statsd_trace.rb
570
572
  - lib/graphql/tracing/statsd_tracing.rb
573
+ - lib/graphql/tracing/trace.rb
571
574
  - lib/graphql/type_kinds.rb
572
575
  - lib/graphql/types.rb
573
576
  - lib/graphql/types/big_int.rb