graphql-metrics 4.0.2 → 4.0.3
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/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +7 -4
- data/lib/graphql/metrics.rb +2 -0
- data/lib/graphql/metrics/analyzer.rb +1 -1
- data/lib/graphql/metrics/instrumentation.rb +2 -0
- data/lib/graphql/metrics/tracer.rb +53 -22
- data/lib/graphql/metrics/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37973ad72745f698107a0877761b9b6fd8f065da661f044eec8b59cfe8c8be0b
|
4
|
+
data.tar.gz: 06d1bc48ac6640e982ef7c258306e99b0fde8808c8f57eddf1e0ef95baceabfa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25a8e51676bd6d62e9c6dd039a0b23388c7f60fbcb994ccaa171d7e1956dfb0cb0fb8d4fbb826468357bcd4cbc96a118659cde38f81f4c6303870c4b2dc7516c
|
7
|
+
data.tar.gz: a2a47c0f7a88c5f9e01e5be0bf464e3c6ff4b3a4ebf88d3c221c18e9ee6d1f65d8cf4dfe9492599d4cd386b0fa3efe33ba2887d94d2512fdcdcd6160b1743aea
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
4.0.3
|
2
|
+
-----
|
3
|
+
- [32](https://github.com/Shopify/graphql-metrics/pull/32) Split validate and analyze_query tracer events (encompasses #30).
|
4
|
+
- [30](https://github.com/Shopify/graphql-metrics/pull/30) Handle queries that have already been parsed (thank you @jturkel).
|
5
|
+
|
1
6
|
4.0.2
|
2
7
|
-----
|
3
8
|
- [25](https://github.com/Shopify/graphql-metrics/pull/25) Safely handle interrupted runtime metrics.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -54,8 +54,8 @@ parsing and validation runtime metrics will not be added to the `metrics` hash.
|
|
54
54
|
### Define your own analyzer subclass
|
55
55
|
|
56
56
|
```ruby
|
57
|
-
class
|
58
|
-
ANALYZER_NAMESPACE = :
|
57
|
+
class SimpleAnalyzer < GraphQL::Metrics::Analyzer
|
58
|
+
ANALYZER_NAMESPACE = :simple_analyzer_namespace
|
59
59
|
|
60
60
|
def initialize(query_or_multiplex)
|
61
61
|
super
|
@@ -78,6 +78,8 @@ parsing and validation runtime metrics will not be added to the `metrics` hash.
|
|
78
78
|
# parsing_duration: 0.0008190000080503523,
|
79
79
|
# validation_start_time_offset: 0.0030819999519735575,
|
80
80
|
# validation_duration: 0.01704599999357015,
|
81
|
+
# analysis_start_time_offset: 0.0010339999571442604,
|
82
|
+
# analysis_duration: 0.0008190000080503523,
|
81
83
|
# }
|
82
84
|
#
|
83
85
|
# You can use these metrics to track high-level query performance, along with any other details you wish to
|
@@ -221,10 +223,11 @@ your application as intended, here's a breakdown of the order of execution of th
|
|
221
223
|
|
222
224
|
When used as instrumentation, an analyzer and tracing, the order of execution is:
|
223
225
|
|
224
|
-
* Tracer.
|
226
|
+
* Tracer.setup_tracing
|
225
227
|
* Tracer.capture_parsing_time
|
226
228
|
* Instrumentation.before_query (context setup)
|
227
|
-
* Tracer.capture_validation_time
|
229
|
+
* Tracer.capture_validation_time
|
230
|
+
* Tracer.capture_analysis_time
|
228
231
|
* Analyzer#initialize (bit more context setup, instance vars setup)
|
229
232
|
* Analyzer#result
|
230
233
|
* Tracer.trace_field (n times)
|
data/lib/graphql/metrics.rb
CHANGED
@@ -28,6 +28,8 @@ module GraphQL
|
|
28
28
|
PARSING_DURATION = :parsing_duration
|
29
29
|
VALIDATION_START_TIME_OFFSET = :validation_start_time_offset
|
30
30
|
VALIDATION_DURATION = :validation_duration
|
31
|
+
ANALYSIS_START_TIME_OFFSET = :analysis_start_time_offset
|
32
|
+
ANALYSIS_DURATION = :analysis_duration
|
31
33
|
INLINE_FIELD_TIMINGS = :inline_field_timings
|
32
34
|
LAZY_FIELD_TIMINGS = :lazy_field_timings
|
33
35
|
|
@@ -50,7 +50,7 @@ module GraphQL
|
|
50
50
|
field_name: node.name,
|
51
51
|
return_type_name: visitor.type_definition.graphql_name,
|
52
52
|
parent_type_name: visitor.parent_type_definition.graphql_name,
|
53
|
-
deprecated: visitor.field_definition.deprecation_reason.
|
53
|
+
deprecated: !visitor.field_definition.deprecation_reason.nil?,
|
54
54
|
path: visitor.response_path,
|
55
55
|
}
|
56
56
|
|
@@ -45,6 +45,8 @@ module GraphQL
|
|
45
45
|
parsing_duration: ns[GraphQL::Metrics::PARSING_DURATION],
|
46
46
|
validation_start_time_offset: ns[GraphQL::Metrics::VALIDATION_START_TIME_OFFSET],
|
47
47
|
validation_duration: ns[GraphQL::Metrics::VALIDATION_DURATION],
|
48
|
+
analysis_start_time_offset: ns[GraphQL::Metrics::ANALYSIS_START_TIME_OFFSET],
|
49
|
+
analysis_duration: ns[GraphQL::Metrics::ANALYSIS_DURATION],
|
48
50
|
}
|
49
51
|
|
50
52
|
analyzer.extract_fields
|
@@ -4,9 +4,10 @@ module GraphQL
|
|
4
4
|
module Metrics
|
5
5
|
class Tracer
|
6
6
|
# NOTE: These constants come from the graphql ruby gem.
|
7
|
-
|
7
|
+
GRAPHQL_GEM_EXECUTE_MULTIPLEX_KEY = 'execute_multiplex'
|
8
8
|
GRAPHQL_GEM_PARSING_KEY = 'parse'
|
9
|
-
|
9
|
+
GRAPHQL_GEM_VALIDATION_KEY = 'validate'
|
10
|
+
GRAPHQL_GEM_ANALYZE_KEY = 'analyze_query'
|
10
11
|
GRAPHQL_GEM_TRACING_FIELD_KEYS = [
|
11
12
|
GRAPHQL_GEM_TRACING_FIELD_KEY = 'execute_field',
|
12
13
|
GRAPHQL_GEM_TRACING_LAZY_FIELD_KEY = 'execute_field_lazy'
|
@@ -22,21 +23,21 @@ module GraphQL
|
|
22
23
|
# NOTE: Not all tracing events are handled here, but those that are are handled in this case statement in
|
23
24
|
# chronological order.
|
24
25
|
case key
|
25
|
-
when
|
26
|
-
return
|
26
|
+
when GRAPHQL_GEM_EXECUTE_MULTIPLEX_KEY
|
27
|
+
return setup_tracing(&block)
|
27
28
|
when GRAPHQL_GEM_PARSING_KEY
|
28
29
|
return capture_parsing_time(&block)
|
29
|
-
when
|
30
|
+
when GRAPHQL_GEM_VALIDATION_KEY
|
30
31
|
context = possible_context
|
31
|
-
|
32
|
-
return yield unless context.query.valid?
|
33
32
|
return capture_validation_time(context, &block)
|
33
|
+
when GRAPHQL_GEM_ANALYZE_KEY
|
34
|
+
context = possible_context
|
35
|
+
return capture_analysis_time(context, &block)
|
36
|
+
|
34
37
|
when *GRAPHQL_GEM_TRACING_FIELD_KEYS
|
35
38
|
return yield if data[:query].context[SKIP_FIELD_AND_ARGUMENT_METRICS]
|
36
39
|
return yield unless GraphQL::Metrics.timings_capture_enabled?(data[:query].context)
|
37
40
|
|
38
|
-
pre_context = nil
|
39
|
-
|
40
41
|
context_key = case key
|
41
42
|
when GRAPHQL_GEM_TRACING_FIELD_KEY
|
42
43
|
GraphQL::Metrics::INLINE_FIELD_TIMINGS
|
@@ -52,15 +53,28 @@ module GraphQL
|
|
52
53
|
|
53
54
|
private
|
54
55
|
|
56
|
+
PreContext = Struct.new(
|
57
|
+
:query_start_time,
|
58
|
+
:query_start_time_monotonic,
|
59
|
+
:parsing_start_time_offset,
|
60
|
+
:parsing_duration
|
61
|
+
) do
|
62
|
+
def reset_parsing_timings
|
63
|
+
self[:parsing_start_time_offset] = nil
|
64
|
+
self[:parsing_duration] = nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
55
68
|
def pre_context
|
56
69
|
# NOTE: This is used to store timings from lexing, parsing, validation, before we have a context to store
|
57
70
|
# values in. Uses thread-safe Concurrent::ThreadLocalVar to store a set of values per thread.
|
58
|
-
@pre_context ||= Concurrent::ThreadLocalVar.new(
|
71
|
+
@pre_context ||= Concurrent::ThreadLocalVar.new(PreContext.new)
|
72
|
+
@pre_context.value
|
59
73
|
end
|
60
74
|
|
61
|
-
def
|
62
|
-
pre_context.
|
63
|
-
pre_context.
|
75
|
+
def setup_tracing
|
76
|
+
pre_context.query_start_time = GraphQL::Metrics.current_time
|
77
|
+
pre_context.query_start_time_monotonic = GraphQL::Metrics.current_time_monotonic
|
64
78
|
|
65
79
|
yield
|
66
80
|
end
|
@@ -68,24 +82,41 @@ module GraphQL
|
|
68
82
|
def capture_parsing_time
|
69
83
|
timed_result = GraphQL::Metrics.time { yield }
|
70
84
|
|
71
|
-
pre_context.
|
72
|
-
pre_context.
|
85
|
+
pre_context.parsing_start_time_offset = timed_result.start_time
|
86
|
+
pre_context.parsing_duration = timed_result.duration
|
73
87
|
|
74
88
|
timed_result.result
|
75
89
|
end
|
76
90
|
|
77
91
|
def capture_validation_time(context)
|
78
|
-
|
92
|
+
if pre_context.parsing_duration.nil?
|
93
|
+
pre_context.parsing_start_time_offset = 0
|
94
|
+
pre_context.parsing_duration = 0
|
95
|
+
end
|
96
|
+
|
97
|
+
timed_result = GraphQL::Metrics.time(pre_context.query_start_time_monotonic) { yield }
|
79
98
|
|
80
99
|
ns = context.namespace(CONTEXT_NAMESPACE)
|
81
|
-
previous_validation_duration = ns[GraphQL::Metrics::VALIDATION_DURATION] || 0
|
82
100
|
|
83
|
-
ns[QUERY_START_TIME] = pre_context.
|
84
|
-
ns[QUERY_START_TIME_MONOTONIC] = pre_context.
|
85
|
-
ns[PARSING_START_TIME_OFFSET] = pre_context.
|
86
|
-
ns[PARSING_DURATION] = pre_context.
|
101
|
+
ns[QUERY_START_TIME] = pre_context.query_start_time
|
102
|
+
ns[QUERY_START_TIME_MONOTONIC] = pre_context.query_start_time_monotonic
|
103
|
+
ns[PARSING_START_TIME_OFFSET] = pre_context.parsing_start_time_offset
|
104
|
+
ns[PARSING_DURATION] = pre_context.parsing_duration
|
87
105
|
ns[VALIDATION_START_TIME_OFFSET] = timed_result.time_since_offset
|
88
|
-
ns[VALIDATION_DURATION] = timed_result.duration
|
106
|
+
ns[VALIDATION_DURATION] = timed_result.duration
|
107
|
+
|
108
|
+
pre_context.reset_parsing_timings
|
109
|
+
|
110
|
+
timed_result.result
|
111
|
+
end
|
112
|
+
|
113
|
+
def capture_analysis_time(context)
|
114
|
+
ns = context.namespace(CONTEXT_NAMESPACE)
|
115
|
+
|
116
|
+
timed_result = GraphQL::Metrics.time(ns[QUERY_START_TIME_MONOTONIC]) { yield }
|
117
|
+
|
118
|
+
ns[ANALYSIS_START_TIME_OFFSET] = timed_result.time_since_offset
|
119
|
+
ns[ANALYSIS_DURATION] = timed_result.duration
|
89
120
|
|
90
121
|
timed_result.result
|
91
122
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-metrics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher Butcher
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-06
|
11
|
+
date: 2020-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|