skylight 5.0.1 → 5.1.1
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 +395 -364
- data/CLA.md +1 -1
- data/LICENSE.md +7 -17
- data/README.md +1 -1
- data/ext/extconf.rb +42 -54
- data/ext/libskylight.yml +9 -6
- 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 +265 -300
- 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 +43 -41
- 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 -39
- 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 +15 -17
- 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 +3 -5
- 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 +6 -6
data/lib/skylight/normalizers.rb
CHANGED
@@ -79,18 +79,18 @@ module Skylight
|
|
79
79
|
|
80
80
|
private
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
82
|
+
def process_meta(trace, _name, payload, meta, cache_key: nil)
|
83
|
+
trace.instrumenter.extensions.process_normalizer_meta(
|
84
|
+
payload,
|
85
|
+
meta,
|
86
|
+
cache_key: cache_key,
|
87
|
+
**process_meta_options(payload)
|
88
|
+
)
|
89
|
+
end
|
90
90
|
|
91
|
-
|
92
|
-
|
93
|
-
|
91
|
+
def process_meta_options(_payload)
|
92
|
+
{}
|
93
|
+
end
|
94
94
|
end
|
95
95
|
|
96
96
|
require "skylight/normalizers/default"
|
@@ -105,6 +105,10 @@ module Skylight
|
|
105
105
|
@normalizers.keys
|
106
106
|
end
|
107
107
|
|
108
|
+
def each_key(&block)
|
109
|
+
@normalizers.each_key(&block)
|
110
|
+
end
|
111
|
+
|
108
112
|
def normalize(trace, name, payload)
|
109
113
|
normalizer_for(name).normalize_with_meta(trace, name, payload)
|
110
114
|
end
|
@@ -121,33 +125,33 @@ module Skylight
|
|
121
125
|
end
|
122
126
|
end
|
123
127
|
|
124
|
-
%w[
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
128
|
+
%w[
|
129
|
+
action_controller/process_action
|
130
|
+
action_controller/send_file
|
131
|
+
action_dispatch/process_middleware
|
132
|
+
action_dispatch/route_set
|
133
|
+
action_view/render_collection
|
134
|
+
action_view/render_partial
|
135
|
+
action_view/render_template
|
136
|
+
action_view/render_layout
|
137
|
+
active_job/perform
|
138
|
+
active_model_serializers/render
|
139
|
+
active_record/instantiation
|
140
|
+
active_record/sql
|
141
|
+
active_storage
|
142
|
+
active_support/cache
|
143
|
+
coach/handler_finish
|
144
|
+
coach/middleware_finish
|
145
|
+
couch_potato/query
|
146
|
+
data_mapper/sql
|
147
|
+
elasticsearch/request
|
148
|
+
faraday/request
|
149
|
+
grape/endpoint
|
150
|
+
graphiti/resolve
|
151
|
+
graphiti/render
|
152
|
+
graphql/base
|
153
|
+
sequel/sql
|
154
|
+
shrine
|
155
|
+
].each { |file| require "skylight/normalizers/#{file}" }
|
152
156
|
end
|
153
157
|
end
|
@@ -32,37 +32,36 @@ module Skylight
|
|
32
32
|
|
33
33
|
private
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
def controller_action(payload)
|
36
|
+
"#{payload[:controller]}##{payload[:action]}"
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
def process_meta_options(payload)
|
40
|
+
# provide hints to override default source_location behavior
|
41
|
+
super.merge(source_location_hint: [:instance_method, payload[:controller], payload[:action]])
|
42
|
+
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
def segment_from_payload(payload)
|
45
|
+
# Show 'error' if there's an unhandled exception or if the status is 4xx or 5xx
|
46
|
+
return "error" if payload[:exception] || payload[:exception_object]
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
[payload[:sk_rendered_format], payload[:sk_variant]].compact.flatten.join("+")
|
53
|
-
end
|
48
|
+
segment_from_status(payload[:status]) || if payload[:sk_rendered_format]
|
49
|
+
# We only show the variant if we actually have a format
|
50
|
+
# We won't have a sk_rendered_format if it's a `head` outside of a `respond_to` block.
|
51
|
+
[payload[:sk_rendered_format], payload[:sk_variant]].compact.flatten.join("+")
|
54
52
|
end
|
53
|
+
end
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
55
|
+
def segment_from_status(status)
|
56
|
+
case status
|
57
|
+
when 304
|
58
|
+
"not modified"
|
59
|
+
when (300..399)
|
60
|
+
"redirect"
|
61
|
+
when (400..599)
|
62
|
+
"error"
|
65
63
|
end
|
64
|
+
end
|
66
65
|
end
|
67
66
|
end
|
68
67
|
end
|
@@ -32,17 +32,18 @@ module Skylight
|
|
32
32
|
|
33
33
|
private
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
OCTET_STREAM = "application/octet-stream".freeze
|
36
|
+
ATTACHMENT = "attachment".freeze
|
37
37
|
|
38
|
-
|
39
|
-
|
38
|
+
def initialize(*)
|
39
|
+
super
|
40
40
|
|
41
|
-
|
41
|
+
@mimes =
|
42
|
+
Mime::SET.each_with_object({}) do |mime, hash|
|
42
43
|
hash[mime.symbol] = mime.to_s.dup.freeze
|
43
44
|
hash
|
44
45
|
end
|
45
|
-
|
46
|
+
end
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
@@ -13,14 +13,14 @@ module Skylight
|
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
def router_class_name
|
17
|
+
"ActionDispatch::Routing::RouteSet"
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
def process_meta_options(_payload)
|
21
|
+
# provide hints to override default source_location behavior
|
22
|
+
super.merge(source_location_hint: [:own_instance_method, router_class_name, "call"])
|
23
|
+
end
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -8,12 +8,16 @@ module Skylight
|
|
8
8
|
DELAYED_JOB_WRAPPER = "ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper".freeze
|
9
9
|
|
10
10
|
def self.normalize_title(job_instance)
|
11
|
-
job_instance
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
job_instance
|
12
|
+
.class
|
13
|
+
.name
|
14
|
+
.to_s
|
15
|
+
.tap do |str|
|
16
|
+
if str.match(DELIVERY_JOB)
|
17
|
+
mailer_class, mailer_method, * = job_instance.arguments
|
18
|
+
return "#{mailer_class}##{mailer_method}", str
|
19
|
+
end
|
15
20
|
end
|
16
|
-
end
|
17
21
|
end
|
18
22
|
|
19
23
|
CAT = "app.job.perform".freeze
|
@@ -36,50 +40,50 @@ module Skylight
|
|
36
40
|
|
37
41
|
private
|
38
42
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
def normalize_adapter_name(adapter)
|
45
|
-
adapter_string = adapter.is_a?(Class) ? adapter.to_s : adapter.class.to_s
|
46
|
-
adapter_string[/ActiveJob::QueueAdapters::(\w+)Adapter/, 1].underscore
|
47
|
-
rescue
|
48
|
-
"active_job"
|
49
|
-
end
|
43
|
+
def process_meta_options(payload)
|
44
|
+
# provide hints to override default source_location behavior
|
45
|
+
super.merge(source_location_hint: [:instance_method, payload[:job].class.to_s, "perform"])
|
46
|
+
end
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
48
|
+
def normalize_adapter_name(adapter)
|
49
|
+
adapter_string = adapter.is_a?(Class) ? adapter.to_s : adapter.class.to_s
|
50
|
+
adapter_string[/ActiveJob::QueueAdapters::(\w+)Adapter/, 1].underscore
|
51
|
+
rescue StandardError
|
52
|
+
"active_job"
|
53
|
+
end
|
56
54
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
return true if defined?(Skylight::Probes::ActiveJob::TITLE) &&
|
61
|
-
trace.endpoint == Skylight::Probes::ActiveJob::TITLE
|
62
|
-
return true if defined?(SKylight::Probes::DelayedJob::Probe::UNKNOWN) &&
|
63
|
-
trace.endpoint == Skylight::Probes::DelayedJob::Probe::UNKNOWN
|
55
|
+
def maybe_set_endpoint(trace, payload)
|
56
|
+
trace.endpoint = normalize_title(payload[:job]) if assign_endpoint?(trace, payload)
|
57
|
+
end
|
64
58
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
# segment to be assigned by normalize_after.
|
71
|
-
trace.endpoint == DELIVERY_JOB ||
|
72
|
-
trace.endpoint == normalize_title(payload[:job]) ||
|
73
|
-
# This adapter wrapper needs to be handled specifically due to interactions with the
|
74
|
-
# standalone Delayed::Job probe, as there is no consistent way to get the wrapped
|
75
|
-
# job name among all Delayed::Job backends.
|
76
|
-
trace.endpoint == DELAYED_JOB_WRAPPER
|
59
|
+
def assign_endpoint?(trace, payload)
|
60
|
+
# Always assign the endpoint if it has not yet been assigned by the ActiveJob probe.
|
61
|
+
return true unless trace.endpoint
|
62
|
+
if defined?(Skylight::Probes::ActiveJob::TITLE) && trace.endpoint == Skylight::Probes::ActiveJob::TITLE
|
63
|
+
return true
|
77
64
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
title
|
65
|
+
if defined?(SKylight::Probes::DelayedJob::Probe::UNKNOWN) &&
|
66
|
+
trace.endpoint == Skylight::Probes::DelayedJob::Probe::UNKNOWN
|
67
|
+
return true
|
82
68
|
end
|
69
|
+
|
70
|
+
# If a job is called using #perform_now inside a controller action
|
71
|
+
# or within another job's #perform method, we do not want this to
|
72
|
+
# overwrite the existing endpoint name (unless it is the default from ActiveJob).
|
73
|
+
#
|
74
|
+
# If the current endpoint name matches this payload, return true to allow the
|
75
|
+
# segment to be assigned by normalize_after.
|
76
|
+
trace.endpoint == DELIVERY_JOB || trace.endpoint == normalize_title(payload[:job]) ||
|
77
|
+
# This adapter wrapper needs to be handled specifically due to interactions with the
|
78
|
+
# standalone Delayed::Job probe, as there is no consistent way to get the wrapped
|
79
|
+
# job name among all Delayed::Job backends.
|
80
|
+
trace.endpoint == DELAYED_JOB_WRAPPER
|
81
|
+
end
|
82
|
+
|
83
|
+
def normalize_title(job_instance)
|
84
|
+
title, * = self.class.normalize_title(job_instance)
|
85
|
+
title
|
86
|
+
end
|
83
87
|
end
|
84
88
|
end
|
85
89
|
end
|
@@ -14,9 +14,13 @@ module Skylight
|
|
14
14
|
title = title.sub(/^ActiveModel::(Serializer::)?/, "")
|
15
15
|
|
16
16
|
if (adapter_instance = payload[:adapter])
|
17
|
-
adapter_name =
|
18
|
-
|
19
|
-
|
17
|
+
adapter_name =
|
18
|
+
adapter_instance
|
19
|
+
.class
|
20
|
+
.name
|
21
|
+
.to_s
|
22
|
+
.sub(/^ActiveModel::Serializer::Adapter::/, "")
|
23
|
+
.sub(/^ActiveModelSerializers::Adapter::/, "")
|
20
24
|
desc = "Adapter: #{adapter_name}"
|
21
25
|
end
|
22
26
|
|
@@ -2,26 +2,24 @@ module Skylight
|
|
2
2
|
module Normalizers
|
3
3
|
class ActiveStorage < Normalizer
|
4
4
|
TITLES = {
|
5
|
-
"preview.active_storage"
|
6
|
-
"transform.active_storage"
|
7
|
-
"service_download.active_storage"
|
8
|
-
"service_upload.active_storage"
|
5
|
+
"preview.active_storage" => "Preview",
|
6
|
+
"transform.active_storage" => "Transform",
|
7
|
+
"service_download.active_storage" => "Download",
|
8
|
+
"service_upload.active_storage" => "Upload",
|
9
9
|
"service_streaming_download.active_storage" => "Streaming Download",
|
10
|
-
"service_download_chunk.active_storage"
|
11
|
-
"service_delete.active_storage"
|
12
|
-
"service_delete_prefixed.active_storage"
|
13
|
-
"service_exist.active_storage"
|
14
|
-
"service_url.active_storage"
|
10
|
+
"service_download_chunk.active_storage" => "Download Chunk",
|
11
|
+
"service_delete.active_storage" => "Delete",
|
12
|
+
"service_delete_prefixed.active_storage" => "Delete Prefixed",
|
13
|
+
"service_exist.active_storage" => "Exist",
|
14
|
+
"service_url.active_storage" => "Url"
|
15
15
|
}.freeze
|
16
16
|
|
17
|
-
TITLES.each_key
|
18
|
-
register key
|
19
|
-
end
|
17
|
+
TITLES.each_key { |key| register key }
|
20
18
|
|
21
19
|
def normalize(_trace, name, _payload)
|
22
20
|
title = ["ActiveStorage", TITLES[name]].join(" ")
|
23
21
|
|
24
|
-
cat = "app.#{name.split(
|
22
|
+
cat = "app.#{name.split(".").reverse.join(".")}"
|
25
23
|
|
26
24
|
[cat, title, nil]
|
27
25
|
end
|
@@ -2,18 +2,7 @@ module Skylight
|
|
2
2
|
module Normalizers
|
3
3
|
module ActiveSupport
|
4
4
|
class Cache < Normalizer
|
5
|
-
%w[
|
6
|
-
clear
|
7
|
-
decrement
|
8
|
-
delete
|
9
|
-
exist
|
10
|
-
fetch_hit
|
11
|
-
generate
|
12
|
-
increment
|
13
|
-
read
|
14
|
-
read_multi
|
15
|
-
write
|
16
|
-
].each do |type|
|
5
|
+
%w[clear decrement delete exist fetch_hit generate increment read read_multi write].each do |type|
|
17
6
|
require "skylight/normalizers/active_support/cache_#{type}"
|
18
7
|
end
|
19
8
|
end
|
@@ -36,9 +36,7 @@ module Skylight
|
|
36
36
|
response_status = payload.fetch(:response, {}).fetch(:status, "").to_s
|
37
37
|
segments << "error" if response_status.start_with?("4", "5")
|
38
38
|
|
39
|
-
if segments.any?
|
40
|
-
trace.segment = segments.join("+")
|
41
|
-
end
|
39
|
+
trace.segment = segments.join("+") if segments.any?
|
42
40
|
end
|
43
41
|
end
|
44
42
|
end
|
@@ -17,15 +17,7 @@ module Skylight
|
|
17
17
|
# @option payload [String] :description
|
18
18
|
# @return [Array, :skip] the normalized array or `:skip` if `name` is not part of a known {Skylight::TIERS tier}
|
19
19
|
def normalize(_trace, name, payload)
|
20
|
-
|
21
|
-
[
|
22
|
-
name,
|
23
|
-
payload[:title],
|
24
|
-
payload[:description]
|
25
|
-
]
|
26
|
-
else
|
27
|
-
:skip
|
28
|
-
end
|
20
|
+
name =~ Skylight::TIER_REGEX ? [name, payload[:title], payload[:description]] : :skip
|
29
21
|
end
|
30
22
|
end
|
31
23
|
end
|
@@ -23,9 +23,7 @@ module Skylight
|
|
23
23
|
def normalize(_trace, _name, payload)
|
24
24
|
uri = payload[:url]
|
25
25
|
|
26
|
-
if disabled?
|
27
|
-
return :skip
|
28
|
-
end
|
26
|
+
return :skip if disabled?
|
29
27
|
|
30
28
|
opts = Formatters::HTTP.build_opts(payload[:method], uri.scheme, uri.host, uri.port, uri.path, uri.query)
|
31
29
|
description = opts[:title]
|
@@ -2,32 +2,26 @@ module Skylight
|
|
2
2
|
module Normalizers
|
3
3
|
module Grape
|
4
4
|
class Endpoint < Normalizer
|
5
|
-
%w[
|
6
|
-
run
|
7
|
-
render
|
8
|
-
run_filters
|
9
|
-
].each do |type|
|
10
|
-
require "skylight/normalizers/grape/endpoint_#{type}"
|
11
|
-
end
|
5
|
+
%w[run render run_filters].each { |type| require "skylight/normalizers/grape/endpoint_#{type}" }
|
12
6
|
|
13
7
|
require "skylight/normalizers/grape/format_response"
|
14
8
|
|
15
9
|
private
|
16
10
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
11
|
+
def get_method(endpoint)
|
12
|
+
method = endpoint.options[:method].first
|
13
|
+
method = "#{method}..." if endpoint.options[:method].length > 1
|
14
|
+
method
|
15
|
+
end
|
22
16
|
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
def get_path(endpoint)
|
18
|
+
endpoint.options[:path].join("/")
|
19
|
+
end
|
26
20
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
21
|
+
def get_namespace(endpoint)
|
22
|
+
# slice off preceding slash for data continuity
|
23
|
+
::Grape::Namespace.joined_space_path(endpoint.namespace_stackable(:namespace)).to_s[1..-1]
|
24
|
+
end
|
31
25
|
end
|
32
26
|
end
|
33
27
|
end
|