yabeda-graphql 0.1.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,483 @@
1
+ {
2
+ "__inputs": [
3
+ {
4
+ "name": "DS_PROMETHEUS",
5
+ "label": "Prometheus",
6
+ "description": "",
7
+ "type": "datasource",
8
+ "pluginId": "prometheus",
9
+ "pluginName": "Prometheus"
10
+ }
11
+ ],
12
+ "__requires": [
13
+ {
14
+ "type": "grafana",
15
+ "id": "grafana",
16
+ "name": "Grafana",
17
+ "version": "6.6.0"
18
+ },
19
+ {
20
+ "type": "panel",
21
+ "id": "graph",
22
+ "name": "Graph",
23
+ "version": ""
24
+ },
25
+ {
26
+ "type": "datasource",
27
+ "id": "prometheus",
28
+ "name": "Prometheus",
29
+ "version": "1.0.0"
30
+ }
31
+ ],
32
+ "annotations": {
33
+ "list": [
34
+ {
35
+ "builtIn": 1,
36
+ "datasource": "-- Grafana --",
37
+ "enable": true,
38
+ "hide": true,
39
+ "iconColor": "rgba(0, 211, 255, 1)",
40
+ "name": "Annotations & Alerts",
41
+ "type": "dashboard"
42
+ }
43
+ ]
44
+ },
45
+ "description": "Example dashboard for metrics provided by yabeda-graphql gem for monitoring of APIs powered by GraphQL-Ruby.",
46
+ "editable": true,
47
+ "gnetId": null,
48
+ "graphTooltip": 0,
49
+ "id": null,
50
+ "links": [
51
+ {
52
+ "asDropdown": false,
53
+ "icon": "doc",
54
+ "includeVars": false,
55
+ "keepTime": false,
56
+ "tags": [],
57
+ "targetBlank": true,
58
+ "title": "yabeda-graphql",
59
+ "tooltip": "Open yabeda-graphql page on GitHub",
60
+ "type": "link",
61
+ "url": "https://github.com/yabeda-rb/yabeda-graphql/"
62
+ }
63
+ ],
64
+ "panels": [
65
+ {
66
+ "aliasColors": {},
67
+ "bars": false,
68
+ "dashLength": 10,
69
+ "dashes": false,
70
+ "datasource": null,
71
+ "fieldConfig": {
72
+ "defaults": {},
73
+ "overrides": []
74
+ },
75
+ "fill": 1,
76
+ "fillGradient": 0,
77
+ "gridPos": {
78
+ "h": 9,
79
+ "w": 24,
80
+ "x": 0,
81
+ "y": 0
82
+ },
83
+ "hiddenSeries": false,
84
+ "id": 2,
85
+ "legend": {
86
+ "alignAsTable": true,
87
+ "avg": false,
88
+ "current": true,
89
+ "hideEmpty": true,
90
+ "hideZero": true,
91
+ "max": true,
92
+ "min": false,
93
+ "rightSide": true,
94
+ "show": true,
95
+ "sort": "max",
96
+ "sortDesc": true,
97
+ "total": false,
98
+ "values": true
99
+ },
100
+ "lines": true,
101
+ "linewidth": 1,
102
+ "nullPointMode": "null",
103
+ "options": {
104
+ "alertThreshold": true
105
+ },
106
+ "percentage": false,
107
+ "pluginVersion": "7.5.3",
108
+ "pointradius": 2,
109
+ "points": false,
110
+ "renderer": "flot",
111
+ "seriesOverrides": [],
112
+ "spaceLength": 10,
113
+ "stack": false,
114
+ "steppedLine": false,
115
+ "targets": [
116
+ {
117
+ "exemplar": true,
118
+ "expr": "histogram_quantile(0.95, sum(rate(graphql_field_resolve_runtime_seconds_bucket[1m])) by (type,field,le))",
119
+ "interval": "",
120
+ "legendFormat": "{{type}}.{{field}}",
121
+ "queryType": "randomWalk",
122
+ "refId": "A"
123
+ }
124
+ ],
125
+ "thresholds": [],
126
+ "timeFrom": null,
127
+ "timeRegions": [],
128
+ "timeShift": null,
129
+ "title": "Field resolve time (95th percentile)",
130
+ "tooltip": {
131
+ "shared": true,
132
+ "sort": 2,
133
+ "value_type": "individual"
134
+ },
135
+ "type": "graph",
136
+ "xaxis": {
137
+ "buckets": null,
138
+ "mode": "time",
139
+ "name": null,
140
+ "show": true,
141
+ "values": []
142
+ },
143
+ "yaxes": [
144
+ {
145
+ "format": "s",
146
+ "label": null,
147
+ "logBase": 1,
148
+ "max": null,
149
+ "min": null,
150
+ "show": true
151
+ },
152
+ {
153
+ "format": "short",
154
+ "label": null,
155
+ "logBase": 1,
156
+ "max": null,
157
+ "min": null,
158
+ "show": false
159
+ }
160
+ ],
161
+ "yaxis": {
162
+ "align": false,
163
+ "alignLevel": null
164
+ }
165
+ },
166
+ {
167
+ "aliasColors": {},
168
+ "bars": false,
169
+ "dashLength": 10,
170
+ "dashes": false,
171
+ "datasource": null,
172
+ "fieldConfig": {
173
+ "defaults": {},
174
+ "overrides": []
175
+ },
176
+ "fill": 1,
177
+ "fillGradient": 0,
178
+ "gridPos": {
179
+ "h": 8,
180
+ "w": 9,
181
+ "x": 0,
182
+ "y": 9
183
+ },
184
+ "hiddenSeries": false,
185
+ "id": 6,
186
+ "legend": {
187
+ "alignAsTable": true,
188
+ "avg": false,
189
+ "current": true,
190
+ "hideEmpty": true,
191
+ "max": true,
192
+ "min": false,
193
+ "rightSide": true,
194
+ "show": true,
195
+ "sort": "current",
196
+ "sortDesc": true,
197
+ "total": false,
198
+ "values": true
199
+ },
200
+ "lines": true,
201
+ "linewidth": 1,
202
+ "nullPointMode": "null",
203
+ "options": {
204
+ "alertThreshold": true
205
+ },
206
+ "percentage": false,
207
+ "pluginVersion": "7.5.3",
208
+ "pointradius": 2,
209
+ "points": false,
210
+ "renderer": "flot",
211
+ "seriesOverrides": [],
212
+ "spaceLength": 10,
213
+ "stack": false,
214
+ "steppedLine": false,
215
+ "targets": [
216
+ {
217
+ "exemplar": true,
218
+ "expr": "sum(rate(graphql_query_fields_count[1m])) by (name)",
219
+ "interval": "",
220
+ "legendFormat": "{{name}}",
221
+ "refId": "A"
222
+ }
223
+ ],
224
+ "thresholds": [],
225
+ "timeFrom": null,
226
+ "timeRegions": [],
227
+ "timeShift": null,
228
+ "title": "Queries throughput",
229
+ "tooltip": {
230
+ "shared": true,
231
+ "sort": 2,
232
+ "value_type": "individual"
233
+ },
234
+ "type": "graph",
235
+ "xaxis": {
236
+ "buckets": null,
237
+ "mode": "time",
238
+ "name": null,
239
+ "show": true,
240
+ "values": []
241
+ },
242
+ "yaxes": [
243
+ {
244
+ "decimals": 0,
245
+ "format": "reqps",
246
+ "label": null,
247
+ "logBase": 1,
248
+ "max": null,
249
+ "min": "0",
250
+ "show": true
251
+ },
252
+ {
253
+ "format": "short",
254
+ "label": null,
255
+ "logBase": 1,
256
+ "max": null,
257
+ "min": null,
258
+ "show": false
259
+ }
260
+ ],
261
+ "yaxis": {
262
+ "align": false,
263
+ "alignLevel": null
264
+ }
265
+ },
266
+ {
267
+ "aliasColors": {},
268
+ "bars": false,
269
+ "dashLength": 10,
270
+ "dashes": false,
271
+ "datasource": null,
272
+ "fieldConfig": {
273
+ "defaults": {},
274
+ "overrides": []
275
+ },
276
+ "fill": 1,
277
+ "fillGradient": 0,
278
+ "gridPos": {
279
+ "h": 8,
280
+ "w": 9,
281
+ "x": 9,
282
+ "y": 9
283
+ },
284
+ "hiddenSeries": false,
285
+ "id": 8,
286
+ "legend": {
287
+ "alignAsTable": true,
288
+ "avg": false,
289
+ "current": true,
290
+ "hideEmpty": true,
291
+ "max": true,
292
+ "min": false,
293
+ "rightSide": true,
294
+ "show": true,
295
+ "sort": "current",
296
+ "sortDesc": true,
297
+ "total": false,
298
+ "values": true
299
+ },
300
+ "lines": true,
301
+ "linewidth": 1,
302
+ "nullPointMode": "null",
303
+ "options": {
304
+ "alertThreshold": true
305
+ },
306
+ "percentage": false,
307
+ "pluginVersion": "7.5.3",
308
+ "pointradius": 2,
309
+ "points": false,
310
+ "renderer": "flot",
311
+ "seriesOverrides": [],
312
+ "spaceLength": 10,
313
+ "stack": false,
314
+ "steppedLine": false,
315
+ "targets": [
316
+ {
317
+ "exemplar": true,
318
+ "expr": "sum(rate(graphql_mutation_fields_count[1m])) by (name)",
319
+ "interval": "",
320
+ "legendFormat": "{{name}}",
321
+ "refId": "A"
322
+ }
323
+ ],
324
+ "thresholds": [],
325
+ "timeFrom": null,
326
+ "timeRegions": [],
327
+ "timeShift": null,
328
+ "title": "Mutations throughput",
329
+ "tooltip": {
330
+ "shared": true,
331
+ "sort": 2,
332
+ "value_type": "individual"
333
+ },
334
+ "type": "graph",
335
+ "xaxis": {
336
+ "buckets": null,
337
+ "mode": "time",
338
+ "name": null,
339
+ "show": true,
340
+ "values": []
341
+ },
342
+ "yaxes": [
343
+ {
344
+ "decimals": 0,
345
+ "format": "reqps",
346
+ "label": null,
347
+ "logBase": 1,
348
+ "max": null,
349
+ "min": "0",
350
+ "show": true
351
+ },
352
+ {
353
+ "format": "short",
354
+ "label": null,
355
+ "logBase": 1,
356
+ "max": null,
357
+ "min": null,
358
+ "show": false
359
+ }
360
+ ],
361
+ "yaxis": {
362
+ "align": false,
363
+ "alignLevel": null
364
+ }
365
+ },
366
+ {
367
+ "aliasColors": {},
368
+ "bars": false,
369
+ "dashLength": 10,
370
+ "dashes": false,
371
+ "datasource": null,
372
+ "decimals": 0,
373
+ "fieldConfig": {
374
+ "defaults": {},
375
+ "overrides": []
376
+ },
377
+ "fill": 1,
378
+ "fillGradient": 0,
379
+ "gridPos": {
380
+ "h": 8,
381
+ "w": 6,
382
+ "x": 18,
383
+ "y": 9
384
+ },
385
+ "hiddenSeries": false,
386
+ "id": 4,
387
+ "legend": {
388
+ "alignAsTable": true,
389
+ "avg": false,
390
+ "current": false,
391
+ "hideEmpty": true,
392
+ "hideZero": false,
393
+ "max": false,
394
+ "min": false,
395
+ "rightSide": true,
396
+ "show": true,
397
+ "total": false,
398
+ "values": false
399
+ },
400
+ "lines": true,
401
+ "linewidth": 1,
402
+ "nullPointMode": "null",
403
+ "options": {
404
+ "alertThreshold": true
405
+ },
406
+ "percentage": false,
407
+ "pluginVersion": "7.5.3",
408
+ "pointradius": 2,
409
+ "points": false,
410
+ "renderer": "flot",
411
+ "seriesOverrides": [],
412
+ "spaceLength": 10,
413
+ "stack": false,
414
+ "steppedLine": false,
415
+ "targets": [
416
+ {
417
+ "exemplar": true,
418
+ "expr": "sum(rate(graphql_fields_request_count{deprecated=\"true\"}[1m])) by (type, field)",
419
+ "interval": "",
420
+ "legendFormat": "{{type}}.{{field}}",
421
+ "refId": "A"
422
+ }
423
+ ],
424
+ "thresholds": [],
425
+ "timeFrom": null,
426
+ "timeRegions": [],
427
+ "timeShift": null,
428
+ "title": "Deprecated fields usage",
429
+ "tooltip": {
430
+ "shared": true,
431
+ "sort": 0,
432
+ "value_type": "individual"
433
+ },
434
+ "type": "graph",
435
+ "xaxis": {
436
+ "buckets": null,
437
+ "mode": "time",
438
+ "name": null,
439
+ "show": true,
440
+ "values": []
441
+ },
442
+ "yaxes": [
443
+ {
444
+ "decimals": 0,
445
+ "format": "reqps",
446
+ "label": null,
447
+ "logBase": 1,
448
+ "max": null,
449
+ "min": "0",
450
+ "show": true
451
+ },
452
+ {
453
+ "format": "short",
454
+ "label": null,
455
+ "logBase": 1,
456
+ "max": null,
457
+ "min": null,
458
+ "show": false
459
+ }
460
+ ],
461
+ "yaxis": {
462
+ "align": false,
463
+ "alignLevel": null
464
+ }
465
+ }
466
+ ],
467
+ "refresh": "10s",
468
+ "schemaVersion": 27,
469
+ "style": "dark",
470
+ "tags": [],
471
+ "templating": {
472
+ "list": []
473
+ },
474
+ "time": {
475
+ "from": "now-6h",
476
+ "to": "now"
477
+ },
478
+ "timepicker": {},
479
+ "timezone": "",
480
+ "title": "GraphQL API",
481
+ "uid": "yabeda-graphql",
482
+ "version": 1
483
+ }
@@ -0,0 +1,27 @@
1
+ module Yabeda
2
+ module GraphQL
3
+ class Instrumentation
4
+ def before_query(query)
5
+ reset_cache!(query)
6
+ end
7
+
8
+ def after_query(query)
9
+ cache(query).each do |_path, options|
10
+ Yabeda.graphql.field_resolve_runtime.measure(options[:tags], options[:duration])
11
+ Yabeda.graphql.fields_request_count.increment(options[:tags])
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def cache(query)
18
+ query.context.namespace(Yabeda::GraphQL)[:field_call_cache]
19
+ end
20
+
21
+ def reset_cache!(query)
22
+ query.context.namespace(Yabeda::GraphQL)[:field_call_cache] =
23
+ Hash.new { |h,k| h[k] = { tags: {}, duration: 0.0 } }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -26,10 +26,10 @@ module Yabeda
26
26
  when "execute_field", "execute_field_lazy"
