graphql 2.4.10 → 2.4.12
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 +4 -4
- data/lib/graphql/analysis/visitor.rb +35 -40
- data/lib/graphql/analysis.rb +12 -9
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
- data/lib/graphql/dashboard/statics/dashboard.css +3 -0
- data/lib/graphql/dashboard/statics/dashboard.js +78 -0
- data/lib/graphql/dashboard/statics/header-icon.png +0 -0
- data/lib/graphql/dashboard/statics/icon.png +0 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/traces/index.html.erb +63 -0
- data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +60 -0
- data/lib/graphql/dashboard.rb +142 -0
- data/lib/graphql/execution/interpreter/runtime.rb +1 -1
- data/lib/graphql/invalid_name_error.rb +1 -1
- data/lib/graphql/invalid_null_error.rb +5 -15
- data/lib/graphql/language/lexer.rb +7 -3
- data/lib/graphql/language/parser.rb +1 -1
- data/lib/graphql/schema/build_from_definition.rb +0 -1
- data/lib/graphql/schema/enum.rb +16 -1
- data/lib/graphql/schema/input_object.rb +1 -1
- data/lib/graphql/schema/loader.rb +0 -1
- data/lib/graphql/schema/member/has_dataloader.rb +4 -0
- data/lib/graphql/schema/resolver.rb +5 -1
- data/lib/graphql/schema.rb +51 -9
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -1
- data/lib/graphql/tracing/active_support_notifications_trace.rb +6 -2
- data/lib/graphql/tracing/appoptics_trace.rb +2 -0
- data/lib/graphql/tracing/appsignal_trace.rb +6 -0
- data/lib/graphql/tracing/data_dog_trace.rb +5 -0
- data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
- data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
- data/lib/graphql/tracing/detailed_trace.rb +93 -0
- data/lib/graphql/tracing/new_relic_trace.rb +47 -23
- data/lib/graphql/tracing/perfetto_trace.rb +13 -2
- data/lib/graphql/tracing/prometheus_trace.rb +22 -0
- data/lib/graphql/tracing/scout_trace.rb +6 -0
- data/lib/graphql/tracing/sentry_trace.rb +5 -0
- data/lib/graphql/tracing/statsd_trace.rb +9 -0
- data/lib/graphql/tracing.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +3 -0
- metadata +15 -2
@@ -4,16 +4,30 @@ require "graphql/tracing/platform_trace"
|
|
4
4
|
|
5
5
|
module GraphQL
|
6
6
|
module Tracing
|
7
|
+
# A tracer for reporting GraphQL-Ruby time to New Relic
|
8
|
+
#
|
9
|
+
# @example Installing the tracer
|
10
|
+
# class MySchema < GraphQL::Schema
|
11
|
+
# trace_with GraphQL::Tracing::NewRelicTrace
|
12
|
+
#
|
13
|
+
# # Optional, use the operation name to set the new relic transaction name:
|
14
|
+
# # trace_with GraphQL::Tracing::NewRelicTrace, set_transaction_name: true
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# @example Installing without trace events for `authorized?` or `resolve_type` calls
|
18
|
+
# trace_with GraphQL::Tracing::NewRelicTrace, trace_authorized: false, trace_resolve_type: false
|
7
19
|
module NewRelicTrace
|
8
20
|
# @param set_transaction_name [Boolean] If true, the GraphQL operation name will be used as the transaction name.
|
9
21
|
# This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
|
10
22
|
# It can also be specified per-query with `context[:set_new_relic_transaction_name]`.
|
11
23
|
# @param trace_authorized [Boolean] If `false`, skip tracing `authorized?` calls
|
12
24
|
# @param trace_resolve_type [Boolean] If `false`, skip tracing `resolve_type?` calls
|
13
|
-
|
25
|
+
# @param trace_scalars [Boolean] If `true`, Enum and Scalar fields will be traced by default
|
26
|
+
def initialize(set_transaction_name: false, trace_authorized: true, trace_resolve_type: true, trace_scalars: false, **_rest)
|
14
27
|
@set_transaction_name = set_transaction_name
|
15
28
|
@trace_authorized = trace_authorized
|
16
29
|
@trace_resolve_type = trace_resolve_type
|
30
|
+
@trace_scalars = trace_scalars
|
17
31
|
@nr_field_names = Hash.new do |h, field|
|
18
32
|
h[field] = "GraphQL/#{field.owner.graphql_name}/#{field.graphql_name}"
|
19
33
|
end.compare_by_identity
|
@@ -80,78 +94,88 @@ module GraphQL
|
|
80
94
|
end
|
81
95
|
|
82
96
|
def begin_execute_field(field, object, arguments, query)
|
83
|
-
|
97
|
+
return_type = field.type.unwrap
|
98
|
+
trace_field = if return_type.kind.scalar? || return_type.kind.enum?
|
99
|
+
(field.trace.nil? && @trace_scalars) || field.trace
|
100
|
+
else
|
101
|
+
true
|
102
|
+
end
|
103
|
+
if trace_field
|
104
|
+
start_segment(partial_name: @nr_field_names[field], category: :web)
|
105
|
+
end
|
84
106
|
super
|
85
107
|
end
|
86
108
|
|
87
109
|
def end_execute_field(field, objects, arguments, query, result)
|
88
|
-
|
110
|
+
finish_segment
|
89
111
|
super
|
90
112
|
end
|
91
113
|
|
92
114
|
def begin_authorized(type, obj, ctx)
|
93
115
|
if @trace_authorized
|
94
|
-
|
116
|
+
start_segment(partial_name: @nr_authorized_names[type], category: :web)
|
95
117
|
end
|
96
118
|
super
|
97
119
|
end
|
98
120
|
|
99
121
|
def end_authorized(type, obj, ctx, is_authed)
|
100
122
|
if @trace_authorized
|
101
|
-
|
123
|
+
finish_segment
|
102
124
|
end
|
103
125
|
super
|
104
126
|
end
|
105
127
|
|
106
128
|
def begin_resolve_type(type, value, context)
|
107
129
|
if @trace_resolve_type
|
108
|
-
|
130
|
+
start_segment(partial_name: @nr_resolve_type_names[type], category: :web)
|
109
131
|
end
|
110
132
|
super
|
111
133
|
end
|
112
134
|
|
113
135
|
def end_resolve_type(type, value, context, resolved_type)
|
114
136
|
if @trace_resolve_type
|
115
|
-
|
137
|
+
finish_segment
|
116
138
|
end
|
117
139
|
super
|
118
140
|
end
|
119
141
|
|
120
|
-
def begin_dataloader(dl)
|
121
|
-
super
|
122
|
-
end
|
123
|
-
|
124
|
-
def end_dataloader(dl)
|
125
|
-
super
|
126
|
-
end
|
127
|
-
|
128
142
|
def begin_dataloader_source(source)
|
129
|
-
|
143
|
+
start_segment(partial_name: @nr_source_names[source], category: :web)
|
130
144
|
super
|
131
145
|
end
|
132
146
|
|
133
147
|
def end_dataloader_source(source)
|
134
|
-
|
148
|
+
finish_segment
|
135
149
|
super
|
136
150
|
end
|
137
151
|
|
138
152
|
def dataloader_fiber_yield(source)
|
139
|
-
|
140
|
-
|
153
|
+
prev_segment = finish_segment
|
154
|
+
Fiber[:graphql_nr_previous_segment] = prev_segment
|
141
155
|
super
|
142
156
|
end
|
143
157
|
|
144
158
|
def dataloader_fiber_resume(source)
|
145
|
-
prev_segment =
|
159
|
+
prev_segment = Fiber[:graphql_nr_previous_segment]
|
160
|
+
Fiber[:graphql_nr_previous_segment] = nil
|
146
161
|
seg_partial_name = prev_segment.name.sub(/^.*(GraphQL.*)$/, '\1')
|
147
|
-
|
162
|
+
start_segment(partial_name: seg_partial_name, category: :web)
|
148
163
|
super
|
149
164
|
end
|
150
165
|
|
151
166
|
private
|
152
167
|
|
153
|
-
def
|
154
|
-
Fiber[:
|
168
|
+
def start_segment(...)
|
169
|
+
Fiber[:graphql_nr_segment] = NewRelic::Agent::Tracer.start_transaction_or_segment(...)
|
170
|
+
end
|
171
|
+
|
172
|
+
def finish_segment
|
173
|
+
segment = Fiber[:graphql_nr_segment]
|
174
|
+
if segment
|
175
|
+
segment.finish
|
176
|
+
Fiber[:graphql_nr_segment] = nil
|
177
|
+
segment
|
178
|
+
end
|
155
179
|
end
|
156
180
|
|
157
181
|
def transaction_name(query)
|
@@ -61,8 +61,10 @@ module GraphQL
|
|
61
61
|
DA_STR_VAL_NIL_IID = 14
|
62
62
|
|
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
|
-
def initialize(active_support_notifications_pattern: nil, **_rest)
|
64
|
+
def initialize(active_support_notifications_pattern: nil, save_profile: false, **_rest)
|
65
65
|
super
|
66
|
+
@save_profile = save_profile
|
67
|
+
Fiber[:graphql_flow_stack] = nil
|
66
68
|
@sequence_id = object_id
|
67
69
|
@pid = Process.pid
|
68
70
|
@flow_ids = Hash.new { |h, source_inst| h[source_inst] = [] }.compare_by_identity
|
@@ -108,6 +110,7 @@ module GraphQL
|
|
108
110
|
@fibers_counter_id = :fibers_counter.object_id
|
109
111
|
@fields_counter_id = :fields_counter.object_id
|
110
112
|
@begin_validate = nil
|
113
|
+
@begin_time = nil
|
111
114
|
@packets = []
|
112
115
|
@packets << TracePacket.new(
|
113
116
|
track_descriptor: TrackDescriptor.new(
|
@@ -172,6 +175,8 @@ module GraphQL
|
|
172
175
|
end
|
173
176
|
|
174
177
|
def begin_execute_multiplex(m)
|
178
|
+
@operation_name = m.queries.map { |q| q.selected_operation_name || "anonymous" }.join(",")
|
179
|
+
@begin_time = Time.now
|
175
180
|
@packets << trace_packet(
|
176
181
|
type: TrackEvent::Type::TYPE_SLICE_BEGIN,
|
177
182
|
track_uuid: fid,
|
@@ -189,6 +194,12 @@ module GraphQL
|
|
189
194
|
track_uuid: fid,
|
190
195
|
)
|
191
196
|
unsubscribe_from_active_support_notifications
|
197
|
+
if @save_profile
|
198
|
+
begin_ts = (@begin_time.to_f * 1000).round
|
199
|
+
end_ts = (Time.now.to_f * 1000).round
|
200
|
+
duration_ms = end_ts - begin_ts
|
201
|
+
m.schema.detailed_trace.save_trace(@operation_name, duration_ms, begin_ts, Trace.encode(Trace.new(packet: @packets)))
|
202
|
+
end
|
192
203
|
super
|
193
204
|
end
|
194
205
|
|
@@ -297,7 +308,7 @@ module GraphQL
|
|
297
308
|
{
|
298
309
|
debug_annotations: [
|
299
310
|
@begin_validate.track_event.debug_annotations.first,
|
300
|
-
payload_to_debug("valid?",
|
311
|
+
payload_to_debug("valid?", validation_errors.empty?)
|
301
312
|
]
|
302
313
|
}
|
303
314
|
)
|
@@ -4,6 +4,28 @@ require "graphql/tracing/platform_trace"
|
|
4
4
|
|
5
5
|
module GraphQL
|
6
6
|
module Tracing
|
7
|
+
# A tracer for reporting GraphQL-Ruby times to Prometheus.
|
8
|
+
#
|
9
|
+
# The PrometheusExporter server must be run with a custom type collector that extends `GraphQL::Tracing::PrometheusTracing::GraphQLCollector`.
|
10
|
+
#
|
11
|
+
# @example Adding this trace to your schema
|
12
|
+
# require 'prometheus_exporter/client'
|
13
|
+
#
|
14
|
+
# class MySchema < GraphQL::Schema
|
15
|
+
# trace_with GraphQL::Tracing::PrometheusTrace
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# @example Running a custom type collector
|
19
|
+
# # lib/graphql_collector.rb
|
20
|
+
# if defined?(PrometheusExporter::Server)
|
21
|
+
# require 'graphql/tracing'
|
22
|
+
#
|
23
|
+
# class GraphQLCollector < GraphQL::Tracing::PrometheusTrace::GraphQLCollector
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # Then run:
|
28
|
+
# # bundle exec prometheus_exporter -a lib/graphql_collector.rb
|
7
29
|
module PrometheusTrace
|
8
30
|
if defined?(PrometheusExporter::Server)
|
9
31
|
autoload :GraphQLCollector, "graphql/tracing/prometheus_trace/graphql_collector"
|
@@ -4,6 +4,12 @@ require "graphql/tracing/platform_trace"
|
|
4
4
|
|
5
5
|
module GraphQL
|
6
6
|
module Tracing
|
7
|
+
# A tracer for sending GraphQL-Ruby times to Scout
|
8
|
+
#
|
9
|
+
# @example Adding this tracer to your schema
|
10
|
+
# class MySchema < GraphQL::Schema
|
11
|
+
# trace_with GraphQL::Tracing::ScoutTrace
|
12
|
+
# end
|
7
13
|
module ScoutTrace
|
8
14
|
include PlatformTrace
|
9
15
|
|
@@ -4,6 +4,11 @@ require "graphql/tracing/platform_trace"
|
|
4
4
|
|
5
5
|
module GraphQL
|
6
6
|
module Tracing
|
7
|
+
# A tracer for reporting GraphQL-Ruby times to Sentry.
|
8
|
+
# @example Installing the tracer
|
9
|
+
# class MySchema < GraphQL::Schema
|
10
|
+
# trace_with GraphQL::Tracing::SentryTrace
|
11
|
+
# end
|
7
12
|
module SentryTrace
|
8
13
|
include PlatformTrace
|
9
14
|
|
@@ -4,6 +4,15 @@ require "graphql/tracing/platform_trace"
|
|
4
4
|
|
5
5
|
module GraphQL
|
6
6
|
module Tracing
|
7
|
+
# A tracer for reporting GraphQL-Ruby times to Statsd.
|
8
|
+
# Passing any Statsd client that implements `.time(name) { ... }` will work.
|
9
|
+
#
|
10
|
+
# @example Installing this tracer
|
11
|
+
# # eg:
|
12
|
+
# # $statsd = Statsd.new 'localhost', 9125
|
13
|
+
# class MySchema < GraphQL::Schema
|
14
|
+
# use GraphQL::Tracing::StatsdTrace, statsd: $statsd
|
15
|
+
# end
|
7
16
|
module StatsdTrace
|
8
17
|
include PlatformTrace
|
9
18
|
|
data/lib/graphql/tracing.rb
CHANGED
@@ -32,6 +32,7 @@ module GraphQL
|
|
32
32
|
autoload :StatsdTrace, "graphql/tracing/statsd_trace"
|
33
33
|
autoload :PrometheusTrace, "graphql/tracing/prometheus_trace"
|
34
34
|
autoload :PerfettoTrace, "graphql/tracing/perfetto_trace"
|
35
|
+
autoload :DetailedTrace, "graphql/tracing/detailed_trace"
|
35
36
|
|
36
37
|
# Objects may include traceable to gain a `.trace(...)` method.
|
37
38
|
# The object must have a `@tracers` ivar of type `Array<<#trace(k, d, &b)>>`.
|
data/lib/graphql/version.rb
CHANGED
data/lib/graphql.rb
CHANGED
@@ -125,6 +125,9 @@ This is probably a bug in GraphQL-Ruby, please report this error on GitHub: http
|
|
125
125
|
autoload :LoadApplicationObjectFailedError, "graphql/load_application_object_failed_error"
|
126
126
|
autoload :Testing, "graphql/testing"
|
127
127
|
autoload :Current, "graphql/current"
|
128
|
+
if defined?(::Rails::Engine)
|
129
|
+
autoload :Dashboard, 'graphql/dashboard'
|
130
|
+
end
|
128
131
|
end
|
129
132
|
|
130
133
|
require "graphql/version"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.
|
4
|
+
version: 2.4.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-03-11 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: base64
|
@@ -459,6 +459,16 @@ files:
|
|
459
459
|
- lib/graphql/backtrace/traced_error.rb
|
460
460
|
- lib/graphql/coercion_error.rb
|
461
461
|
- lib/graphql/current.rb
|
462
|
+
- lib/graphql/dashboard.rb
|
463
|
+
- lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css
|
464
|
+
- lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js
|
465
|
+
- lib/graphql/dashboard/statics/dashboard.css
|
466
|
+
- lib/graphql/dashboard/statics/dashboard.js
|
467
|
+
- lib/graphql/dashboard/statics/header-icon.png
|
468
|
+
- lib/graphql/dashboard/statics/icon.png
|
469
|
+
- lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb
|
470
|
+
- lib/graphql/dashboard/views/graphql/dashboard/traces/index.html.erb
|
471
|
+
- lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb
|
462
472
|
- lib/graphql/dataloader.rb
|
463
473
|
- lib/graphql/dataloader/active_record_association_source.rb
|
464
474
|
- lib/graphql/dataloader/active_record_source.rb
|
@@ -721,6 +731,9 @@ files:
|
|
721
731
|
- lib/graphql/tracing/call_legacy_tracers.rb
|
722
732
|
- lib/graphql/tracing/data_dog_trace.rb
|
723
733
|
- lib/graphql/tracing/data_dog_tracing.rb
|
734
|
+
- lib/graphql/tracing/detailed_trace.rb
|
735
|
+
- lib/graphql/tracing/detailed_trace/memory_backend.rb
|
736
|
+
- lib/graphql/tracing/detailed_trace/redis_backend.rb
|
724
737
|
- lib/graphql/tracing/legacy_hooks_trace.rb
|
725
738
|
- lib/graphql/tracing/legacy_trace.rb
|
726
739
|
- lib/graphql/tracing/new_relic_trace.rb
|