skylight 4.2.3 → 5.3.0
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 +420 -331
- data/CLA.md +1 -1
- data/CONTRIBUTING.md +2 -8
- data/ERRORS.md +3 -0
- data/LICENSE.md +7 -17
- data/README.md +1 -1
- data/ext/extconf.rb +61 -56
- data/ext/libskylight.yml +8 -6
- data/ext/skylight_native.c +26 -100
- data/lib/skylight/api.rb +32 -21
- data/lib/skylight/cli/doctor.rb +64 -65
- data/lib/skylight/cli/helpers.rb +19 -19
- data/lib/skylight/cli/merger.rb +142 -138
- data/lib/skylight/cli.rb +48 -46
- data/lib/skylight/config.rb +640 -201
- data/lib/skylight/data/cacert.pem +730 -1023
- data/lib/skylight/deprecation.rb +17 -0
- data/lib/skylight/errors.rb +26 -9
- data/lib/skylight/extensions/source_location.rb +291 -0
- data/lib/skylight/extensions.rb +95 -0
- data/lib/skylight/formatters/http.rb +18 -0
- data/lib/skylight/gc.rb +99 -0
- data/lib/skylight/helpers.rb +81 -36
- data/lib/skylight/instrumenter.rb +336 -18
- data/lib/skylight/middleware.rb +147 -1
- data/lib/skylight/native.rb +60 -12
- data/lib/skylight/native_ext_fetcher.rb +13 -14
- data/lib/skylight/normalizers/action_controller/process_action.rb +68 -0
- data/lib/skylight/normalizers/action_controller/send_file.rb +51 -0
- data/lib/skylight/normalizers/action_dispatch/process_middleware.rb +22 -0
- data/lib/skylight/normalizers/action_dispatch/route_set.rb +27 -0
- data/lib/skylight/normalizers/action_view/render_collection.rb +24 -0
- data/lib/skylight/normalizers/action_view/render_layout.rb +25 -0
- data/lib/skylight/normalizers/action_view/render_partial.rb +23 -0
- data/lib/skylight/normalizers/action_view/render_template.rb +23 -0
- data/lib/skylight/normalizers/active_job/perform.rb +87 -0
- data/lib/skylight/normalizers/active_model_serializers/render.rb +32 -0
- data/lib/skylight/normalizers/active_record/instantiation.rb +16 -0
- data/lib/skylight/normalizers/active_record/sql.rb +20 -0
- data/lib/skylight/normalizers/active_storage.rb +28 -0
- data/lib/skylight/normalizers/active_support/cache.rb +11 -0
- data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
- data/lib/skylight/normalizers/coach/handler_finish.rb +44 -0
- data/lib/skylight/normalizers/coach/middleware_finish.rb +33 -0
- data/lib/skylight/normalizers/couch_potato/query.rb +20 -0
- data/lib/skylight/normalizers/data_mapper/sql.rb +12 -0
- data/lib/skylight/normalizers/default.rb +24 -0
- data/lib/skylight/normalizers/elasticsearch/request.rb +20 -0
- data/lib/skylight/normalizers/faraday/request.rb +38 -0
- data/lib/skylight/normalizers/grape/endpoint.rb +28 -0
- data/lib/skylight/normalizers/grape/endpoint_render.rb +25 -0
- data/lib/skylight/normalizers/grape/endpoint_run.rb +39 -0
- data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +20 -0
- data/lib/skylight/normalizers/grape/format_response.rb +20 -0
- data/lib/skylight/normalizers/graphiti/render.rb +22 -0
- data/lib/skylight/normalizers/graphiti/resolve.rb +31 -0
- data/lib/skylight/normalizers/graphql/base.rb +127 -0
- data/lib/skylight/normalizers/render.rb +79 -0
- data/lib/skylight/normalizers/sequel/sql.rb +12 -0
- data/lib/skylight/normalizers/shrine.rb +32 -0
- data/lib/skylight/normalizers/sql.rb +41 -0
- data/lib/skylight/normalizers.rb +157 -0
- data/lib/skylight/probes/action_controller.rb +52 -0
- data/lib/skylight/probes/action_dispatch/request_id.rb +33 -0
- data/lib/skylight/probes/action_dispatch/routing/route_set.rb +30 -0
- data/lib/skylight/probes/action_dispatch.rb +2 -0
- data/lib/skylight/probes/action_view.rb +42 -0
- data/lib/skylight/probes/active_job.rb +27 -0
- data/lib/skylight/probes/active_job_enqueue.rb +35 -0
- data/lib/skylight/probes/active_model_serializers.rb +50 -0
- data/lib/skylight/probes/active_record_async.rb +96 -0
- data/lib/skylight/probes/delayed_job.rb +144 -0
- data/lib/skylight/probes/elasticsearch.rb +36 -0
- data/lib/skylight/probes/excon/middleware.rb +65 -0
- data/lib/skylight/probes/excon.rb +25 -0
- data/lib/skylight/probes/faraday.rb +23 -0
- data/lib/skylight/probes/graphql.rb +38 -0
- data/lib/skylight/probes/httpclient.rb +44 -0
- data/lib/skylight/probes/middleware.rb +135 -0
- data/lib/skylight/probes/mongo.rb +156 -0
- data/lib/skylight/probes/mongoid.rb +13 -0
- data/lib/skylight/probes/net_http.rb +54 -0
- data/lib/skylight/probes/rack_builder.rb +37 -0
- data/lib/skylight/probes/redis.rb +51 -0
- data/lib/skylight/probes/sequel.rb +29 -0
- data/lib/skylight/probes/sinatra.rb +66 -0
- data/lib/skylight/probes/sinatra_add_middleware.rb +10 -10
- data/lib/skylight/probes/tilt.rb +25 -0
- data/lib/skylight/probes.rb +173 -0
- data/lib/skylight/railtie.rb +166 -28
- data/lib/skylight/sidekiq.rb +47 -0
- data/lib/skylight/sinatra.rb +1 -1
- data/lib/skylight/subscriber.rb +130 -0
- data/lib/skylight/test.rb +147 -0
- data/lib/skylight/trace.rb +325 -22
- data/lib/skylight/user_config.rb +58 -0
- data/lib/skylight/util/allocation_free.rb +26 -0
- data/lib/skylight/util/clock.rb +57 -0
- data/lib/skylight/util/component.rb +22 -22
- data/lib/skylight/util/deploy.rb +19 -24
- data/lib/skylight/util/gzip.rb +20 -0
- data/lib/skylight/util/http.rb +106 -113
- data/lib/skylight/util/instrumenter_method.rb +26 -0
- data/lib/skylight/util/logging.rb +136 -0
- data/lib/skylight/util/lru_cache.rb +36 -0
- data/lib/skylight/util/platform.rb +3 -7
- data/lib/skylight/util/ssl.rb +1 -25
- data/lib/skylight/util.rb +12 -0
- data/lib/skylight/vendor/cli/thor/rake_compat.rb +1 -1
- data/lib/skylight/version.rb +5 -1
- data/lib/skylight/vm/gc.rb +60 -0
- data/lib/skylight.rb +201 -14
- metadata +134 -18
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
module Normalizers
|
|
3
|
+
# Base Normalizer for Rails rendering
|
|
4
|
+
class RenderNormalizer < Normalizer
|
|
5
|
+
include Skylight::Util::AllocationFree
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
@paths = []
|
|
9
|
+
|
|
10
|
+
Gem.path.each do |path|
|
|
11
|
+
@paths << "#{path}/bundler/gems".freeze
|
|
12
|
+
@paths << "#{path}/gems".freeze
|
|
13
|
+
@paths << path
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
@paths.concat(Array(config["normalizers.render.view_paths"]))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Generic normalizer for renders
|
|
20
|
+
# @param category [String]
|
|
21
|
+
# @param payload [Hash]
|
|
22
|
+
# @option payload [String] :identifier
|
|
23
|
+
# @return [Array]
|
|
24
|
+
def normalize_render(category, payload)
|
|
25
|
+
if (path = payload[:identifier])
|
|
26
|
+
title = relative_path(path)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
[category, title, nil]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def relative_path(path)
|
|
33
|
+
return path if relative_path?(path)
|
|
34
|
+
|
|
35
|
+
if (root = array_find(@paths) { |p| path.start_with?(p) })
|
|
36
|
+
start = root.size
|
|
37
|
+
start += 1 if path.getbyte(start) == SEPARATOR_BYTE
|
|
38
|
+
|
|
39
|
+
path[start, path.size].sub(
|
|
40
|
+
# Matches a Gem Version or 12-digit hex (sha)
|
|
41
|
+
# that is preceeded by a `-` and followed by `/`
|
|
42
|
+
# Also matches 'app/views/' if it exists
|
|
43
|
+
%r{-(?:#{Gem::Version::VERSION_PATTERN}|[0-9a-f]{12})/(?:app/views/)*},
|
|
44
|
+
": ".freeze
|
|
45
|
+
)
|
|
46
|
+
else
|
|
47
|
+
"Absolute Path".freeze
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def relative_path?(path)
|
|
54
|
+
!absolute_path?(path)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
SEPARATOR_BYTE = File::SEPARATOR.ord
|
|
58
|
+
|
|
59
|
+
if File.const_defined?(:NULL) ? File::NULL == "NUL" : RbConfig::CONFIG["host_os"] =~ /mingw|mswin32/
|
|
60
|
+
# This is a DOSish environment
|
|
61
|
+
ALT_SEPARATOR_BYTE = File::ALT_SEPARATOR&.ord
|
|
62
|
+
COLON_BYTE = ":".ord
|
|
63
|
+
SEPARATOR_BYTES = [SEPARATOR_BYTE, ALT_SEPARATOR_BYTE].freeze
|
|
64
|
+
|
|
65
|
+
def absolute_path?(path)
|
|
66
|
+
SEPARATOR_BYTES.include?(path.getbyte(2)) if alpha?(path.getbyte(0)) && path.getbyte(1) == COLON_BYTE
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def alpha?(byte)
|
|
70
|
+
(byte >= 65 && byte <= 90) || (byte >= 97 && byte <= 122)
|
|
71
|
+
end
|
|
72
|
+
else
|
|
73
|
+
def absolute_path?(path)
|
|
74
|
+
path.getbyte(0) == SEPARATOR_BYTE
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
module Normalizers
|
|
3
|
+
class Shrine < Normalizer
|
|
4
|
+
TITLES = {
|
|
5
|
+
"upload.shrine" => "Upload",
|
|
6
|
+
"download.shrine" => "Download",
|
|
7
|
+
"open.shrine" => "Open",
|
|
8
|
+
"exists.shrine" => "Exists",
|
|
9
|
+
"delete.shrine" => "Delete",
|
|
10
|
+
"metadata.shrine" => "Metadata",
|
|
11
|
+
"mime_type.shrine" => "MIME Type",
|
|
12
|
+
"image_dimensions.shrine" => "Image Dimensions",
|
|
13
|
+
"signature.shrine" => "Signature",
|
|
14
|
+
"extension.shrine" => "Extension",
|
|
15
|
+
"derivation.shrine" => "Derivation",
|
|
16
|
+
"derivatives.shrine" => "Derivatives",
|
|
17
|
+
"data_uri.shrine" => "Data URI",
|
|
18
|
+
"remote_url.shrine" => "Remote URL"
|
|
19
|
+
}.freeze
|
|
20
|
+
|
|
21
|
+
TITLES.each_key { |key| register key }
|
|
22
|
+
|
|
23
|
+
def normalize(_trace, name, _payload)
|
|
24
|
+
title = ["Shrine", TITLES[name]].join(" ")
|
|
25
|
+
|
|
26
|
+
cat = "app.#{name.split(".").reverse.join(".")}"
|
|
27
|
+
|
|
28
|
+
[cat, title, nil]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Skylight
|
|
6
|
+
module Normalizers
|
|
7
|
+
# Normalizer for SQL requests
|
|
8
|
+
class SQL < Normalizer
|
|
9
|
+
CAT = "db.sql.query"
|
|
10
|
+
|
|
11
|
+
# @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
|
|
12
|
+
# @param name [String] ignored, only present to match API
|
|
13
|
+
# @param payload [Hash]
|
|
14
|
+
# @option payload [String] [:name] The SQL operation
|
|
15
|
+
# @option payload [Hash] [:binds] The bound parameters
|
|
16
|
+
# @return [Array]
|
|
17
|
+
def normalize(_trace, _name, payload)
|
|
18
|
+
return :skip if payload[:name] == "SCHEMA" || payload[:name] == "CACHE"
|
|
19
|
+
|
|
20
|
+
title = payload[:name] || "SQL"
|
|
21
|
+
|
|
22
|
+
# We can only handle UTF-8 encoded strings.
|
|
23
|
+
# (Construction method here avoids extra allocations)
|
|
24
|
+
sql = String.new.concat("<sk-sql>", payload[:sql], "</sk-sql>").force_encoding(Encoding::UTF_8)
|
|
25
|
+
|
|
26
|
+
unless sql.valid_encoding?
|
|
27
|
+
if config[:log_sql_parse_errors]
|
|
28
|
+
config.logger.error "[#{Skylight::SqlLexError.formatted_code}] Unable to extract binds from non-UTF-8 " \
|
|
29
|
+
"query. " \
|
|
30
|
+
"encoding=#{payload[:sql].encoding.name} " \
|
|
31
|
+
"sql=#{payload[:sql].inspect} "
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
sql = nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
[CAT, title, sql]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
# @api private
|
|
3
|
+
# Convert AS::N events to Skylight events
|
|
4
|
+
module Normalizers
|
|
5
|
+
def self.registry
|
|
6
|
+
@registry ||= {}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.register(name, klass, opts = {})
|
|
10
|
+
enabled = opts[:enabled] != false
|
|
11
|
+
registry[name] = [klass, enabled]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.unregister(name)
|
|
15
|
+
@registry.delete(name)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.enable(*names, enabled: true)
|
|
19
|
+
names.each do |name|
|
|
20
|
+
matches = registry.select { |n, _| n =~ /(^|\.)#{name}$/ }
|
|
21
|
+
raise ArgumentError, "no normalizers match #{name}" if matches.empty?
|
|
22
|
+
|
|
23
|
+
matches.each_value { |v| v[1] = enabled }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.disable(*names)
|
|
28
|
+
enable(*names, enabled: false)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.build(config)
|
|
32
|
+
normalizers = {}
|
|
33
|
+
|
|
34
|
+
registry.each do |key, (klass, enabled)|
|
|
35
|
+
next unless enabled
|
|
36
|
+
|
|
37
|
+
unless klass.method_defined?(:normalize)
|
|
38
|
+
# TODO: Warn
|
|
39
|
+
next
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
normalizers[key] = klass.new(config)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
Container.new(normalizers)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class Normalizer
|
|
49
|
+
def self.register(name, opts = {})
|
|
50
|
+
Normalizers.register(name, self, opts)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
attr_reader :config
|
|
54
|
+
|
|
55
|
+
include Util::Logging
|
|
56
|
+
|
|
57
|
+
def initialize(config)
|
|
58
|
+
@config = config
|
|
59
|
+
setup if respond_to?(:setup)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def normalize(_trace, _name, _payload)
|
|
63
|
+
:skip
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def normalize_with_meta(trace, name, payload)
|
|
67
|
+
# If we have a normal response but no meta, add it
|
|
68
|
+
cat, title, desc, meta = ret = normalize(trace, name, payload)
|
|
69
|
+
return cat if cat == :skip
|
|
70
|
+
|
|
71
|
+
meta ||= {}
|
|
72
|
+
cache_key = ret.hash
|
|
73
|
+
process_meta(trace, name, payload, meta, cache_key: cache_key)
|
|
74
|
+
|
|
75
|
+
[cat, title, desc, meta]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def normalize_after(trace, span, name, payload); end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
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
|
+
|
|
91
|
+
def process_meta_options(_payload)
|
|
92
|
+
{}
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
require "skylight/normalizers/default"
|
|
97
|
+
DEFAULT = Default.new
|
|
98
|
+
|
|
99
|
+
class Container
|
|
100
|
+
def initialize(normalizers)
|
|
101
|
+
@normalizers = normalizers
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def keys
|
|
105
|
+
@normalizers.keys
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def each_key(&block)
|
|
109
|
+
@normalizers.each_key(&block)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def normalize(trace, name, payload)
|
|
113
|
+
normalizer_for(name).normalize_with_meta(trace, name, payload)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def normalize_after(trace, span, name, payload)
|
|
117
|
+
normalizer_for(name).normalize_after(trace, span, name, payload)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def normalizer_for(name)
|
|
121
|
+
# We never expect to hit the default case since we only register listeners
|
|
122
|
+
# for items that we know have normalizers. For now, though, we'll play it
|
|
123
|
+
# safe and provide a fallback.
|
|
124
|
+
@normalizers.fetch(name, DEFAULT)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
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}" }
|
|
156
|
+
end
|
|
157
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
module Probes
|
|
3
|
+
module ActionController
|
|
4
|
+
class Probe
|
|
5
|
+
def install
|
|
6
|
+
# Prepending doesn't work here since this a module that's already been included
|
|
7
|
+
::ActionController::Instrumentation.class_eval do
|
|
8
|
+
private
|
|
9
|
+
|
|
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
|
+
|
|
14
|
+
payload[:sk_rendered_format] = sk_rendered_mime.try(:ref)
|
|
15
|
+
payload[:sk_variant] = request.respond_to?(:variant) ? request.variant : nil
|
|
16
|
+
end
|
|
17
|
+
|
|
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
|
+
|
|
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
|
|
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
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
register(
|
|
46
|
+
:action_controller,
|
|
47
|
+
"ActionController::Instrumentation",
|
|
48
|
+
"action_controller/metal/instrumentation",
|
|
49
|
+
ActionController::Probe.new
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
module Probes
|
|
3
|
+
module ActionDispatch
|
|
4
|
+
module RequestId
|
|
5
|
+
module Instrumentation
|
|
6
|
+
def call(env)
|
|
7
|
+
@skylight_request_id = env["skylight.request_id"]
|
|
8
|
+
super
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def internal_request_id
|
|
14
|
+
@skylight_request_id || super
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Probe
|
|
19
|
+
def install
|
|
20
|
+
::ActionDispatch::RequestId.prepend(Instrumentation)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
register(
|
|
27
|
+
:action_dispatch,
|
|
28
|
+
"ActionDispatch::RequestId",
|
|
29
|
+
"action_dispatch/middleware/request_id",
|
|
30
|
+
ActionDispatch::RequestId::Probe.new
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Skylight
|
|
4
|
+
module Probes
|
|
5
|
+
module ActionDispatch
|
|
6
|
+
module Routing
|
|
7
|
+
module RouteSet
|
|
8
|
+
module Instrumentation
|
|
9
|
+
def call(env)
|
|
10
|
+
ActiveSupport::Notifications.instrument("route_set.action_dispatch") { super }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class Probe
|
|
15
|
+
def install
|
|
16
|
+
::ActionDispatch::Routing::RouteSet.prepend(Instrumentation)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
register(
|
|
24
|
+
:rails_router,
|
|
25
|
+
"ActionDispatch::Routing::RouteSet",
|
|
26
|
+
"action_dispatch/routing/route_set",
|
|
27
|
+
ActionDispatch::Routing::RouteSet::Probe.new
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Skylight
|
|
4
|
+
module Probes
|
|
5
|
+
module ActionView
|
|
6
|
+
module Instrumentation
|
|
7
|
+
def render_with_layout(*args) #:nodoc:
|
|
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
|
|
16
|
+
|
|
17
|
+
layout = nil
|
|
18
|
+
|
|
19
|
+
layout = find_layout(path, locals.keys, [formats.first]) if path
|
|
20
|
+
|
|
21
|
+
if layout
|
|
22
|
+
ActiveSupport::Notifications.instrument("render_template.action_view", identifier: layout.identifier) do
|
|
23
|
+
super
|
|
24
|
+
end
|
|
25
|
+
else
|
|
26
|
+
super
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class Probe
|
|
32
|
+
def install
|
|
33
|
+
return if ::ActionView.gem_version >= Gem::Version.new("6.1.0.alpha")
|
|
34
|
+
|
|
35
|
+
::ActionView::TemplateRenderer.prepend(Instrumentation)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
register(:action_view, "ActionView::TemplateRenderer", "action_view", ActionView::Probe.new)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
module Probes
|
|
3
|
+
module ActiveJob
|
|
4
|
+
TITLE = "ActiveJob.execute".freeze
|
|
5
|
+
|
|
6
|
+
module Instrumentation
|
|
7
|
+
def execute(*)
|
|
8
|
+
Skylight.trace(TITLE, "app.job.execute", component: :worker) do |trace|
|
|
9
|
+
# See normalizers/active_job/perform for endpoint/segment assignment
|
|
10
|
+
super
|
|
11
|
+
rescue Exception
|
|
12
|
+
trace.segment = "error" if trace
|
|
13
|
+
raise
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Probe
|
|
19
|
+
def install
|
|
20
|
+
::ActiveJob::Base.singleton_class.prepend(Instrumentation)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
register(:active_job, "ActiveJob::Base", "active_job/base", ActiveJob::Probe.new)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
module Probes
|
|
3
|
+
module ActiveJob
|
|
4
|
+
class EnqueueProbe
|
|
5
|
+
CAT = "other.active_job.enqueue".freeze
|
|
6
|
+
|
|
7
|
+
def install
|
|
8
|
+
::ActiveJob::Base.around_enqueue do |job, block|
|
|
9
|
+
job_class = job.class
|
|
10
|
+
adapter_name = EnqueueProbe.normalize_adapter_name(job_class)
|
|
11
|
+
|
|
12
|
+
# If this is an ActionMailer::DeliveryJob, we'll report this as the mailer title
|
|
13
|
+
# and include ActionMailer::DeliveryJob in the description.
|
|
14
|
+
name, job_class_name = Normalizers::ActiveJob::Perform.normalize_title(job)
|
|
15
|
+
descriptors = ["adapter: '#{adapter_name}'", "queue: '#{job.queue_name}'"]
|
|
16
|
+
descriptors << "job: '#{job_class_name}'" if job_class_name
|
|
17
|
+
desc = "{ #{descriptors.join(", ")} }"
|
|
18
|
+
rescue StandardError
|
|
19
|
+
block.call
|
|
20
|
+
else
|
|
21
|
+
Skylight.instrument(title: "Enqueue #{name}", category: CAT, description: desc, internal: true, &block)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
self.class.instance_eval do
|
|
25
|
+
def normalize_adapter_name(job_class)
|
|
26
|
+
job_class.queue_adapter_name
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
register(:active_job_enqueue, "ActiveJob::Base", "active_job/base", ActiveJob::EnqueueProbe.new)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Skylight
|
|
2
|
+
module Probes
|
|
3
|
+
module ActiveModelSerializers
|
|
4
|
+
module Instrumentation
|
|
5
|
+
def as_json(*)
|
|
6
|
+
payload = { serializer: self.class }
|
|
7
|
+
ActiveSupport::Notifications.instrument("render.active_model_serializers", payload) { super }
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class Probe
|
|
12
|
+
def install
|
|
13
|
+
version = nil
|
|
14
|
+
|
|
15
|
+
# File moved location between version
|
|
16
|
+
%w[serializer serializers].each do |dir|
|
|
17
|
+
require "active_model/#{dir}/version"
|
|
18
|
+
rescue LoadError # rubocop:disable Lint/SuppressedException
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
version = Gem.loaded_specs["active_model_serializers"].version if Gem.loaded_specs["active_model_serializers"]
|
|
22
|
+
|
|
23
|
+
if !version || version < Gem::Version.new("0.5.0")
|
|
24
|
+
Skylight.error "Instrumention is only available for ActiveModelSerializers version 0.5.0 and greater."
|
|
25
|
+
return
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# We don't actually support the RCs correctly, requires
|
|
29
|
+
# a release after 0.10.0.rc3
|
|
30
|
+
if version >= Gem::Version.new("0.10.0.rc1")
|
|
31
|
+
# AS::N is built in to newer versions
|
|
32
|
+
return
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# End users could override as_json without calling super, but it's likely safer
|
|
36
|
+
# than overriding serializable_array/hash/object.
|
|
37
|
+
|
|
38
|
+
[::ActiveModel::Serializer, ::ActiveModel::ArraySerializer].each { |klass| klass.prepend(Instrumentation) }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
register(
|
|
44
|
+
:active_model_serializers,
|
|
45
|
+
"ActiveModel::Serializer",
|
|
46
|
+
"active_model/serializer",
|
|
47
|
+
ActiveModelSerializers::Probe.new
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
end
|