27
27
  field, path, query = extract_field_trace_data(data)
28
28
 
29
- return result if key == "execute_field" && query.schema.lazy?(result)
30
-
31
29
  tags = extract_field_tags(field)
32
30
  if path.length == 1
31
+ return result if key == "execute_field" && query.schema.lazy?(result)
32
+
33
33
  if query.query?
34
34
  instrument_query_execution(tags)
35
35
  elsif query.mutation?
@@ -38,7 +38,7 @@ module Yabeda
38
38
  # Not implemented yet
39
39
  end
40
40
  else
41
- instrument_field_execution(tags, duration)
41
+ instrument_field_execution(query, path, tags, duration)
42
42
  end
43
43
  end
44
44
 
@@ -63,9 +63,9 @@ module Yabeda
63
63
  }
64
64
  end
65
65
 
66
- def instrument_field_execution(tags, duration)
67
- Yabeda.graphql.field_resolve_runtime.measure(tags, duration)
68
- Yabeda.graphql.fields_request_count.increment(tags)
66
+ def instrument_field_execution(query, path, tags, duration)
67
+ cache(query)[path][:tags] = tags
68
+ cache(query)[path][:duration] += duration
69
69
  end
70
70
 
71
71
  def instrument_mutation_execution(tags)
@@ -78,6 +78,10 @@ module Yabeda
78
78
  Yabeda.graphql.query_fields_count.increment(tags)
