graphql 2.0.21 → 2.0.32
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.
- checksums.yaml +4 -4
- data/lib/generators/graphql/mutation_delete_generator.rb +1 -1
- data/lib/generators/graphql/mutation_update_generator.rb +1 -1
- data/lib/generators/graphql/relay.rb +18 -1
- data/lib/graphql/backtrace.rb +0 -4
- data/lib/graphql/dataloader/source.rb +69 -45
- data/lib/graphql/dataloader.rb +4 -4
- data/lib/graphql/execution/interpreter/arguments_cache.rb +31 -30
- data/lib/graphql/execution/interpreter/runtime.rb +122 -101
- data/lib/graphql/execution/interpreter.rb +1 -2
- data/lib/graphql/execution/lookahead.rb +1 -1
- data/lib/graphql/filter.rb +2 -1
- data/lib/graphql/introspection/entry_points.rb +1 -1
- data/lib/graphql/language/document_from_schema_definition.rb +16 -9
- data/lib/graphql/language/lexer.rb +89 -57
- data/lib/graphql/language/nodes.rb +3 -0
- data/lib/graphql/language/parser.rb +706 -691
- data/lib/graphql/language/parser.y +1 -0
- data/lib/graphql/language/printer.rb +28 -14
- data/lib/graphql/language/visitor.rb +64 -61
- data/lib/graphql/query/context.rb +16 -7
- data/lib/graphql/query/null_context.rb +8 -18
- data/lib/graphql/query/validation_pipeline.rb +2 -1
- data/lib/graphql/query.rb +37 -12
- data/lib/graphql/schema/addition.rb +38 -12
- data/lib/graphql/schema/always_visible.rb +10 -0
- data/lib/graphql/schema/argument.rb +8 -10
- data/lib/graphql/schema/build_from_definition.rb +8 -7
- data/lib/graphql/schema/directive.rb +1 -1
- data/lib/graphql/schema/enum_value.rb +2 -2
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +26 -15
- data/lib/graphql/schema/input_object.rb +9 -7
- data/lib/graphql/schema/interface.rb +5 -1
- data/lib/graphql/schema/introspection_system.rb +1 -1
- data/lib/graphql/schema/member/build_type.rb +10 -2
- data/lib/graphql/schema/member/has_arguments.rb +9 -7
- data/lib/graphql/schema/member/has_directives.rb +1 -1
- data/lib/graphql/schema/member/has_fields.rb +1 -1
- data/lib/graphql/schema/member/has_interfaces.rb +1 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
- data/lib/graphql/schema/object.rb +6 -1
- data/lib/graphql/schema/printer.rb +3 -1
- data/lib/graphql/schema/relay_classic_mutation.rb +1 -1
- data/lib/graphql/schema/resolver.rb +12 -10
- data/lib/graphql/schema/timeout.rb +1 -1
- data/lib/graphql/schema/validator.rb +1 -1
- data/lib/graphql/schema/warden.rb +37 -4
- data/lib/graphql/schema.rb +92 -23
- data/lib/graphql/tracing/appoptics_trace.rb +35 -11
- data/lib/graphql/tracing/appsignal_trace.rb +4 -0
- data/lib/graphql/tracing/data_dog_trace.rb +89 -50
- data/lib/graphql/tracing/data_dog_tracing.rb +7 -21
- data/lib/graphql/tracing/legacy_trace.rb +5 -1
- data/lib/graphql/tracing/notifications_trace.rb +7 -0
- data/lib/graphql/tracing/platform_trace.rb +26 -12
- data/lib/graphql/tracing/prometheus_trace.rb +4 -0
- data/lib/graphql/tracing/scout_trace.rb +3 -0
- data/lib/graphql/tracing/statsd_trace.rb +4 -0
- data/lib/graphql/tracing.rb +1 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +1 -1
- data/lib/graphql/types/relay/edge_behaviors.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -1
- metadata +36 -24
data/lib/graphql/schema.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "graphql/schema/addition"
|
3
|
+
require "graphql/schema/always_visible"
|
3
4
|
require "graphql/schema/base_64_encoder"
|
4
5
|
require "graphql/schema/find_inherited_value"
|
5
6
|
require "graphql/schema/finder"
|
@@ -157,14 +158,25 @@ module GraphQL
|
|
157
158
|
def trace_class_for(mode)
|
158
159
|
@trace_modes ||= {}
|
159
160
|
@trace_modes[mode] ||= begin
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
161
|
+
case mode
|
162
|
+
when :default
|
163
|
+
superclass_base_class = if superclass.respond_to?(:trace_class_for)
|
164
|
+
superclass.trace_class_for(mode)
|
165
|
+
else
|
166
|
+
GraphQL::Tracing::Trace
|
167
|
+
end
|
168
|
+
Class.new(superclass_base_class)
|
169
|
+
when :default_backtrace
|
170
|
+
schema_base_class = trace_class_for(:default)
|
171
|
+
Class.new(schema_base_class) do
|
172
|
+
include(GraphQL::Backtrace::Trace)
|
173
|
+
end
|
164
174
|
else
|
165
|
-
|
175
|
+
mods = trace_modules_for(mode)
|
176
|
+
Class.new(trace_class_for(:default)) do
|
177
|
+
mods.any? && include(*mods)
|
178
|
+
end
|
166
179
|
end
|
167
|
-
Class.new(base_class)
|
168
180
|
end
|
169
181
|
end
|
170
182
|
|
@@ -179,6 +191,19 @@ module GraphQL
|
|
179
191
|
nil
|
180
192
|
end
|
181
193
|
|
194
|
+
def own_trace_modules
|
195
|
+
@own_trace_modules ||= Hash.new { |h, k| h[k] = [] }
|
196
|
+
end
|
197
|
+
|
198
|
+
# @return [Array<Module>] Modules added for tracing in `trace_mode`, including inherited ones
|
199
|
+
def trace_modules_for(trace_mode)
|
200
|
+
modules = own_trace_modules[trace_mode]
|
201
|
+
if superclass.respond_to?(:trace_modules_for)
|
202
|
+
modules += superclass.trace_modules_for(trace_mode)
|
203
|
+
end
|
204
|
+
modules
|
205
|
+
end
|
206
|
+
|
182
207
|
|
183
208
|
# Returns the JSON response of {Introspection::INTROSPECTION_QUERY}.
|
184
209
|
# @see {#as_json}
|
@@ -244,11 +269,13 @@ module GraphQL
|
|
244
269
|
end
|
245
270
|
|
246
271
|
def default_filter
|
247
|
-
GraphQL::Filter.new(except: default_mask
|
272
|
+
GraphQL::Filter.new(except: default_mask)
|
248
273
|
end
|
249
274
|
|
250
275
|
def default_mask(new_mask = nil)
|
251
276
|
if new_mask
|
277
|
+
line = caller(2, 10).find { |l| !l.include?("lib/graphql") }
|
278
|
+
GraphQL::Deprecation.warn("GraphQL::Filter and Schema.mask are deprecated and will be removed in v2.1.0. Implement `visible?` on your schema members instead (https://graphql-ruby.org/authorization/visibility.html).\n #{line}")
|
252
279
|
@own_default_mask = new_mask
|
253
280
|
else
|
254
281
|
@own_default_mask || find_inherited_value(:default_mask, Schema::NullMask)
|
@@ -418,6 +445,18 @@ module GraphQL
|
|
418
445
|
@root_types
|
419
446
|
end
|
420
447
|
|
448
|
+
def warden_class
|
449
|
+
if defined?(@warden_class)
|
450
|
+
@warden_class
|
451
|
+
elsif superclass.respond_to?(:warden_class)
|
452
|
+
superclass.warden_class
|
453
|
+
else
|
454
|
+
GraphQL::Schema::Warden
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
attr_writer :warden_class
|
459
|
+
|
421
460
|
# @param type [Module] The type definition whose possible types you want to see
|
422
461
|
# @return [Hash<String, Module>] All possible types, if no `type` is given.
|
423
462
|
# @return [Array<Module>] Possible types for `type`, if it's given.
|
@@ -959,10 +998,8 @@ module GraphQL
|
|
959
998
|
end
|
960
999
|
|
961
1000
|
def tracer(new_tracer)
|
962
|
-
if
|
963
|
-
|
964
|
-
else
|
965
|
-
trace_mode(:default, Class.new(GraphQL::Tracing::LegacyTrace))
|
1001
|
+
if !(trace_class_for(:default) < GraphQL::Tracing::CallLegacyTracers)
|
1002
|
+
trace_with(GraphQL::Tracing::CallLegacyTracers)
|
966
1003
|
end
|
967
1004
|
|
968
1005
|
own_tracers << new_tracer
|
@@ -976,28 +1013,58 @@ module GraphQL
|
|
976
1013
|
# will be called at runtime.
|
977
1014
|
#
|
978
1015
|
# @param trace_mod [Module] A module that implements tracing methods
|
1016
|
+
# @param mode [Symbol] Trace module will only be used for this trade mode
|
979
1017
|
# @param options [Hash] Keywords that will be passed to the tracing class during `#initialize`
|
980
1018
|
# @return [void]
|
981
|
-
def trace_with(trace_mod, **options)
|
982
|
-
|
983
|
-
|
1019
|
+
def trace_with(trace_mod, mode: :default, **options)
|
1020
|
+
if mode.is_a?(Array)
|
1021
|
+
mode.each { |m| trace_with(trace_mod, mode: m, **options) }
|
1022
|
+
else
|
1023
|
+
tc = trace_class_for(mode)
|
1024
|
+
tc.include(trace_mod)
|
1025
|
+
if mode != :default
|
1026
|
+
own_trace_modules[mode] << trace_mod
|
1027
|
+
end
|
1028
|
+
t_opts = trace_options_for(mode)
|
1029
|
+
t_opts.merge!(options)
|
1030
|
+
end
|
1031
|
+
nil
|
984
1032
|
end
|
985
1033
|
|
986
|
-
|
987
|
-
|
1034
|
+
# The options hash for this trace mode
|
1035
|
+
# @return [Hash]
|
1036
|
+
def trace_options_for(mode)
|
1037
|
+
@trace_options_for_mode ||= {}
|
1038
|
+
@trace_options_for_mode[mode] ||= begin
|
1039
|
+
if superclass.respond_to?(:trace_options_for)
|
1040
|
+
superclass.trace_options_for(mode).dup
|
1041
|
+
else
|
1042
|
+
{}
|
1043
|
+
end
|
1044
|
+
end
|
988
1045
|
end
|
989
1046
|
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
1047
|
+
# Create a trace instance which will include the trace modules specified for the optional mode.
|
1048
|
+
#
|
1049
|
+
# @param mode [Symbol] Trace modules for this trade mode will be included
|
1050
|
+
# @param options [Hash] Keywords that will be passed to the tracing class during `#initialize`
|
1051
|
+
# @return [Tracing::Trace]
|
1052
|
+
def new_trace(mode: nil, **options)
|
1053
|
+
target = options[:query] || options[:multiplex]
|
1054
|
+
mode ||= target && target.context[:trace_mode]
|
1055
|
+
|
1056
|
+
trace_mode = if mode
|
1057
|
+
mode
|
1058
|
+
elsif target && target.context[:backtrace]
|
995
1059
|
:default_backtrace
|
996
1060
|
else
|
997
1061
|
:default
|
998
1062
|
end
|
999
|
-
|
1000
|
-
|
1063
|
+
|
1064
|
+
base_trace_options = trace_options_for(trace_mode)
|
1065
|
+
trace_options = base_trace_options.merge(options)
|
1066
|
+
trace_class_for_mode = trace_class_for(trace_mode)
|
1067
|
+
trace_class_for_mode.new(**trace_options)
|
1001
1068
|
end
|
1002
1069
|
|
1003
1070
|
def query_analyzer(new_analyzer)
|
@@ -1036,7 +1103,9 @@ module GraphQL
|
|
1036
1103
|
{
|
1037
1104
|
backtrace: ctx[:backtrace],
|
1038
1105
|
tracers: ctx[:tracers],
|
1106
|
+
trace: ctx[:trace],
|
1039
1107
|
dataloader: ctx[:dataloader],
|
1108
|
+
trace_mode: ctx[:trace_mode],
|
1040
1109
|
}
|
1041
1110
|
else
|
1042
1111
|
{}
|
@@ -28,6 +28,8 @@ module GraphQL
|
|
28
28
|
Gem::Version.new('1.0.0')
|
29
29
|
end
|
30
30
|
|
31
|
+
# rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
|
32
|
+
|
31
33
|
[
|
32
34
|
'lex',
|
33
35
|
'parse',
|
@@ -55,20 +57,41 @@ module GraphQL
|
|
55
57
|
RUBY
|
56
58
|
end
|
57
59
|
|
58
|
-
|
59
|
-
return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
|
60
|
-
layer = platform_key
|
61
|
-
kvs = metadata(data, layer)
|
60
|
+
# rubocop:enable Development/NoEvalCop
|
62
61
|
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
def execute_field(query:, field:, ast_node:, arguments:, object:)
|
63
|
+
return_type = field.type.unwrap
|
64
|
+
trace_field = if return_type.kind.scalar? || return_type.kind.enum?
|
65
|
+
(field.trace.nil? && @trace_scalars) || field.trace
|
66
|
+
else
|
67
|
+
true
|
68
|
+
end
|
69
|
+
platform_key = if trace_field
|
70
|
+
@platform_key_cache[AppOpticsTrace].platform_field_key_cache[field]
|
71
|
+
else
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
if platform_key && trace_field
|
75
|
+
return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
|
76
|
+
layer = platform_key
|
77
|
+
kvs = metadata({query: query, field: field, ast_node: ast_node, arguments: arguments, object: object}, layer)
|
78
|
+
|
79
|
+
::AppOpticsAPM::SDK.trace(layer, kvs) do
|
80
|
+
kvs.clear # we don't have to send them twice
|
81
|
+
super
|
82
|
+
end
|
83
|
+
else
|
84
|
+
super
|
66
85
|
end
|
67
86
|
end
|
68
87
|
|
88
|
+
def execute_field_lazy(query:, field:, ast_node:, arguments:, object:)
|
89
|
+
execute_field(query: query, field: field, ast_node: ast_node, arguments: arguments, object: object)
|
90
|
+
end
|
91
|
+
|
69
92
|
def authorized(**data)
|
70
93
|
return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
|
71
|
-
layer = @platform_authorized_key_cache[data[:type]]
|
94
|
+
layer = @platform_key_cache[AppOpticsTrace].platform_authorized_key_cache[data[:type]]
|
72
95
|
kvs = metadata(data, layer)
|
73
96
|
|
74
97
|
::AppOpticsAPM::SDK.trace(layer, kvs) do
|
@@ -79,7 +102,7 @@ module GraphQL
|
|
79
102
|
|
80
103
|
def authorized_lazy(**data)
|
81
104
|
return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
|
82
|
-
layer = @platform_authorized_key_cache[data[:type]]
|
105
|
+
layer = @platform_key_cache[AppOpticsTrace].platform_authorized_key_cache[data[:type]]
|
83
106
|
kvs = metadata(data, layer)
|
84
107
|
|
85
108
|
::AppOpticsAPM::SDK.trace(layer, kvs) do
|
@@ -90,7 +113,8 @@ module GraphQL
|
|
90
113
|
|
91
114
|
def resolve_type(**data)
|
92
115
|
return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
|
93
|
-
layer = @platform_resolve_type_key_cache[data[:type]]
|
116
|
+
layer = @platform_key_cache[AppOpticsTrace].platform_resolve_type_key_cache[data[:type]]
|
117
|
+
|
94
118
|
kvs = metadata(data, layer)
|
95
119
|
|
96
120
|
::AppOpticsAPM::SDK.trace(layer, kvs) do
|
@@ -101,7 +125,7 @@ module GraphQL
|
|
101
125
|
|
102
126
|
def resolve_type_lazy(**data)
|
103
127
|
return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
|
104
|
-
layer = @platform_resolve_type_key_cache[data[:type]]
|
128
|
+
layer = @platform_key_cache[AppOpticsTrace].platform_resolve_type_key_cache[data[:type]]
|
105
129
|
kvs = metadata(data, layer)
|
106
130
|
|
107
131
|
::AppOpticsAPM::SDK.trace(layer, kvs) do
|
@@ -13,6 +13,8 @@ module GraphQL
|
|
13
13
|
super
|
14
14
|
end
|
15
15
|
|
16
|
+
# rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
|
17
|
+
|
16
18
|
{
|
17
19
|
"lex" => "lex.graphql",
|
18
20
|
"parse" => "parse.graphql",
|
@@ -43,6 +45,8 @@ module GraphQL
|
|
43
45
|
RUBY
|
44
46
|
end
|
45
47
|
|
48
|
+
# rubocop:enable Development/NoEvalCop
|
49
|
+
|
46
50
|
def platform_execute_field(platform_key)
|
47
51
|
Appsignal.instrument(platform_key) do
|
48
52
|
yield
|
@@ -3,24 +3,25 @@
|
|
3
3
|
module GraphQL
|
4
4
|
module Tracing
|
5
5
|
module DataDogTrace
|
6
|
+
# @param tracer [#trace] Deprecated
|
6
7
|
# @param analytics_enabled [Boolean] Deprecated
|
7
8
|
# @param analytics_sample_rate [Float] Deprecated
|
8
|
-
def initialize(tracer: nil, analytics_enabled: false, analytics_sample_rate: 1.0, service:
|
9
|
+
def initialize(tracer: nil, analytics_enabled: false, analytics_sample_rate: 1.0, service: nil, **rest)
|
9
10
|
if tracer.nil?
|
10
11
|
tracer = defined?(Datadog::Tracing) ? Datadog::Tracing : Datadog.tracer
|
11
12
|
end
|
12
13
|
@tracer = tracer
|
13
14
|
|
14
|
-
|
15
|
-
&& Datadog::Contrib::Analytics.respond_to?(:enabled?) \
|
16
|
-
&& Datadog::Contrib::Analytics.respond_to?(:set_sample_rate)
|
17
|
-
|
18
|
-
@analytics_enabled = analytics_available && Datadog::Contrib::Analytics.enabled?(analytics_enabled)
|
15
|
+
@analytics_enabled = analytics_enabled
|
19
16
|
@analytics_sample_rate = analytics_sample_rate
|
17
|
+
|
20
18
|
@service_name = service
|
19
|
+
@has_prepare_span = respond_to?(:prepare_span)
|
21
20
|
super
|
22
21
|
end
|
23
22
|
|
23
|
+
# rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
|
24
|
+
|
24
25
|
{
|
25
26
|
'lex' => 'lex.graphql',
|
26
27
|
'parse' => 'parse.graphql',
|
@@ -33,12 +34,9 @@ module GraphQL
|
|
33
34
|
}.each do |trace_method, trace_key|
|
34
35
|
module_eval <<-RUBY, __FILE__, __LINE__
|
35
36
|
def #{trace_method}(**data)
|
36
|
-
@tracer.trace("#{trace_key}", service: @service_name) do |span|
|
37
|
-
|
38
|
-
|
39
|
-
span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
|
40
|
-
span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, '#{trace_method}')
|
41
|
-
end
|
37
|
+
@tracer.trace("#{trace_key}", service: @service_name, type: 'custom') do |span|
|
38
|
+
span.set_tag('component', 'graphql')
|
39
|
+
span.set_tag('operation', '#{trace_method}')
|
42
40
|
|
43
41
|
#{
|
44
42
|
if trace_method == 'execute_multiplex'
|
@@ -53,10 +51,8 @@ module GraphQL
|
|
53
51
|
end
|
54
52
|
span.resource = resource if resource
|
55
53
|
|
56
|
-
#
|
57
|
-
if @analytics_enabled
|
58
|
-
Datadog::Contrib::Analytics.set_sample_rate(span, @analytics_sample_rate)
|
59
|
-
end
|
54
|
+
# [Deprecated] will be removed in the future
|
55
|
+
span.set_metric('_dd1.sr.eausr', @analytics_sample_rate) if @analytics_enabled
|
60
56
|
RUBY
|
61
57
|
elsif trace_method == 'execute_query'
|
62
58
|
<<-RUBY
|
@@ -66,61 +62,104 @@ module GraphQL
|
|
66
62
|
RUBY
|
67
63
|
end
|
68
64
|
}
|
69
|
-
|
65
|
+
if @has_prepare_span
|
66
|
+
prepare_span("#{trace_method.sub("platform_", "")}", data, span)
|
67
|
+
end
|
70
68
|
super
|
71
69
|
end
|
72
70
|
end
|
73
71
|
RUBY
|
74
72
|
end
|
75
73
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
74
|
+
# rubocop:enable Development/NoEvalCop
|
75
|
+
|
76
|
+
def execute_field_span(span_key, query, field, ast_node, arguments, object)
|
77
|
+
return_type = field.type.unwrap
|
78
|
+
trace_field = if return_type.kind.scalar? || return_type.kind.enum?
|
79
|
+
(field.trace.nil? && @trace_scalars) || field.trace
|
80
|
+
else
|
81
|
+
true
|
82
|
+
end
|
83
|
+
platform_key = if trace_field
|
84
|
+
@platform_key_cache[DataDogTrace].platform_field_key_cache[field]
|
85
|
+
else
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
if platform_key && trace_field
|
89
|
+
@tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
|
90
|
+
span.set_tag('component', 'graphql')
|
91
|
+
span.set_tag('operation', span_key)
|
92
|
+
|
93
|
+
if @has_prepare_span
|
94
|
+
prepare_span_data = { query: query, field: field, ast_node: ast_node, arguments: arguments, object: object }
|
95
|
+
prepare_span(span_key, prepare_span_data, span)
|
96
|
+
end
|
97
|
+
yield
|
82
98
|
end
|
83
|
-
|
99
|
+
else
|
84
100
|
yield
|
85
101
|
end
|
86
102
|
end
|
103
|
+
def execute_field(query:, field:, ast_node:, arguments:, object:)
|
104
|
+
execute_field_span("execute_field", query, field, ast_node, arguments, object) do
|
105
|
+
super(query: query, field: field, ast_node: ast_node, arguments: arguments, object: object)
|
106
|
+
end
|
107
|
+
end
|
87
108
|
|
88
|
-
def
|
89
|
-
|
109
|
+
def execute_field_lazy(query:, field:, ast_node:, arguments:, object:)
|
110
|
+
execute_field_span("execute_field_lazy", query, field, ast_node, arguments, object) do
|
111
|
+
super(query: query, field: field, ast_node: ast_node, arguments: arguments, object: object)
|
112
|
+
end
|
90
113
|
end
|
91
114
|
|
92
|
-
def authorized(
|
93
|
-
|
94
|
-
@tracer.trace(platform_key, service: @service_name) do |span|
|
95
|
-
span.span_type = 'custom'
|
96
|
-
if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
|
97
|
-
span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
|
98
|
-
span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
|
99
|
-
end
|
100
|
-
prepare_span(span_key, {object: object, type: type, query: query}, span)
|
115
|
+
def authorized(query:, type:, object:)
|
116
|
+
authorized_span("authorized", object, type, query) do
|
101
117
|
super(query: query, type: type, object: object)
|
102
118
|
end
|
103
119
|
end
|
104
120
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
121
|
+
def authorized_span(span_key, object, type, query)
|
122
|
+
platform_key = @platform_key_cache[DataDogTrace].platform_authorized_key_cache[type]
|
123
|
+
@tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
|
124
|
+
span.set_tag('component', 'graphql')
|
125
|
+
span.set_tag('operation', span_key)
|
108
126
|
|
109
|
-
|
110
|
-
|
111
|
-
@tracer.trace(platform_key, service: @service_name) do |span|
|
112
|
-
span.span_type = 'custom'
|
113
|
-
if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
|
114
|
-
span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
|
115
|
-
span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
|
127
|
+
if @has_prepare_span
|
128
|
+
prepare_span(span_key, {object: object, type: type, query: query}, span)
|
116
129
|
end
|
117
|
-
|
130
|
+
yield
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def authorized_lazy(object:, type:, query:)
|
135
|
+
authorized_span("authorized_lazy", object, type, query) do
|
118
136
|
super(query: query, type: type, object: object)
|
119
137
|
end
|
120
138
|
end
|
121
139
|
|
122
|
-
def
|
123
|
-
|
140
|
+
def resolve_type(object:, type:, query:)
|
141
|
+
resolve_type_span("resolve_type", object, type, query) do
|
142
|
+
super(object: object, query: query, type: type)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def resolve_type_lazy(object:, type:, query:)
|
147
|
+
resolve_type_span("resolve_type_lazy", object, type, query) do
|
148
|
+
super(object: object, query: query, type: type)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def resolve_type_span(span_key, object, type, query)
|
153
|
+
platform_key = @platform_key_cache[DataDogTrace].platform_resolve_type_key_cache[type]
|
154
|
+
@tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
|
155
|
+
span.set_tag('component', 'graphql')
|
156
|
+
span.set_tag('operation', span_key)
|
157
|
+
|
158
|
+
if @has_prepare_span
|
159
|
+
prepare_span(span_key, {object: object, type: type, query: query}, span)
|
160
|
+
end
|
161
|
+
yield
|
162
|
+
end
|
124
163
|
end
|
125
164
|
|
126
165
|
include PlatformTrace
|
@@ -129,8 +168,8 @@ module GraphQL
|
|
129
168
|
# @param key [String] The event being traced
|
130
169
|
# @param data [Hash] The runtime data for this event (@see GraphQL::Tracing for keys for each event)
|
131
170
|
# @param span [Datadog::Tracing::SpanOperation] The datadog span for this event
|
132
|
-
def prepare_span(key, data, span)
|
133
|
-
end
|
171
|
+
# def prepare_span(key, data, span)
|
172
|
+
# end
|
134
173
|
|
135
174
|
def platform_field_key(field)
|
136
175
|
field.path
|
@@ -15,12 +15,9 @@ module GraphQL
|
|
15
15
|
}
|
16
16
|
|
17
17
|
def platform_trace(platform_key, key, data)
|
18
|
-
tracer.trace(platform_key, service:
|
19
|
-
span.
|
20
|
-
|
21
|
-
span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
|
22
|
-
span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, key)
|
23
|
-
end
|
18
|
+
tracer.trace(platform_key, service: options[:service], type: 'custom') do |span|
|
19
|
+
span.set_tag('component', 'graphql')
|
20
|
+
span.set_tag('operation', key)
|
24
21
|
|
25
22
|
if key == 'execute_multiplex'
|
26
23
|
operations = data[:multiplex].queries.map(&:selected_operation_name).join(', ')
|
@@ -33,10 +30,8 @@ module GraphQL
|
|
33
30
|
end
|
34
31
|
span.resource = resource if resource
|
35
32
|
|
36
|
-
#
|
37
|
-
if analytics_enabled?
|
38
|
-
Datadog::Contrib::Analytics.set_sample_rate(span, analytics_sample_rate)
|
39
|
-
end
|
33
|
+
# [Deprecated] will be removed in the future
|
34
|
+
span.set_metric('_dd1.sr.eausr', analytics_sample_rate) if analytics_enabled?
|
40
35
|
end
|
41
36
|
|
42
37
|
if key == 'execute_query'
|
@@ -51,10 +46,6 @@ module GraphQL
|
|
51
46
|
end
|
52
47
|
end
|
53
48
|
|
54
|
-
def service_name
|
55
|
-
options.fetch(:service, 'ruby-graphql')
|
56
|
-
end
|
57
|
-
|
58
49
|
# Implement this method in a subclass to apply custom tags to datadog spans
|
59
50
|
# @param key [String] The event being traced
|
60
51
|
# @param data [Hash] The runtime data for this event (@see GraphQL::Tracing for keys for each event)
|
@@ -65,18 +56,13 @@ module GraphQL
|
|
65
56
|
def tracer
|
66
57
|
default_tracer = defined?(Datadog::Tracing) ? Datadog::Tracing : Datadog.tracer
|
67
58
|
|
59
|
+
# [Deprecated] options[:tracer] will be removed in the future
|
68
60
|
options.fetch(:tracer, default_tracer)
|
69
61
|
end
|
70
62
|
|
71
|
-
def analytics_available?
|
72
|
-
defined?(Datadog::Contrib::Analytics) \
|
73
|
-
&& Datadog::Contrib::Analytics.respond_to?(:enabled?) \
|
74
|
-
&& Datadog::Contrib::Analytics.respond_to?(:set_sample_rate)
|
75
|
-
end
|
76
|
-
|
77
63
|
def analytics_enabled?
|
78
64
|
# [Deprecated] options[:analytics_enabled] will be removed in the future
|
79
|
-
|
65
|
+
options.fetch(:analytics_enabled, false)
|
80
66
|
end
|
81
67
|
|
82
68
|
def analytics_sample_rate
|
@@ -4,7 +4,7 @@ module GraphQL
|
|
4
4
|
# This trace class calls legacy-style tracer with payload hashes.
|
5
5
|
# New-style `trace_with` modules significantly reduce the overhead of tracing,
|
6
6
|
# but that advantage is lost when legacy-style tracers are also used (since the payload hashes are still constructed).
|
7
|
-
|
7
|
+
module CallLegacyTracers
|
8
8
|
def lex(query_string:)
|
9
9
|
(@multiplex || @query).trace("lex", { query_string: query_string }) { super }
|
10
10
|
end
|
@@ -61,5 +61,9 @@ module GraphQL
|
|
61
61
|
query.trace("resolve_type_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
|
62
62
|
end
|
63
63
|
end
|
64
|
+
|
65
|
+
class LegacyTrace < Trace
|
66
|
+
include CallLegacyTracers
|
67
|
+
end
|
64
68
|
end
|
65
69
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "graphql/tracing/platform_trace"
|
4
|
+
|
3
5
|
module GraphQL
|
4
6
|
module Tracing
|
5
7
|
# This implementation forwards events to a notification handler (i.e.
|
@@ -14,12 +16,15 @@ module GraphQL
|
|
14
16
|
super
|
15
17
|
end
|
16
18
|
|
19
|
+
# rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
|
20
|
+
|
17
21
|
{
|
18
22
|
"lex" => "lex.graphql",
|
19
23
|
"parse" => "parse.graphql",
|
20
24
|
"validate" => "validate.graphql",
|
21
25
|
"analyze_multiplex" => "analyze_multiplex.graphql",
|
22
26
|
"analyze_query" => "analyze_query.graphql",
|
27
|
+
"execute_multiplex" => "execute_multiplex.graphql",
|
23
28
|
"execute_query" => "execute_query.graphql",
|
24
29
|
"execute_query_lazy" => "execute_query_lazy.graphql",
|
25
30
|
"execute_field" => "execute_field.graphql",
|
@@ -36,6 +41,8 @@ module GraphQL
|
|
36
41
|
RUBY
|
37
42
|
end
|
38
43
|
|
44
|
+
# rubocop:enable Development/NoEvalCop
|
45
|
+
|
39
46
|
include PlatformTrace
|
40
47
|
end
|
41
48
|
end
|