skylight 5.0.0.beta4 → 5.1.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|