79
79
  end
80
80
 
81
+ def cache(query)
82
+ query.context.namespace(Yabeda::GraphQL)[:field_call_cache]
83
+ end
84
+
81
85
  def platform_field_key(type, field)
82
86
  "#{type.graphql_name}.#{field.graphql_name}"
83
87
  end
@@ -1,5 +1,5 @@
1
1
  module Yabeda
2
2
  module GraphQL
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.2"
4
4
  end
5
5
  end
@@ -1,13 +1,14 @@
1
1
  require "yabeda"
2
2
  require "yabeda/graphql/version"
3
3
  require "yabeda/graphql/tracing"
4
+ require "yabeda/graphql/instrumentation"
4
5
 
5
6
  module Yabeda
6
7
  module GraphQL
7
8
  class Error < StandardError; end
8
9
 
9
10
  REQUEST_BUCKETS = [
10
- 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10,
11
+ 0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10,
11
12
  ].freeze
12
13
 
13
14
  Yabeda.configure do
@@ -27,5 +28,10 @@ module Yabeda
27
28
  counter :mutation_fields_count, comment: "A counter for mutation root fields",
28
29
  tags: %i[name deprecated]
29
30
  end
31
+
32
+ def self.use(schema)
33
+ schema.instrument(:query, Instrumentation.new)
34
+ schema.use Tracing, trace_scalars: true
35
+ end
30
36
  end
