skylight 5.0.0.beta4 → 5.1.0.beta2
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 +399 -362
- data/CLA.md +1 -1
- data/CONTRIBUTING.md +1 -1
- data/LICENSE.md +7 -17
- data/README.md +1 -1
- data/ext/extconf.rb +42 -54
- data/ext/libskylight.yml +10 -5
- data/lib/skylight.rb +20 -30
- data/lib/skylight/api.rb +22 -18
- data/lib/skylight/cli.rb +47 -46
- data/lib/skylight/cli/doctor.rb +50 -50
- data/lib/skylight/cli/helpers.rb +19 -19
- data/lib/skylight/cli/merger.rb +141 -139
- data/lib/skylight/config.rb +267 -310
- data/lib/skylight/deprecation.rb +4 -4
- data/lib/skylight/errors.rb +3 -4
- data/lib/skylight/extensions.rb +17 -29
- data/lib/skylight/extensions/source_location.rb +128 -128
- data/lib/skylight/formatters/http.rb +1 -3
- data/lib/skylight/gc.rb +30 -40
- data/lib/skylight/helpers.rb +57 -30
- data/lib/skylight/instrumenter.rb +25 -18
- data/lib/skylight/middleware.rb +31 -35
- data/lib/skylight/native.rb +8 -10
- data/lib/skylight/native_ext_fetcher.rb +10 -12
- data/lib/skylight/normalizers.rb +43 -38
- data/lib/skylight/normalizers/action_controller/process_action.rb +24 -25
- data/lib/skylight/normalizers/action_controller/send_file.rb +7 -6
- data/lib/skylight/normalizers/action_dispatch/route_set.rb +7 -7
- data/lib/skylight/normalizers/active_job/perform.rb +48 -44
- data/lib/skylight/normalizers/active_model_serializers/render.rb +7 -3
- data/lib/skylight/normalizers/active_storage.rb +11 -13
- data/lib/skylight/normalizers/active_support/cache.rb +1 -12
- data/lib/skylight/normalizers/coach/handler_finish.rb +1 -3
- data/lib/skylight/normalizers/default.rb +1 -9
- data/lib/skylight/normalizers/faraday/request.rb +1 -3
- data/lib/skylight/normalizers/grape/endpoint.rb +13 -19
- data/lib/skylight/normalizers/grape/endpoint_run.rb +16 -18
- data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +1 -3
- data/lib/skylight/normalizers/graphql/base.rb +23 -28
- data/lib/skylight/normalizers/render.rb +19 -21
- data/lib/skylight/normalizers/shrine.rb +32 -0
- data/lib/skylight/normalizers/sql.rb +4 -4
- data/lib/skylight/probes.rb +38 -46
- data/lib/skylight/probes/action_controller.rb +32 -28
- data/lib/skylight/probes/action_dispatch/request_id.rb +9 -5
- data/lib/skylight/probes/action_dispatch/routing/route_set.rb +7 -5
- data/lib/skylight/probes/action_view.rb +9 -10
- data/lib/skylight/probes/active_job_enqueue.rb +3 -9
- data/lib/skylight/probes/active_model_serializers.rb +8 -8
- data/lib/skylight/probes/delayed_job.rb +37 -42
- data/lib/skylight/probes/elasticsearch.rb +4 -6
- data/lib/skylight/probes/excon.rb +1 -1
- data/lib/skylight/probes/excon/middleware.rb +22 -23
- data/lib/skylight/probes/graphql.rb +2 -7
- data/lib/skylight/probes/middleware.rb +14 -5
- data/lib/skylight/probes/mongo.rb +83 -91
- data/lib/skylight/probes/net_http.rb +1 -1
- data/lib/skylight/probes/redis.rb +5 -17
- data/lib/skylight/probes/sequel.rb +7 -11
- data/lib/skylight/probes/sinatra.rb +8 -5
- data/lib/skylight/probes/tilt.rb +2 -4
- data/lib/skylight/railtie.rb +121 -135
- data/lib/skylight/sidekiq.rb +4 -5
- data/lib/skylight/subscriber.rb +31 -33
- data/lib/skylight/test.rb +89 -84
- data/lib/skylight/trace.rb +121 -115
- data/lib/skylight/user_config.rb +14 -17
- data/lib/skylight/util/clock.rb +1 -0
- data/lib/skylight/util/component.rb +18 -21
- data/lib/skylight/util/deploy.rb +11 -13
- data/lib/skylight/util/http.rb +104 -105
- data/lib/skylight/util/logging.rb +4 -6
- data/lib/skylight/util/lru_cache.rb +2 -6
- data/lib/skylight/util/platform.rb +2 -6
- data/lib/skylight/util/ssl.rb +1 -25
- data/lib/skylight/version.rb +1 -1
- data/lib/skylight/vm/gc.rb +1 -9
- metadata +20 -5
@@ -7,42 +7,46 @@ module Skylight
|
|
7
7
|
::ActionController::Instrumentation.class_eval do
|
8
8
|
private
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
alias_method :append_info_to_payload_without_sk, :append_info_to_payload
|
11
|
+
def append_info_to_payload(payload)
|
12
|
+
append_info_to_payload_without_sk(payload)
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
payload[:sk_rendered_format] = sk_rendered_mime.try(:ref)
|
15
|
+
payload[:sk_variant] = request.respond_to?(:variant) ? request.variant : nil
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
def sk_rendered_mime
|
19
|
+
if respond_to?(:media_type)
|
20
|
+
mt = media_type
|
21
|
+
return mt && Mime::Type.lookup(mt)
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
rescue
|
33
|
-
# There are cases in which actionpack can return
|
34
|
-
# a stringified representation of a Mime::NullType instance,
|
35
|
-
# which is invalid for a number of reasons. This string raises
|
36
|
-
# errors when piped through Mime::Type.lookup, so it's probably
|
37
|
-
# best to just return nil in those cases.
|
38
|
-
nil
|
24
|
+
if content_type.is_a?(Mime::Type)
|
25
|
+
content_type
|
26
|
+
elsif content_type.respond_to?(:to_s)
|
27
|
+
type_str = content_type.to_s.split(";").first
|
28
|
+
Mime::Type.lookup(type_str) unless type_str.blank?
|
29
|
+
elsif respond_to?(:rendered_format) && rendered_format
|
30
|
+
rendered_format
|
39
31
|
end
|
32
|
+
rescue StandardError
|
33
|
+
# There are cases in which actionpack can return
|
34
|
+
# a stringified representation of a Mime::NullType instance,
|
35
|
+
# which is invalid for a number of reasons. This string raises
|
36
|
+
# errors when piped through Mime::Type.lookup, so it's probably
|
37
|
+
# best to just return nil in those cases.
|
38
|
+
nil
|
39
|
+
end
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
register(
|
46
|
-
|
45
|
+
register(
|
46
|
+
:action_controller,
|
47
|
+
"ActionController::Instrumentation",
|
48
|
+
"action_controller/metal/instrumentation",
|
49
|
+
ActionController::Probe.new
|
50
|
+
)
|
47
51
|
end
|
48
52
|
end
|
@@ -10,9 +10,9 @@ module Skylight
|
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
def internal_request_id
|
14
|
+
@skylight_request_id || super
|
15
|
+
end
|
16
16
|
end
|
17
17
|
|
18
18
|
class Probe
|
@@ -23,7 +23,11 @@ module Skylight
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
register(
|
27
|
-
|
26
|
+
register(
|
27
|
+
:action_dispatch,
|
28
|
+
"ActionDispatch::RequestId",
|
29
|
+
"action_dispatch/middleware/request_id",
|
30
|
+
ActionDispatch::RequestId::Probe.new
|
31
|
+
)
|
28
32
|
end
|
29
33
|
end
|
@@ -7,9 +7,7 @@ module Skylight
|
|
7
7
|
module RouteSet
|
8
8
|
module Instrumentation
|
9
9
|
def call(env)
|
10
|
-
ActiveSupport::Notifications.instrument("route_set.action_dispatch")
|
11
|
-
super
|
12
|
-
end
|
10
|
+
ActiveSupport::Notifications.instrument("route_set.action_dispatch") { super }
|
13
11
|
end
|
14
12
|
end
|
15
13
|
|
@@ -22,7 +20,11 @@ module Skylight
|
|
22
20
|
end
|
23
21
|
end
|
24
22
|
|
25
|
-
register(
|
26
|
-
|
23
|
+
register(
|
24
|
+
:rails_router,
|
25
|
+
"ActionDispatch::Routing::RouteSet",
|
26
|
+
"action_dispatch/routing/route_set",
|
27
|
+
ActionDispatch::Routing::RouteSet::Probe.new
|
28
|
+
)
|
27
29
|
end
|
28
30
|
end
|
@@ -5,19 +5,18 @@ module Skylight
|
|
5
5
|
module ActionView
|
6
6
|
module Instrumentation
|
7
7
|
def render_with_layout(*args) #:nodoc:
|
8
|
-
path, locals =
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
path, locals =
|
9
|
+
case args.length
|
10
|
+
when 2
|
11
|
+
args
|
12
|
+
when 4
|
13
|
+
# Rails > 6.0.0.beta3 arguments are (view, template, path, locals)
|
14
|
+
[args[2], args[3]]
|
15
|
+
end
|
15
16
|
|
16
17
|
layout = nil
|
17
18
|
|
18
|
-
if path
|
19
|
-
layout = find_layout(path, locals.keys, [formats.first])
|
20
|
-
end
|
19
|
+
layout = find_layout(path, locals.keys, [formats.first]) if path
|
21
20
|
|
22
21
|
if layout
|
23
22
|
ActiveSupport::Notifications.instrument("render_template.action_view", identifier: layout.identifier) do
|
@@ -14,17 +14,11 @@ module Skylight
|
|
14
14
|
name, job_class_name = Normalizers::ActiveJob::Perform.normalize_title(job)
|
15
15
|
descriptors = ["adapter: '#{adapter_name}'", "queue: '#{job.queue_name}'"]
|
16
16
|
descriptors << "job: '#{job_class_name}'" if job_class_name
|
17
|
-
desc = "{ #{descriptors.join(
|
18
|
-
rescue
|
17
|
+
desc = "{ #{descriptors.join(", ")} }"
|
18
|
+
rescue StandardError
|
19
19
|
block.call
|
20
20
|
else
|
21
|
-
Skylight.instrument(
|
22
|
-
title: "Enqueue #{name}",
|
23
|
-
category: CAT,
|
24
|
-
description: desc,
|
25
|
-
internal: true,
|
26
|
-
&block
|
27
|
-
)
|
21
|
+
Skylight.instrument(title: "Enqueue #{name}", category: CAT, description: desc, internal: true, &block)
|
28
22
|
end
|
29
23
|
|
30
24
|
self.class.instance_eval do
|
@@ -18,9 +18,7 @@ module Skylight
|
|
18
18
|
rescue LoadError # rubocop:disable Lint/SuppressedException
|
19
19
|
end
|
20
20
|
|
21
|
-
if Gem.loaded_specs["active_model_serializers"]
|
22
|
-
version = Gem.loaded_specs["active_model_serializers"].version
|
23
|
-
end
|
21
|
+
version = Gem.loaded_specs["active_model_serializers"].version if Gem.loaded_specs["active_model_serializers"]
|
24
22
|
|
25
23
|
if !version || version < Gem::Version.new("0.5.0")
|
26
24
|
Skylight.error "Instrumention is only available for ActiveModelSerializers version 0.5.0 and greater."
|
@@ -37,14 +35,16 @@ module Skylight
|
|
37
35
|
# End users could override as_json without calling super, but it's likely safer
|
38
36
|
# than overriding serializable_array/hash/object.
|
39
37
|
|
40
|
-
[::ActiveModel::Serializer, ::ActiveModel::ArraySerializer].each
|
41
|
-
klass.prepend(Instrumentation)
|
42
|
-
end
|
38
|
+
[::ActiveModel::Serializer, ::ActiveModel::ArraySerializer].each { |klass| klass.prepend(Instrumentation) }
|
43
39
|
end
|
44
40
|
end
|
45
41
|
end
|
46
42
|
|
47
|
-
register(
|
48
|
-
|
43
|
+
register(
|
44
|
+
:active_model_serializers,
|
45
|
+
"ActiveModel::Serializer",
|
46
|
+
"active_model/serializer",
|
47
|
+
ActiveModelSerializers::Probe.new
|
48
|
+
)
|
49
49
|
end
|
50
50
|
end
|
@@ -10,13 +10,9 @@ module Skylight
|
|
10
10
|
|
11
11
|
class Plugin < ::Delayed::Plugin
|
12
12
|
callbacks do |lifecycle|
|
13
|
-
lifecycle.around(:perform)
|
14
|
-
sk_instrument(worker, job, &block)
|
15
|
-
end
|
13
|
+
lifecycle.around(:perform) { |worker, job, &block| sk_instrument(worker, job, &block) }
|
16
14
|
|
17
|
-
lifecycle.after(:error)
|
18
|
-
Skylight.trace&.segment = "error"
|
19
|
-
end
|
15
|
+
lifecycle.after(:error) { |_worker, _job| Skylight.trace&.segment = "error" }
|
20
16
|
end
|
21
17
|
|
22
18
|
class << self
|
@@ -25,15 +21,19 @@ module Skylight
|
|
25
21
|
def sk_instrument(_worker, job)
|
26
22
|
endpoint = Skylight::Probes::DelayedJob.handler_name(job)
|
27
23
|
|
28
|
-
Skylight.trace(
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
24
|
+
Skylight.trace(
|
25
|
+
endpoint,
|
26
|
+
"app.delayed_job.worker",
|
27
|
+
"Delayed::Worker#run",
|
28
|
+
component: :worker,
|
29
|
+
segment: job.queue,
|
30
|
+
meta: {
|
31
|
+
source_location: "delayed_job"
|
32
|
+
}
|
33
|
+
) do
|
34
|
+
t { "Delayed::Job beginning trace" }
|
35
|
+
yield
|
36
|
+
end
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -44,11 +44,8 @@ module Skylight
|
|
44
44
|
UNKNOWN = "<Delayed::Job Unknown>"
|
45
45
|
|
46
46
|
def self.handler_name(job)
|
47
|
-
payload_object =
|
48
|
-
|
49
|
-
else
|
50
|
-
job.payload_object
|
51
|
-
end
|
47
|
+
payload_object =
|
48
|
+
job.respond_to?(:payload_object_without_sk) ? job.payload_object_without_sk : job.payload_object
|
52
49
|
|
53
50
|
payload_object_name(payload_object)
|
54
51
|
end
|
@@ -62,7 +59,7 @@ module Skylight
|
|
62
59
|
# Use class name instead to avoid this.
|
63
60
|
payload_object.class.name
|
64
61
|
end
|
65
|
-
rescue
|
62
|
+
rescue StandardError
|
66
63
|
UNKNOWN
|
67
64
|
end
|
68
65
|
|
@@ -84,8 +81,10 @@ module Skylight
|
|
84
81
|
|
85
82
|
opts = {
|
86
83
|
category: "app.delayed_job.job",
|
87
|
-
title:
|
88
|
-
meta:
|
84
|
+
title: format_source(*source_meta),
|
85
|
+
meta: {
|
86
|
+
source_location_hint: source_meta
|
87
|
+
},
|
89
88
|
internal: true
|
90
89
|
}
|
91
90
|
|
@@ -99,13 +98,9 @@ module Skylight
|
|
99
98
|
|
100
99
|
private
|
101
100
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
else
|
106
|
-
"#{constant_name}.#{method_name}"
|
107
|
-
end
|
108
|
-
end
|
101
|
+
def format_source(method_type, constant_name, method_name)
|
102
|
+
method_type == :instance_method ? "#{constant_name}##{method_name}" : "#{constant_name}.#{method_name}"
|
103
|
+
end
|
109
104
|
end
|
110
105
|
|
111
106
|
class Probe
|
@@ -124,23 +119,23 @@ module Skylight
|
|
124
119
|
|
125
120
|
private
|
126
121
|
|
127
|
-
|
128
|
-
|
129
|
-
|
122
|
+
def plugin_defined?
|
123
|
+
defined?(::Skylight::Probes::DelayedJob::Plugin)
|
124
|
+
end
|
130
125
|
|
131
|
-
|
132
|
-
|
133
|
-
|
126
|
+
def validate_version
|
127
|
+
spec = Gem.loaded_specs["delayed_job"]
|
128
|
+
version = spec&.version
|
134
129
|
|
135
|
-
|
136
|
-
|
130
|
+
if !version || version < Gem::Version.new("4.0.0")
|
131
|
+
Skylight.error "The installed version of DelayedJob is not supported on Skylight. " \
|
137
132
|
"Your jobs will not be tracked."
|
138
133
|
|
139
|
-
|
140
|
-
end
|
141
|
-
|
142
|
-
true
|
134
|
+
return false
|
143
135
|
end
|
136
|
+
|
137
|
+
true
|
138
|
+
end
|
144
139
|
end
|
145
140
|
end
|
146
141
|
|
@@ -9,16 +9,14 @@ module Skylight
|
|
9
9
|
def perform_request(method, path, *args, &block)
|
10
10
|
ActiveSupport::Notifications.instrument(
|
11
11
|
"request.elasticsearch",
|
12
|
-
name:
|
12
|
+
name: "Request",
|
13
13
|
method: method,
|
14
|
-
path:
|
14
|
+
path: path
|
15
15
|
) do
|
16
16
|
# Prevent HTTP-related probes from firing
|
17
17
|
Skylight::Normalizers::Faraday::Request.disable do
|
18
18
|
disable_skylight_probe(:NetHTTP) do
|
19
|
-
disable_skylight_probe(:HTTPClient)
|
20
|
-
perform_request_without_sk(method, path, *args, &block)
|
21
|
-
end
|
19
|
+
disable_skylight_probe(:HTTPClient) { perform_request_without_sk(method, path, *args, &block) }
|
22
20
|
end
|
23
21
|
end
|
24
22
|
end
|
@@ -26,7 +24,7 @@ module Skylight
|
|
26
24
|
|
27
25
|
def disable_skylight_probe(class_name)
|
28
26
|
klass = ::ActiveSupport::Inflector.safe_constantize("Skylight::Probes::#{class_name}::Probe")
|
29
|
-
(klass ? klass.disable { yield } : yield).tap {
|
27
|
+
(klass ? klass.disable { yield } : yield).tap { Skylight.log(:debug, "re-enabling: #{klass}") }
|
30
28
|
end
|
31
29
|
end
|
32
30
|
end
|
@@ -14,7 +14,7 @@ module Skylight
|
|
14
14
|
::Excon.defaults[:middlewares].insert(idx, Probes::Excon::Middleware)
|
15
15
|
else
|
16
16
|
Skylight.error "The installed version of Excon doesn't support Middlewares. " \
|
17
|
-
|
17
|
+
"The Excon probe will be disabled."
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -33,33 +33,32 @@ module Skylight
|
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
# TODO: Maybe don't show other default ports like 443
|
41
|
-
port = datum[:port] == 80 ? nil : datum[:port]
|
42
|
-
path = datum[:path]
|
43
|
-
query = datum[:query]
|
36
|
+
def begin_instrumentation(datum)
|
37
|
+
method = datum[:method].to_s
|
38
|
+
scheme = datum[:scheme]
|
39
|
+
host = datum[:host]
|
44
40
|
|
45
|
-
|
41
|
+
# TODO: Maybe don't show other default ports like 443
|
42
|
+
port = datum[:port] == 80 ? nil : datum[:port]
|
43
|
+
path = datum[:path]
|
44
|
+
query = datum[:query]
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
opts = Formatters::HTTP.build_opts(method, scheme, host, port, path, query)
|
47
|
+
|
48
|
+
@requests[datum] = Skylight.instrument(opts)
|
49
|
+
rescue Exception => e
|
50
|
+
Skylight.error "failed to begin instrumentation for Excon; msg=%s", e.message
|
51
|
+
end
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
58
|
-
Skylight.done(request, meta)
|
59
|
-
end
|
60
|
-
rescue Exception => e
|
61
|
-
Skylight.error "failed to end instrumentation for Excon; msg=%s", e.message
|
53
|
+
def end_instrumentation(datum)
|
54
|
+
if (request = @requests.delete(datum))
|
55
|
+
meta = {}
|
56
|
+
meta[:exception_object] = datum[:error] if datum[:error].is_a?(Exception)
|
57
|
+
Skylight.done(request, meta)
|
62
58
|
end
|
59
|
+
rescue Exception => e
|
60
|
+
Skylight.error "failed to end instrumentation for Excon; msg=%s", e.message
|
61
|
+
end
|
63
62
|
end
|
64
63
|
end
|
65
64
|
end
|
@@ -20,16 +20,11 @@ module Skylight
|
|
20
20
|
class Probe
|
21
21
|
def install
|
22
22
|
tracing_klass_name = "::GraphQL::Tracing::ActiveSupportNotificationsTracing"
|
23
|
-
klasses_to_probe = %w[
|
24
|
-
::GraphQL::Execution::Multiplex
|
25
|
-
::GraphQL::Query
|
26
|
-
]
|
23
|
+
klasses_to_probe = %w[::GraphQL::Execution::Multiplex ::GraphQL::Query]
|
27
24
|
|
28
25
|
return unless ([tracing_klass_name] + klasses_to_probe).all?(&method(:safe_constantize))
|
29
26
|
|
30
|
-
klasses_to_probe.each
|
31
|
-
safe_constantize(klass_name).prepend(Instrumentation)
|
32
|
-
end
|
27
|
+
klasses_to_probe.each { |klass_name| safe_constantize(klass_name).prepend(Instrumentation) }
|
33
28
|
end
|
34
29
|
|
35
30
|
def safe_constantize(klass_name)
|