skylight 4.3.2 → 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 +399 -336
- data/CLA.md +1 -1
- data/CONTRIBUTING.md +2 -8
- data/LICENSE.md +7 -17
- data/README.md +1 -1
- data/ext/extconf.rb +45 -56
- data/ext/libskylight.yml +10 -6
- data/ext/skylight_native.c +22 -99
- data/lib/skylight.rb +201 -14
- data/lib/skylight/api.rb +32 -21
- data/lib/skylight/cli.rb +48 -46
- data/lib/skylight/cli/doctor.rb +62 -63
- data/lib/skylight/cli/helpers.rb +19 -19
- data/lib/skylight/cli/merger.rb +142 -138
- data/lib/skylight/config.rb +634 -199
- data/lib/skylight/deprecation.rb +17 -0
- data/lib/skylight/errors.rb +23 -9
- data/lib/skylight/extensions.rb +95 -0
- data/lib/skylight/extensions/source_location.rb +291 -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 +134 -1
- data/lib/skylight/native.rb +60 -12
- data/lib/skylight/native_ext_fetcher.rb +13 -14
- data/lib/skylight/normalizers.rb +157 -0
- 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 +90 -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 +12 -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 +45 -0
- data/lib/skylight/probes.rb +173 -0
- data/lib/skylight/probes/action_controller.rb +52 -0
- data/lib/skylight/probes/action_dispatch.rb +2 -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_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/delayed_job.rb +144 -0
- data/lib/skylight/probes/elasticsearch.rb +36 -0
- data/lib/skylight/probes/excon.rb +25 -0
- data/lib/skylight/probes/excon/middleware.rb +65 -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/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/railtie.rb +157 -27
- data/lib/skylight/sidekiq.rb +47 -0
- data/lib/skylight/subscriber.rb +108 -0
- data/lib/skylight/test.rb +151 -0
- data/lib/skylight/trace.rb +325 -22
- data/lib/skylight/user_config.rb +58 -0
- data/lib/skylight/util.rb +12 -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 +16 -21
- 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 +1 -5
- data/lib/skylight/util/ssl.rb +1 -25
- 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
- metadata +126 -13
data/lib/skylight/middleware.rb
CHANGED
|
@@ -1,4 +1,137 @@
|
|
|
1
|
+
require "securerandom"
|
|
2
|
+
|
|
1
3
|
module Skylight
|
|
2
|
-
|
|
4
|
+
# @api private
|
|
5
|
+
class Middleware
|
|
6
|
+
class BodyProxy
|
|
7
|
+
def initialize(body, &block)
|
|
8
|
+
@body = body
|
|
9
|
+
@block = block
|
|
10
|
+
@closed = false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def respond_to_missing?(name, include_all = false)
|
|
14
|
+
return false if name.to_s !~ /^to_ary$/
|
|
15
|
+
|
|
16
|
+
@body.respond_to?(name, include_all)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def close
|
|
20
|
+
return if @closed
|
|
21
|
+
|
|
22
|
+
@closed = true
|
|
23
|
+
begin
|
|
24
|
+
@body.close if @body.respond_to? :close
|
|
25
|
+
ensure
|
|
26
|
+
@block.call
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def closed?
|
|
31
|
+
@closed
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# N.B. This method is a special case to address the bug described by
|
|
35
|
+
# https://github.com/rack/rack/issues/434.
|
|
36
|
+
# We are applying this special case for #each only. Future bugs of this
|
|
37
|
+
# class will be handled by requesting users to patch their ruby
|
|
38
|
+
# implementation, to save adding too many methods in this class.
|
|
39
|
+
def each(*args, &block)
|
|
40
|
+
@body.each(*args, &block)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def method_missing(*args, &block)
|
|
44
|
+
super if args.first.to_s =~ /^to_ary$/
|
|
45
|
+
@body.__send__(*args, &block)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.with_after_close(resp, debug_identifier: "unknown", &block)
|
|
50
|
+
unless resp.respond_to?(:to_ary)
|
|
51
|
+
if resp.respond_to?(:to_a)
|
|
52
|
+
Skylight.warn(
|
|
53
|
+
"Rack response from \"#{debug_identifier}\" cannot be implicitly converted to an array. " \
|
|
54
|
+
"This is in violation of the Rack SPEC and will raise an error in future versions."
|
|
55
|
+
)
|
|
56
|
+
resp = resp.to_a
|
|
57
|
+
else
|
|
58
|
+
Skylight.error(
|
|
59
|
+
"Rack response from \"#{debug_identifier}\" cannot be converted to an array. This is in " \
|
|
60
|
+
"violation of the Rack SPEC and may cause problems with Skylight operation."
|
|
61
|
+
)
|
|
62
|
+
return resp
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
status, headers, body = resp
|
|
67
|
+
[status, headers, BodyProxy.new(body, &block)]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
include Skylight::Util::Logging
|
|
71
|
+
|
|
72
|
+
# For Util::Logging
|
|
73
|
+
attr_reader :config
|
|
74
|
+
|
|
75
|
+
def initialize(app, opts = {})
|
|
76
|
+
@app = app
|
|
77
|
+
@config = opts[:config]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def call(env)
|
|
81
|
+
set_request_id(env)
|
|
82
|
+
|
|
83
|
+
if Skylight.tracing?
|
|
84
|
+
error "Already instrumenting. Make sure the Skylight Rack Middleware hasn't been added more than once."
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
if env["REQUEST_METHOD"] == "HEAD"
|
|
88
|
+
t { "middleware skipping HEAD" }
|
|
89
|
+
@app.call(env)
|
|
90
|
+
else
|
|
91
|
+
begin
|
|
92
|
+
t { "middleware beginning trace" }
|
|
93
|
+
trace = Skylight.trace(endpoint_name(env), "app.rack.request", nil, meta: endpoint_meta(env), component: :web)
|
|
94
|
+
t { "middleware began trace=#{trace ? trace.uuid : nil}" }
|
|
95
|
+
|
|
96
|
+
resp = @app.call(env)
|
|
97
|
+
|
|
98
|
+
trace ? Middleware.with_after_close(resp, debug_identifier: "Rack App: #{@app.class}") { trace.submit } : resp
|
|
99
|
+
rescue Exception => e
|
|
100
|
+
t { "middleware exception: #{e}\n#{e.backtrace.join("\n")}" }
|
|
101
|
+
trace&.submit
|
|
102
|
+
raise
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def log_context
|
|
110
|
+
# Don't cache this, it will change
|
|
111
|
+
{ request_id: @current_request_id, inst: Skylight.instrumenter&.uuid }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Allow for overwriting
|
|
115
|
+
def endpoint_name(_env)
|
|
116
|
+
"Rack"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def endpoint_meta(_env)
|
|
120
|
+
{ source_location: Trace::SYNTHETIC }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Request ID code based on ActionDispatch::RequestId
|
|
124
|
+
def set_request_id(env)
|
|
125
|
+
existing_request_id = env["action_dispatch.request_id"] || env["HTTP_X_REQUEST_ID"]
|
|
126
|
+
@current_request_id = env["skylight.request_id"] = make_request_id(existing_request_id)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def make_request_id(request_id)
|
|
130
|
+
request_id && !request_id.empty? ? request_id.gsub(/[^\w\-]/, "".freeze)[0...255] : internal_request_id
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def internal_request_id
|
|
134
|
+
SecureRandom.uuid
|
|
135
|
+
end
|
|
3
136
|
end
|
|
4
137
|
end
|
data/lib/skylight/native.rb
CHANGED
|
@@ -1,6 +1,55 @@
|
|
|
1
1
|
require "skylight/util/platform"
|
|
2
2
|
|
|
3
3
|
module Skylight
|
|
4
|
+
# Some methods exepected to be defined by the native code (OUTDATED)
|
|
5
|
+
#
|
|
6
|
+
# * Skylight::Util::Clock#native_hrtime
|
|
7
|
+
# - returns current time in nanoseconds
|
|
8
|
+
# * Skylight::Trace#native_new(start, uuid, endpoint)
|
|
9
|
+
# - start is milliseconds
|
|
10
|
+
# - uuid is currently unused
|
|
11
|
+
# - endpoint is the endpoint name
|
|
12
|
+
# - returns an instance of Trace
|
|
13
|
+
# * Skylight::Trace#native_get_started_at
|
|
14
|
+
# - returns the start time
|
|
15
|
+
# * Skylight::Trace#native_get_endpoint
|
|
16
|
+
# - returns the endpoint name
|
|
17
|
+
# * Skylight::Trace#native_set_endpoint(endpoint)
|
|
18
|
+
# - returns nil
|
|
19
|
+
# * Skylight::Trace#native_get_uuid
|
|
20
|
+
# - returns the uuid
|
|
21
|
+
# * Skylight::Trace#native_start_span(time, category)
|
|
22
|
+
# - time is milliseconds
|
|
23
|
+
# - category is a string
|
|
24
|
+
# - returns a numeric span id
|
|
25
|
+
# * Skylight::Trace#native_stop_span(span, time)
|
|
26
|
+
# - span is the span id
|
|
27
|
+
# - time is milliseconds
|
|
28
|
+
# - returns nil
|
|
29
|
+
# * Skylight::Trace#native_span_set_title(span, title)
|
|
30
|
+
# - span is the span id
|
|
31
|
+
# - title is a string
|
|
32
|
+
# - returns nil
|
|
33
|
+
# * Skylight::Trace#native_span_set_description(span, desc)
|
|
34
|
+
# - span is the span id
|
|
35
|
+
# - desc is a string
|
|
36
|
+
# - returns nil
|
|
37
|
+
# * Skylight::Instrumenter#native_new(env)
|
|
38
|
+
# - env is the config converted to a flattened array of ENV style values
|
|
39
|
+
# e.g. `["SKYLIGHT_AUTHENTICATION", "abc123", ...]
|
|
40
|
+
# - returns a new Instrumenter instance
|
|
41
|
+
# * Skylight::Instrumenter#native_start()
|
|
42
|
+
# - returns a truthy value if successful
|
|
43
|
+
# * Skylight::Instrumenter#native_stop()
|
|
44
|
+
# - returns nil
|
|
45
|
+
# * Skylight::Instrumenter#native_submit_trace(trace)
|
|
46
|
+
# - trace is a Trace instance
|
|
47
|
+
# - returns nil
|
|
48
|
+
# * Skylight::Instrumenter#native_track_desc(endpoint, description)
|
|
49
|
+
# - endpoint is a string
|
|
50
|
+
# - description is a string
|
|
51
|
+
# - returns truthy unless uniqueness cap exceeded
|
|
52
|
+
|
|
4
53
|
# @api private
|
|
5
54
|
# Whether or not the native extension is present
|
|
6
55
|
@has_native_ext = false
|
|
@@ -40,7 +89,8 @@ module Skylight
|
|
|
40
89
|
end
|
|
41
90
|
|
|
42
91
|
if Skylight.native?
|
|
43
|
-
|
|
92
|
+
require "skylight/util/clock"
|
|
93
|
+
Util::Clock.use_native!
|
|
44
94
|
else
|
|
45
95
|
class Instrumenter
|
|
46
96
|
def self.native_new(*_args)
|
|
@@ -51,24 +101,22 @@ module Skylight
|
|
|
51
101
|
|
|
52
102
|
# @api private
|
|
53
103
|
def self.check_install_errors(config)
|
|
54
|
-
#
|
|
104
|
+
# NOTE: An unsupported arch doesn't count as an error.
|
|
55
105
|
install_log = File.expand_path("../../ext/install.log", __dir__)
|
|
56
106
|
|
|
57
107
|
if File.exist?(install_log) && File.read(install_log) =~ /ERROR/
|
|
58
|
-
config.alert_logger.error \
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
"The missing extension will not affect the functioning of your application."
|
|
108
|
+
config.alert_logger.error "[SKYLIGHT] [#{Skylight::VERSION}] The Skylight native extension failed to install. " \
|
|
109
|
+
"Please check #{install_log} and notify support@skylight.io. " \
|
|
110
|
+
"The missing extension will not affect the functioning of your application."
|
|
62
111
|
end
|
|
63
112
|
end
|
|
64
113
|
|
|
65
114
|
# @api private
|
|
66
115
|
def self.warn_skylight_native_missing(config)
|
|
67
|
-
config.alert_logger.error \
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"supported platform, please contact support at support@skylight.io."
|
|
116
|
+
config.alert_logger.error "[SKYLIGHT] [#{Skylight::VERSION}] The Skylight native extension for " \
|
|
117
|
+
"your platform wasn't found. Supported operating systems are " \
|
|
118
|
+
"Linux 2.6.18+ and Mac OS X 10.8+. The missing extension will not " \
|
|
119
|
+
"affect the functioning of your application. If you are on a " \
|
|
120
|
+
"supported platform, please contact support at support@skylight.io."
|
|
73
121
|
end
|
|
74
122
|
end
|
|
@@ -17,13 +17,14 @@ module Skylight
|
|
|
17
17
|
|
|
18
18
|
include FileUtils
|
|
19
19
|
|
|
20
|
-
class FetchError < StandardError
|
|
20
|
+
class FetchError < StandardError
|
|
21
|
+
end
|
|
21
22
|
|
|
22
23
|
# Creates a new fetcher and fetches
|
|
23
24
|
# @param opts [Hash]
|
|
24
25
|
def self.fetch(**args)
|
|
25
26
|
args[:source] ||= BASE_URL
|
|
26
|
-
args[:logger] ||= Logger.new(
|
|
27
|
+
args[:logger] ||= Logger.new($stdout)
|
|
27
28
|
new(**args).fetch
|
|
28
29
|
end
|
|
29
30
|
|
|
@@ -35,7 +36,7 @@ module Skylight
|
|
|
35
36
|
# @param required [Boolean] whether the download is required to be successful
|
|
36
37
|
# @param platform
|
|
37
38
|
# @param log [Logger]
|
|
38
|
-
def initialize(source:, target:, version:, checksum:, arch:, required: false, platform: nil
|
|
39
|
+
def initialize(source:, target:, version:, checksum:, arch:, logger:, required: false, platform: nil)
|
|
39
40
|
raise "source required" unless source
|
|
40
41
|
raise "target required" unless target
|
|
41
42
|
raise "checksum required" unless checksum
|
|
@@ -56,7 +57,7 @@ module Skylight
|
|
|
56
57
|
# @return [String] the inflated archive
|
|
57
58
|
def fetch
|
|
58
59
|
log "fetching native ext; curr-platform=#{@platform}; " \
|
|
59
|
-
|
|
60
|
+
"requested-arch=#{@arch}; version=#{@version}"
|
|
60
61
|
|
|
61
62
|
tar_gz = "#{@target}/#{basename}"
|
|
62
63
|
|
|
@@ -109,10 +110,12 @@ module Skylight
|
|
|
109
110
|
next
|
|
110
111
|
end
|
|
111
112
|
end
|
|
112
|
-
rescue => e
|
|
113
|
+
rescue StandardError => e
|
|
113
114
|
remaining_attempts -= 1
|
|
114
115
|
|
|
115
|
-
error "failed to fetch native extension; uri=#{uri}; msg=#{e.message};
|
|
116
|
+
error "failed to fetch native extension; uri=#{uri}; msg=#{e.message}; " \
|
|
117
|
+
"remaining-attempts=#{remaining_attempts}",
|
|
118
|
+
e
|
|
116
119
|
|
|
117
120
|
if remaining_attempts > 0
|
|
118
121
|
sleep 2
|
|
@@ -148,9 +151,7 @@ module Skylight
|
|
|
148
151
|
opts = {}
|
|
149
152
|
opts[:use_ssl] = use_ssl
|
|
150
153
|
|
|
151
|
-
if use_ssl
|
|
152
|
-
opts[:ca_file] = Util::SSL.ca_cert_file_or_default
|
|
153
|
-
end
|
|
154
|
+
opts[:ca_file] = Util::SSL.ca_cert_file_or_default if use_ssl
|
|
154
155
|
|
|
155
156
|
Net::HTTP.start(host, port, p_host, p_port, p_user, p_pass, use_ssl: use_ssl) do |http|
|
|
156
157
|
http.request_get path do |resp|
|
|
@@ -163,13 +164,13 @@ module Skylight
|
|
|
163
164
|
out.write chunk
|
|
164
165
|
end
|
|
165
166
|
|
|
166
|
-
return
|
|
167
|
+
return :success, digest.hexdigest
|
|
167
168
|
when Net::HTTPRedirection
|
|
168
169
|
unless (location = resp["location"])
|
|
169
170
|
raise "received redirect but no location"
|
|
170
171
|
end
|
|
171
172
|
|
|
172
|
-
return
|
|
173
|
+
return :redirect, location
|
|
173
174
|
else
|
|
174
175
|
raise "received HTTP status code #{resp.code}"
|
|
175
176
|
end
|
|
@@ -220,9 +221,7 @@ module Skylight
|
|
|
220
221
|
def maybe_raise(err)
|
|
221
222
|
error err
|
|
222
223
|
|
|
223
|
-
if @required
|
|
224
|
-
raise err
|
|
225
|
-
end
|
|
224
|
+
raise err if @required
|
|
226
225
|
end
|
|
227
226
|
|
|
228
227
|
# Log an `info` to the `logger`
|
|
@@ -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
|