31
37
  end
Binary file
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.require_paths = ["lib"]
25
25
 
26
26
  spec.add_runtime_dependency "yabeda", "~> 0.2"
27
- spec.add_runtime_dependency "graphql", "~> 1.9"
27
+ spec.add_runtime_dependency "graphql", ">= 1.9", "< 3"
28
28
 
29
29
  spec.add_development_dependency "bundler"
30
30
  spec.add_development_dependency "rake", "~> 13.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yabeda-graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Novikov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-17 00:00:00.000000000 Z
11
+ date: 2022-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yabeda
@@ -28,16 +28,22 @@ dependencies:
28
28
  name: graphql
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.9'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '3'
34
37
  type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
- - - "~>"
41
+ - - ">="
39
42
  - !ruby/object:Gem::Version
40
43
  version: '1.9'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '3'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: bundler
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -102,10 +108,12 @@ executables: []
102
108
  extensions: []
103
109
  extra_rdoc_files: []
104
110
  files:
111
+ - ".github/workflows/build-release.yml"
112
+ - ".github/workflows/test.yml"
105
113
  - ".gitignore"
106
114
  - ".rspec"
107
- - ".travis.yml"
108
115
  - Appraisals
116
+ - CHANGELOG.md
109
117
  - Gemfile
110
118
  - Gemfile.lock
