graphql 2.4.15 → 2.5.0
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/graphql/dashboard/detailed_traces.rb +47 -0
- data/lib/graphql/dashboard/installable.rb +22 -0
- data/lib/graphql/dashboard/limiters.rb +93 -0
- data/lib/graphql/dashboard/operation_store.rb +199 -0
- data/lib/graphql/dashboard/statics/charts.min.css +1 -0
- data/lib/graphql/dashboard/statics/dashboard.css +27 -0
- data/lib/graphql/dashboard/statics/dashboard.js +74 -9
- data/lib/graphql/dashboard/subscriptions.rb +96 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +23 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
- data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +49 -1
- data/lib/graphql/dashboard.rb +45 -29
- data/lib/graphql/execution/interpreter.rb +3 -5
- data/lib/graphql/execution/multiplex.rb +1 -1
- data/lib/graphql/language/parser.rb +13 -6
- data/lib/graphql/query.rb +2 -4
- data/lib/graphql/static_validation/all_rules.rb +1 -1
- data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +25 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +7 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +5 -0
- data/lib/graphql/tracing/appsignal_trace.rb +26 -61
- data/lib/graphql/tracing/data_dog_trace.rb +41 -164
- data/lib/graphql/tracing/monitor_trace.rb +285 -0
- data/lib/graphql/tracing/new_relic_trace.rb +34 -166
- data/lib/graphql/tracing/notifications_trace.rb +181 -37
- data/lib/graphql/tracing/perfetto_trace.rb +15 -18
- data/lib/graphql/tracing/prometheus_trace.rb +47 -74
- data/lib/graphql/tracing/scout_trace.rb +25 -59
- data/lib/graphql/tracing/sentry_trace.rb +57 -99
- data/lib/graphql/tracing/statsd_trace.rb +24 -47
- data/lib/graphql/tracing/trace.rb +0 -17
- data/lib/graphql/tracing.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- metadata +25 -4
- data/lib/graphql/dashboard/views/graphql/dashboard/traces/index.html.erb +0 -63
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "graphql/tracing/
|
3
|
+
require "graphql/tracing/monitor_trace"
|
4
4
|
|
5
5
|
module GraphQL
|
6
6
|
module Tracing
|
@@ -16,184 +16,52 @@ module GraphQL
|
|
16
16
|
#
|
17
17
|
# @example Installing without trace events for `authorized?` or `resolve_type` calls
|
18
18
|
# trace_with GraphQL::Tracing::NewRelicTrace, trace_authorized: false, trace_resolve_type: false
|
19
|
+
NewRelicTrace = MonitorTrace.create_module("newrelic")
|
19
20
|
module NewRelicTrace
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
h[type] = "GraphQL/Authorized/#{type.graphql_name}"
|
37
|
-
end.compare_by_identity
|
38
|
-
|
39
|
-
@nr_resolve_type_names = Hash.new do |h, type|
|
40
|
-
h[type] = "GraphQL/ResolveType/#{type.graphql_name}"
|
41
|
-
end.compare_by_identity
|
42
|
-
|
43
|
-
@nr_source_names = Hash.new do |h, source_inst|
|
44
|
-
h[source_inst] = "GraphQL/Source/#{source_inst.class.name}"
|
45
|
-
end.compare_by_identity
|
46
|
-
|
47
|
-
@nr_parse = @nr_validate = @nr_analyze = @nr_execute = nil
|
48
|
-
super
|
49
|
-
end
|
50
|
-
|
51
|
-
def begin_parse(query_str)
|
52
|
-
@nr_parse = NewRelic::Agent::Tracer.start_transaction_or_segment(partial_name: "GraphQL/parse", category: :web)
|
53
|
-
super
|
54
|
-
end
|
55
|
-
|
56
|
-
def end_parse(query_str)
|
57
|
-
@nr_parse.finish
|
58
|
-
super
|
59
|
-
end
|
60
|
-
|
61
|
-
def begin_validate(query, validate)
|
62
|
-
@nr_validate = NewRelic::Agent::Tracer.start_transaction_or_segment(partial_name: "GraphQL/validate", category: :web)
|
63
|
-
super
|
64
|
-
end
|
65
|
-
|
66
|
-
def end_validate(query, validate, validation_errors)
|
67
|
-
@nr_validate.finish
|
68
|
-
super
|
69
|
-
end
|
70
|
-
|
71
|
-
def begin_analyze_multiplex(multiplex, analyzers)
|
72
|
-
@nr_analyze = NewRelic::Agent::Tracer.start_transaction_or_segment(partial_name: "GraphQL/analyze", category: :web)
|
73
|
-
super
|
74
|
-
end
|
75
|
-
|
76
|
-
def end_analyze_multiplex(multiplex, analyzers)
|
77
|
-
@nr_analyze.finish
|
78
|
-
super
|
79
|
-
end
|
80
|
-
|
81
|
-
def begin_execute_multiplex(multiplex)
|
82
|
-
query = multiplex.queries.first
|
83
|
-
set_this_txn_name = query.context[:set_new_relic_transaction_name]
|
84
|
-
if set_this_txn_name || (set_this_txn_name.nil? && @set_transaction_name)
|
85
|
-
NewRelic::Agent.set_transaction_name(transaction_name(query))
|
21
|
+
class NewrelicMonitor < MonitorTrace::Monitor
|
22
|
+
PARSE_NAME = "GraphQL/parse"
|
23
|
+
LEX_NAME = "GraphQL/lex"
|
24
|
+
VALIDATE_NAME = "GraphQL/validate"
|
25
|
+
EXECUTE_NAME = "GraphQL/execute"
|
26
|
+
ANALYZE_NAME = "GraphQL/analyze"
|
27
|
+
|
28
|
+
def instrument(keyword, payload, &block)
|
29
|
+
if keyword == :execute
|
30
|
+
query = payload.queries.first
|
31
|
+
set_this_txn_name = query.context[:set_new_relic_transaction_name]
|
32
|
+
if set_this_txn_name || (set_this_txn_name.nil? && @set_transaction_name)
|
33
|
+
NewRelic::Agent.set_transaction_name(transaction_name(query))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
::NewRelic::Agent::MethodTracerHelpers.trace_execution_scoped(name_for(keyword, payload), &block)
|
86
37
|
end
|
87
|
-
@nr_execute = NewRelic::Agent::Tracer.start_transaction_or_segment(partial_name: "GraphQL/execute", category: :web)
|
88
|
-
super
|
89
|
-
end
|
90
|
-
|
91
|
-
def end_execute_multiplex(multiplex)
|
92
|
-
@nr_execute.finish
|
93
|
-
super
|
94
|
-
end
|
95
38
|
|
96
|
-
|
97
|
-
|
98
|
-
trace_field = if return_type.kind.scalar? || return_type.kind.enum?
|
99
|
-
(field.trace.nil? && @trace_scalars) || field.trace
|
100
|
-
else
|
101
|
-
true
|
39
|
+
def platform_source_class_key(source_class)
|
40
|
+
"GraphQL/Source/#{source_class.name}"
|
102
41
|
end
|
103
|
-
if trace_field
|
104
|
-
start_segment(partial_name: @nr_field_names[field], category: :web)
|
105
|
-
end
|
106
|
-
super
|
107
|
-
end
|
108
42
|
|
109
|
-
|
110
|
-
|
111
|
-
super
|
112
|
-
end
|
113
|
-
|
114
|
-
def begin_authorized(type, obj, ctx)
|
115
|
-
if @trace_authorized
|
116
|
-
start_segment(partial_name: @nr_authorized_names[type], category: :web)
|
117
|
-
end
|
118
|
-
super
|
119
|
-
end
|
120
|
-
|
121
|
-
def end_authorized(type, obj, ctx, is_authed)
|
122
|
-
if @trace_authorized
|
123
|
-
finish_segment
|
43
|
+
def platform_field_key(field)
|
44
|
+
"GraphQL/#{field.owner.graphql_name}/#{field.graphql_name}"
|
124
45
|
end
|
125
|
-
super
|
126
|
-
end
|
127
46
|
|
128
|
-
|
129
|
-
|
130
|
-
start_segment(partial_name: @nr_resolve_type_names[type], category: :web)
|
47
|
+
def platform_authorized_key(type)
|
48
|
+
"GraphQL/Authorized/#{type.graphql_name}"
|
131
49
|
end
|
132
|
-
super
|
133
|
-
end
|
134
50
|
|
135
|
-
|
136
|
-
|
137
|
-
finish_segment
|
51
|
+
def platform_resolve_type_key(type)
|
52
|
+
"GraphQL/ResolveType/#{type.graphql_name}"
|
138
53
|
end
|
139
|
-
super
|
140
|
-
end
|
141
|
-
|
142
|
-
def begin_dataloader_source(source)
|
143
|
-
start_segment(partial_name: @nr_source_names[source], category: :web)
|
144
|
-
super
|
145
|
-
end
|
146
54
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
def dataloader_fiber_yield(source)
|
153
|
-
prev_segment = finish_segment
|
154
|
-
Fiber[:graphql_nr_previous_segment] = prev_segment
|
155
|
-
super
|
156
|
-
end
|
55
|
+
class Event < MonitorTrace::Monitor::Event
|
56
|
+
def start
|
57
|
+
name = @monitor.name_for(keyword, object)
|
58
|
+
@nr_ev = NewRelic::Agent::Tracer.start_transaction_or_segment(partial_name: name, category: :web)
|
59
|
+
end
|
157
60
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
if prev_segment
|
162
|
-
seg_partial_name = prev_segment.name.sub(/^.*(GraphQL.*)$/, '\1')
|
163
|
-
start_segment(partial_name: seg_partial_name, category: :web)
|
61
|
+
def finish
|
62
|
+
@nr_ev.finish
|
63
|
+
end
|
164
64
|
end
|
165
|
-
super
|
166
|
-
end
|
167
|
-
|
168
|
-
private
|
169
|
-
|
170
|
-
def start_segment(...)
|
171
|
-
Fiber[:graphql_nr_segment] = NewRelic::Agent::Tracer.start_transaction_or_segment(...)
|
172
|
-
end
|
173
|
-
|
174
|
-
def finish_segment
|
175
|
-
segment = Fiber[:graphql_nr_segment]
|
176
|
-
if segment
|
177
|
-
segment.finish
|
178
|
-
Fiber[:graphql_nr_segment] = nil
|
179
|
-
segment
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def transaction_name(query)
|
184
|
-
selected_op = query.selected_operation
|
185
|
-
txn_name = if selected_op
|
186
|
-
op_type = selected_op.operation_type
|
187
|
-
op_name = selected_op.name || fallback_transaction_name(query.context) || "anonymous"
|
188
|
-
"#{op_type}.#{op_name}"
|
189
|
-
else
|
190
|
-
"query.anonymous"
|
191
|
-
end
|
192
|
-
"GraphQL/#{txn_name}"
|
193
|
-
end
|
194
|
-
|
195
|
-
def fallback_transaction_name(context)
|
196
|
-
context[:tracing_fallback_transaction_name]
|
197
65
|
end
|
198
66
|
end
|
199
67
|
end
|
@@ -1,49 +1,193 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "graphql/tracing/platform_trace"
|
4
|
-
|
5
3
|
module GraphQL
|
6
4
|
module Tracing
|
7
|
-
# This implementation forwards events to a notification handler
|
8
|
-
# ActiveSupport::Notifications or Dry::Monitor::Notifications)
|
9
|
-
#
|
5
|
+
# This implementation forwards events to a notification handler
|
6
|
+
# (i.e. ActiveSupport::Notifications or Dry::Monitor::Notifications) with a `graphql` suffix.
|
7
|
+
#
|
8
|
+
# @see ActiveSupportNotificationsTrace ActiveSupport::Notifications integration
|
10
9
|
module NotificationsTrace
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
"authorized_lazy" => "authorized_lazy.graphql",
|
34
|
-
"resolve_type" => "resolve_type.graphql",
|
35
|
-
"resolve_type_lazy" => "resolve_type.graphql",
|
36
|
-
}.each do |trace_method, platform_key|
|
37
|
-
module_eval <<-RUBY, __FILE__, __LINE__
|
38
|
-
def #{trace_method}(**metadata, &block)
|
39
|
-
@notifications_engine.instrument("#{platform_key}", metadata) { super(**metadata, &block) }
|
10
|
+
# @api private
|
11
|
+
class Adapter
|
12
|
+
def instrument(keyword, payload, &block)
|
13
|
+
raise "Implement #{self.class}#instrument to measure the block"
|
14
|
+
end
|
15
|
+
|
16
|
+
def start_event(keyword, payload)
|
17
|
+
ev = self.class::Event.new(keyword, payload)
|
18
|
+
ev.start
|
19
|
+
ev
|
20
|
+
end
|
21
|
+
|
22
|
+
class Event
|
23
|
+
def initialize(name, payload)
|
24
|
+
@name = name
|
25
|
+
@payload = payload
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :name, :payload
|
29
|
+
|
30
|
+
def start
|
31
|
+
raise "Implement #{self.class}#start to begin a new event (#{inspect})"
|
40
32
|
end
|
41
|
-
|
33
|
+
|
34
|
+
def finish
|
35
|
+
raise "Implement #{self.class}#finish to end this event (#{inspect})"
|
36
|
+
end
|
37
|
+
end
|
42
38
|
end
|
43
39
|
|
44
|
-
#
|
40
|
+
# @api private
|
41
|
+
class DryMonitorAdapter < Adapter
|
42
|
+
def instrument(...)
|
43
|
+
Dry::Monitor.instrument(...)
|
44
|
+
end
|
45
45
|
|
46
|
-
|
46
|
+
class Event < Adapter::Event
|
47
|
+
def start
|
48
|
+
Dry::Monitor.start(@name, @payload)
|
49
|
+
end
|
50
|
+
|
51
|
+
def finish
|
52
|
+
Dry::Monitor.stop(@name, @payload)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# @api private
|
58
|
+
class ActiveSupportNotificationsAdapter < Adapter
|
59
|
+
def instrument(...)
|
60
|
+
ActiveSupport::Notifications.instrument(...)
|
61
|
+
end
|
62
|
+
|
63
|
+
class Event < Adapter::Event
|
64
|
+
def start
|
65
|
+
@asn_event = ActiveSupport::Notifications.instrumenter.new_event(@name, @payload)
|
66
|
+
@asn_event.start!
|
67
|
+
end
|
68
|
+
|
69
|
+
def finish
|
70
|
+
@asn_event.finish!
|
71
|
+
ActiveSupport::Notifications.publish_event(@asn_event)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# @param engine [Class] The notifications engine to use, eg `Dry::Monitor` or `ActiveSupport::Notifications`
|
77
|
+
def initialize(engine:, **rest)
|
78
|
+
adapter = if defined?(Dry::Monitor) && engine == Dry::Monitor
|
79
|
+
DryMonitoringAdapter
|
80
|
+
elsif defined?(ActiveSupport::Notifications) && engine == ActiveSupport::Notifications
|
81
|
+
ActiveSupportNotificationsAdapter
|
82
|
+
else
|
83
|
+
engine
|
84
|
+
end
|
85
|
+
@notifications = adapter.new
|
86
|
+
super
|
87
|
+
end
|
88
|
+
|
89
|
+
def parse(**payload)
|
90
|
+
@notifications.instrument("parse.graphql", payload) do
|
91
|
+
super
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def lex(**payload)
|
96
|
+
@notifications.instrument("lex.graphql", payload) do
|
97
|
+
super
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def validate(**payload)
|
102
|
+
@notifications.instrument("validate.graphql", payload) do
|
103
|
+
super
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def begin_analyze_multiplex(multiplex, analyzers)
|
108
|
+
begin_notifications_event("analyze.graphql", {multiplex: multiplex, analyzers: analyzers})
|
109
|
+
super
|
110
|
+
end
|
111
|
+
|
112
|
+
def end_analyze_multiplex(_multiplex, _analyzers)
|
113
|
+
finish_notifications_event
|
114
|
+
super
|
115
|
+
end
|
116
|
+
|
117
|
+
def execute_multiplex(**payload)
|
118
|
+
@notifications.instrument("execute.graphql", payload) do
|
119
|
+
super
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def begin_execute_field(field, object, arguments, query)
|
124
|
+
begin_notifications_event("execute_field.graphql", {field: field, object: object, arguments: arguments, query: query})
|
125
|
+
super
|
126
|
+
end
|
127
|
+
|
128
|
+
def end_execute_field(_field, _object, _arguments, _query, _result)
|
129
|
+
finish_notifications_event
|
130
|
+
super
|
131
|
+
end
|
132
|
+
|
133
|
+
def dataloader_fiber_yield(source)
|
134
|
+
Fiber[PREVIOUS_EV_KEY] = finish_notifications_event
|
135
|
+
super
|
136
|
+
end
|
137
|
+
|
138
|
+
def dataloader_fiber_resume(source)
|
139
|
+
prev_ev = Fiber[PREVIOUS_EV_KEY]
|
140
|
+
begin_notifications_event(prev_ev.name, prev_ev.payload)
|
141
|
+
super
|
142
|
+
end
|
143
|
+
|
144
|
+
def begin_authorized(type, object, context)
|
145
|
+
begin_notifications_event("authorized.graphql", {type: type, object: object, context: context})
|
146
|
+
super
|
147
|
+
end
|
148
|
+
|
149
|
+
def end_authorized(type, object, context, result)
|
150
|
+
finish_notifications_event
|
151
|
+
super
|
152
|
+
end
|
153
|
+
|
154
|
+
def begin_resolve_type(type, object, context)
|
155
|
+
begin_notifications_event("resolve_type.graphql", {type: type, object: object, context: context})
|
156
|
+
super
|
157
|
+
end
|
158
|
+
|
159
|
+
def end_resolve_type(type, object, context, resolved_type)
|
160
|
+
finish_notifications_event
|
161
|
+
super
|
162
|
+
end
|
163
|
+
|
164
|
+
def begin_dataloader_source(source)
|
165
|
+
begin_notifications_event("dataloader_source.graphql", { source: source })
|
166
|
+
super
|
167
|
+
end
|
168
|
+
|
169
|
+
def end_dataloader_source(source)
|
170
|
+
finish_notifications_event
|
171
|
+
super
|
172
|
+
end
|
173
|
+
|
174
|
+
CURRENT_EV_KEY = :__notifications_graphql_trace_event
|
175
|
+
PREVIOUS_EV_KEY = :__notifications_graphql_trace_previous_event
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
def begin_notifications_event(name, payload)
|
180
|
+
Fiber[CURRENT_EV_KEY] = @notifications.start_event(name, payload)
|
181
|
+
end
|
182
|
+
|
183
|
+
def finish_notifications_event
|
184
|
+
if ev = Fiber[CURRENT_EV_KEY]
|
185
|
+
ev.finish
|
186
|
+
# Use `false` to prevent grabbing an event from a parent fiber
|
187
|
+
Fiber[CURRENT_EV_KEY] = false
|
188
|
+
ev
|
189
|
+
end
|
190
|
+
end
|
47
191
|
end
|
48
192
|
end
|
49
193
|
end
|
@@ -63,6 +63,7 @@ module GraphQL
|
|
63
63
|
# @param active_support_notifications_pattern [String, RegExp, false] A filter for `ActiveSupport::Notifications`, if it's present. Or `false` to skip subscribing.
|
64
64
|
def initialize(active_support_notifications_pattern: nil, save_profile: false, **_rest)
|
65
65
|
super
|
66
|
+
@active_support_notifications_pattern = active_support_notifications_pattern
|
66
67
|
@save_profile = save_profile
|
67
68
|
Fiber[:graphql_flow_stack] = nil
|
68
69
|
@sequence_id = object_id
|
@@ -168,39 +169,38 @@ module GraphQL
|
|
168
169
|
track_uuid: @fields_counter_id,
|
169
170
|
counter_value: count_fields,
|
170
171
|
)
|
171
|
-
|
172
|
-
if defined?(ActiveSupport::Notifications) && active_support_notifications_pattern != false
|
173
|
-
subscribe_to_active_support_notifications(active_support_notifications_pattern)
|
174
|
-
end
|
175
172
|
end
|
176
173
|
|
177
|
-
def
|
178
|
-
|
174
|
+
def execute_multiplex(multiplex:)
|
175
|
+
if defined?(ActiveSupport::Notifications) && @active_support_notifications_pattern != false
|
176
|
+
subscribe_to_active_support_notifications(@active_support_notifications_pattern)
|
177
|
+
end
|
178
|
+
@operation_name = multiplex.queries.map { |q| q.selected_operation_name || "anonymous" }.join(",")
|
179
179
|
@begin_time = Time.now
|
180
180
|
@packets << trace_packet(
|
181
181
|
type: TrackEvent::Type::TYPE_SLICE_BEGIN,
|
182
182
|
track_uuid: fid,
|
183
183
|
name: "Multiplex",
|
184
184
|
debug_annotations: [
|
185
|
-
payload_to_debug("query_string",
|
185
|
+
payload_to_debug("query_string", multiplex.queries.map(&:sanitized_query_string).join("\n\n"))
|
186
186
|
]
|
187
187
|
)
|
188
|
-
super
|
189
|
-
end
|
188
|
+
result = super
|
190
189
|
|
191
|
-
def end_execute_multiplex(m)
|
192
190
|
@packets << trace_packet(
|
193
191
|
type: TrackEvent::Type::TYPE_SLICE_END,
|
194
192
|
track_uuid: fid,
|
195
193
|
)
|
194
|
+
|
195
|
+
result
|
196
|
+
ensure
|
196
197
|
unsubscribe_from_active_support_notifications
|
197
198
|
if @save_profile
|
198
199
|
begin_ts = (@begin_time.to_f * 1000).round
|
199
200
|
end_ts = (Time.now.to_f * 1000).round
|
200
201
|
duration_ms = end_ts - begin_ts
|
201
|
-
|
202
|
+
multiplex.schema.detailed_trace.save_trace(@operation_name, duration_ms, begin_ts, Trace.encode(Trace.new(packet: @packets)))
|
202
203
|
end
|
203
|
-
super
|
204
204
|
end
|
205
205
|
|
206
206
|
def begin_execute_field(field, object, arguments, query)
|
@@ -261,7 +261,7 @@ module GraphQL
|
|
261
261
|
super
|
262
262
|
end
|
263
263
|
|
264
|
-
def
|
264
|
+
def parse(query_string:)
|
265
265
|
@packets << trace_packet(
|
266
266
|
type: TrackEvent::Type::TYPE_SLICE_BEGIN,
|
267
267
|
track_uuid: fid,
|
@@ -269,17 +269,14 @@ module GraphQL
|
|
269
269
|
extra_counter_values: [count_allocations],
|
270
270
|
name: "Parse"
|
271
271
|
)
|
272
|
-
super
|
273
|
-
end
|
274
|
-
|
275
|
-
def end_parse(str)
|
272
|
+
result = super
|
276
273
|
@packets << trace_packet(
|
277
274
|
type: TrackEvent::Type::TYPE_SLICE_END,
|
278
275
|
track_uuid: fid,
|
279
276
|
extra_counter_track_uuids: [@objects_counter_id],
|
280
277
|
extra_counter_values: [count_allocations],
|
281
278
|
)
|
282
|
-
|
279
|
+
result
|
283
280
|
end
|
284
281
|
|
285
282
|
def begin_validate(query, validate)
|