skylight-core 4.2.0 → 4.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/skylight/core/middleware.rb +19 -5
- data/lib/skylight/core/normalizers/active_job/perform.rb +2 -2
- data/lib/skylight/core/normalizers/grape/endpoint.rb +2 -1
- data/lib/skylight/core/normalizers/graphql/base.rb +53 -15
- data/lib/skylight/core/probes/action_controller.rb +7 -0
- data/lib/skylight/core/probes/graphql.rb +26 -25
- data/lib/skylight/core/probes/middleware.rb +1 -1
- data/lib/skylight/core/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2443077b98bc42af5683f82aac17e192670026cbd6bdfa9a940caff2237860a0
|
4
|
+
data.tar.gz: e0dc413f3f0d0827f4b064b8fdfbac13f607357113ed50a223f9522e5775b5e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3ae4c018808967cf5b0cec1fb9056c037f37c2cd60b1790759755d1d9e05cba3f400a790502110fa5723541ad03f0fcf50eeb0d3ebc546d9ff19eb3c8d00309
|
7
|
+
data.tar.gz: ca5ca4747d2ec5a578f830dc5ee1ef818a651ca9a9f95ad069cfd26849014279f9aa4f9d3f2040eaf6de8ea64501959fbab005800c96107d17fe9f92b572517c
|
@@ -44,17 +44,31 @@ module Skylight::Core
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
def self.with_after_close(resp, &block)
|
47
|
+
def self.with_after_close(resp, debug_identifier: "unknown", &block)
|
48
48
|
# Responses should be arrays but in some situations they aren't
|
49
49
|
# e.g. https://github.com/ruby-grape/grape/issues/1041
|
50
|
-
# The safest approach seems to be to rely on implicit destructuring
|
51
|
-
# since that is currently what Rack::Lint does.
|
52
50
|
# See also https://github.com/rack/rack/issues/1239
|
53
|
-
status, headers, body = resp
|
54
51
|
|
52
|
+
unless resp.respond_to?(:to_ary)
|
53
|
+
if resp.respond_to?(:to_a)
|
54
|
+
log_target.warn("Rack response from \"#{debug_identifier}\" cannot be implicitly converted to an array. This is in violation of "\
|
55
|
+
"the Rack SPEC and will raise an error in future versions.")
|
56
|
+
resp = resp.to_a
|
57
|
+
else
|
58
|
+
log_target.error("Rack response from \"#{debug_identifier}\" cannot be converted to an array. This is in violation of the Rack SPEC "\
|
59
|
+
"and may cause problems with Skylight operation.")
|
60
|
+
return resp
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
status, headers, body = resp
|
55
65
|
[status, headers, BodyProxy.new(body, &block)]
|
56
66
|
end
|
57
67
|
|
68
|
+
def self.log_target
|
69
|
+
@log_target ||= (Skylight::Core::Fanout.registered.first&.config || Logger.new(STDERR))
|
70
|
+
end
|
71
|
+
|
58
72
|
include Util::Logging
|
59
73
|
|
60
74
|
# For Util::Logging
|
@@ -84,7 +98,7 @@ module Skylight::Core
|
|
84
98
|
resp = @app.call(env)
|
85
99
|
|
86
100
|
if trace
|
87
|
-
Middleware.with_after_close(resp) { trace.submit }
|
101
|
+
Middleware.with_after_close(resp, debug_identifier: "Rack App: #{@app.class}") { trace.submit }
|
88
102
|
else
|
89
103
|
resp
|
90
104
|
end
|
@@ -4,12 +4,12 @@ module Skylight::Core
|
|
4
4
|
class Perform < Normalizer
|
5
5
|
register "perform.active_job"
|
6
6
|
|
7
|
-
DELIVERY_JOB =
|
7
|
+
DELIVERY_JOB = /\AActionMailer::(Mail)?DeliveryJob\Z/.freeze
|
8
8
|
DELAYED_JOB_WRAPPER = "ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper".freeze
|
9
9
|
|
10
10
|
def self.normalize_title(job_instance)
|
11
11
|
job_instance.class.name.to_s.tap do |str|
|
12
|
-
if str
|
12
|
+
if str.match(DELIVERY_JOB)
|
13
13
|
mailer_class, mailer_method, * = job_instance.arguments
|
14
14
|
return ["#{mailer_class}##{mailer_method}", str]
|
15
15
|
end
|
@@ -25,7 +25,8 @@ module Skylight::Core
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def get_namespace(endpoint)
|
28
|
-
|
28
|
+
# slice off preceding slash for data continuity
|
29
|
+
::Grape::Namespace.joined_space_path(endpoint.namespace_stackable(:namespace)).to_s[1..-1]
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/inflector"
|
4
|
+
|
3
5
|
module Skylight::Core::Normalizers::GraphQL
|
4
6
|
# Some AS::N events in GraphQL are not super useful.
|
5
7
|
# We are purposefully ignoring the following keys (and you probably shouldn't add them):
|
@@ -11,25 +13,61 @@ module Skylight::Core::Normalizers::GraphQL
|
|
11
13
|
ANONYMOUS = "[anonymous]".freeze
|
12
14
|
CAT = "app.graphql".freeze
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
+
if defined?(::GraphQL::VERSION) && Gem::Version.new(::GraphQL::VERSION) >= Gem::Version.new("1.10")
|
17
|
+
def self.register_graphql
|
18
|
+
register("#{key}.graphql")
|
19
|
+
end
|
20
|
+
else
|
21
|
+
def self.register_graphql
|
22
|
+
register("graphql.#{key}")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.inherited(klass)
|
27
|
+
klass.const_set(
|
28
|
+
:KEY,
|
29
|
+
ActiveSupport::Inflector.underscore(
|
30
|
+
ActiveSupport::Inflector.demodulize(klass.name)
|
31
|
+
).freeze
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.key
|
36
|
+
self::KEY
|
16
37
|
end
|
38
|
+
|
39
|
+
def normalize(_trace, _name, _payload)
|
40
|
+
[CAT, "graphql.#{key}", nil]
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def key
|
46
|
+
self.class.key
|
47
|
+
end
|
48
|
+
|
49
|
+
def extract_query_name(query)
|
50
|
+
query&.context&.[](:skylight_endpoint) ||
|
51
|
+
query&.operation_name ||
|
52
|
+
ANONYMOUS
|
53
|
+
end
|
17
54
|
end
|
18
55
|
|
19
56
|
class Lex < Base
|
20
|
-
|
57
|
+
register_graphql
|
21
58
|
end
|
22
59
|
|
23
60
|
class Parse < Base
|
24
|
-
|
61
|
+
register_graphql
|
25
62
|
end
|
26
63
|
|
27
64
|
class Validate < Base
|
28
|
-
|
65
|
+
register_graphql
|
29
66
|
end
|
30
67
|
|
31
68
|
class ExecuteMultiplex < Base
|
32
|
-
|
69
|
+
register_graphql
|
70
|
+
|
33
71
|
def normalize_after(trace, _span, _name, payload)
|
34
72
|
# This is in normalize_after because the queries may not have
|
35
73
|
# an assigned operation name before they are executed.
|
@@ -44,7 +82,7 @@ module Skylight::Core::Normalizers::GraphQL
|
|
44
82
|
# has not been done yet at the point where execute_multiplex starts.
|
45
83
|
# [1] https://graphql.org/learn/serving-over-http/#post-request
|
46
84
|
queries, has_errors = payload[:multiplex].queries.each_with_object([Set.new, Set.new]) do |query, (names, errors)|
|
47
|
-
names << (query
|
85
|
+
names << extract_query_name(query)
|
48
86
|
errors << query.static_errors.any?
|
49
87
|
end
|
50
88
|
|
@@ -58,14 +96,14 @@ module Skylight::Core::Normalizers::GraphQL
|
|
58
96
|
end
|
59
97
|
|
60
98
|
class AnalyzeQuery < Base
|
61
|
-
|
99
|
+
register_graphql
|
62
100
|
end
|
63
101
|
|
64
102
|
class ExecuteQuery < Base
|
65
|
-
|
103
|
+
register_graphql
|
66
104
|
|
67
|
-
def normalize(trace,
|
68
|
-
query_name = payload[:query]
|
105
|
+
def normalize(trace, _name, payload)
|
106
|
+
query_name = extract_query_name(payload[:query])
|
69
107
|
|
70
108
|
if query_name == ANONYMOUS
|
71
109
|
meta = { mute_children: true }
|
@@ -75,18 +113,18 @@ module Skylight::Core::Normalizers::GraphQL
|
|
75
113
|
# but in the case of a single query, it will be the same value anyway.
|
76
114
|
trace.endpoint = "graphql:#{query_name}"
|
77
115
|
|
78
|
-
[CAT, "
|
116
|
+
[CAT, "graphql.#{key}: #{query_name}", nil, meta]
|
79
117
|
end
|
80
118
|
end
|
81
119
|
|
82
120
|
class ExecuteQueryLazy < ExecuteQuery
|
83
|
-
|
121
|
+
register_graphql
|
84
122
|
|
85
|
-
def normalize(trace,
|
123
|
+
def normalize(trace, _name, payload)
|
86
124
|
if payload[:query]
|
87
125
|
super
|
88
126
|
elsif payload[:multiplex]
|
89
|
-
[CAT, "
|
127
|
+
[CAT, "graphql.#{key}.multiplex", nil]
|
90
128
|
end
|
91
129
|
end
|
92
130
|
end
|
@@ -27,6 +27,13 @@ module Skylight::Core
|
|
27
27
|
elsif respond_to?(:rendered_format) && rendered_format
|
28
28
|
rendered_format
|
29
29
|
end
|
30
|
+
rescue
|
31
|
+
# There are cases in which actionpack can return
|
32
|
+
# a stringified representation of a Mime::NullType instance,
|
33
|
+
# which is invalid for a number of reasons. This string raises
|
34
|
+
# errors when piped through Mime::Type.lookup, so it's probably
|
35
|
+
# best to just return nil in those cases.
|
36
|
+
nil
|
30
37
|
end
|
31
38
|
end
|
32
39
|
end
|
@@ -3,35 +3,36 @@
|
|
3
3
|
module Skylight::Core
|
4
4
|
module Probes
|
5
5
|
module GraphQL
|
6
|
+
module Instrumentation
|
7
|
+
def initialize(*, **)
|
8
|
+
super
|
9
|
+
|
10
|
+
return unless defined?(@tracers)
|
11
|
+
|
12
|
+
unless @tracers.include?(::GraphQL::Tracing::ActiveSupportNotificationsTracing)
|
13
|
+
@tracers << ::GraphQL::Tracing::ActiveSupportNotificationsTracing
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
6
18
|
class Probe
|
7
19
|
def install
|
8
|
-
::GraphQL::
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
def sk_add_tracer
|
19
|
-
Skylight::Core::Config::MUTEX.synchronize do
|
20
|
-
graphql_tracer = ::GraphQL::Tracing::ActiveSupportNotificationsTracing
|
21
|
-
unless tracers.include?(graphql_tracer)
|
22
|
-
$stdout.puts "[SKYLIGHT::CORE] Adding tracer 'GraphQL::Tracing::ActiveSupportNotificationsTracing' to schema"
|
23
|
-
tracers << graphql_tracer
|
24
|
-
end
|
25
|
-
|
26
|
-
class << self
|
27
|
-
# Remove the probe and reset multiplex/execute to original version
|
28
|
-
# after the tracer has been added
|
29
|
-
alias_method :multiplex, :multiplex_without_sk
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
20
|
+
tracing_klass_name = "::GraphQL::Tracing::ActiveSupportNotificationsTracing"
|
21
|
+
klasses_to_probe = %w(
|
22
|
+
::GraphQL::Execution::Multiplex
|
23
|
+
::GraphQL::Query
|
24
|
+
)
|
25
|
+
|
26
|
+
return unless ([tracing_klass_name] + klasses_to_probe).all?(&method(:safe_constantize))
|
27
|
+
|
28
|
+
klasses_to_probe.each do |klass_name|
|
29
|
+
safe_constantize(klass_name).prepend(Instrumentation)
|
33
30
|
end
|
34
31
|
end
|
32
|
+
|
33
|
+
def safe_constantize(klass_name)
|
34
|
+
Skylight::Core::Util::Inflector.safe_constantize(klass_name)
|
35
|
+
end
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
@@ -33,7 +33,7 @@ module Skylight::Core
|
|
33
33
|
spans = Skylight::Core::Fanout.instrument(title: name, category: "#{category}")
|
34
34
|
resp = call_without_sk(*args, &block)
|
35
35
|
|
36
|
-
proxied_response = Skylight::Core::Middleware.with_after_close(resp) do
|
36
|
+
proxied_response = Skylight::Core::Middleware.with_after_close(resp, debug_identifier: "Middleware: #{name}") do
|
37
37
|
Skylight::Core::Fanout.done(spans)
|
38
38
|
end
|
39
39
|
rescue Exception => err
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skylight-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tilde, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -269,8 +269,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
269
269
|
- !ruby/object:Gem::Version
|
270
270
|
version: '0'
|
271
271
|
requirements: []
|
272
|
-
|
273
|
-
rubygems_version: 2.7.6
|
272
|
+
rubygems_version: 3.1.2
|
274
273
|
signing_key:
|
275
274
|
specification_version: 4
|
276
275
|
summary: The core methods of the Skylight profiler.
|