111
119
  - LICENSE.txt
@@ -116,11 +124,22 @@ files:
116
124
  - gemfiles/.bundle/config
117
125
  - gemfiles/graphql_1.10.gemfile
118
126
  - gemfiles/graphql_1.10.gemfile.lock
127
+ - gemfiles/graphql_1.11.gemfile
128
+ - gemfiles/graphql_1.11.gemfile.lock
129
+ - gemfiles/graphql_1.12.gemfile
130
+ - gemfiles/graphql_1.12.gemfile.lock
131
+ - gemfiles/graphql_1.13.gemfile
132
+ - gemfiles/graphql_1.13.gemfile.lock
119
133
  - gemfiles/graphql_1.9.gemfile
120
134
  - gemfiles/graphql_1.9.gemfile.lock
135
+ - gemfiles/graphql_2.0.gemfile
136
+ - gemfiles/graphql_2.0.gemfile.lock
137
+ - grafana-dashboard.json
121
138
  - lib/yabeda/graphql.rb
139
+ - lib/yabeda/graphql/instrumentation.rb
122
140
  - lib/yabeda/graphql/tracing.rb
123
141
  - lib/yabeda/graphql/version.rb
142
+ - yabeda-graphql-logo.png
124
143
  - yabeda-graphql.gemspec
125
144
  homepage: http://github.com/yabeda-rb/yabeda-graphql
126
145
  licenses:
@@ -142,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
161
  - !ruby/object:Gem::Version
143
162
  version: '0'
144
163
  requirements: []
145
- rubygems_version: 3.1.2
164
+ rubygems_version: 3.1.6
146
165
  signing_key:
147
166
  specification_version: 4
148
167
  summary: Collects metrics to monitor execution of your GraphQL queries
data/.travis.yml DELETED
@@ -1,12 +0,0 @@
1
- ---
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.7.0
6
- gemfile:
7
- - gemfiles/graphql_1.10.gemfile
8
- - gemfiles/graphql_1.9.gemfile
9
- env:
10
- - GRAPHQL_RUBY_INTERPRETER=yes
11
- - GRAPHQL_RUBY_INTERPRETER=no
12
- before_install: gem install bundler -v 2.1.4