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.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +399 -336
  3. data/CLA.md +1 -1
  4. data/CONTRIBUTING.md +2 -8
  5. data/LICENSE.md +7 -17
  6. data/README.md +1 -1
  7. data/ext/extconf.rb +45 -56
  8. data/ext/libskylight.yml +10 -6
  9. data/ext/skylight_native.c +22 -99
  10. data/lib/skylight.rb +201 -14
  11. data/lib/skylight/api.rb +32 -21
  12. data/lib/skylight/cli.rb +48 -46
  13. data/lib/skylight/cli/doctor.rb +62 -63
  14. data/lib/skylight/cli/helpers.rb +19 -19
  15. data/lib/skylight/cli/merger.rb +142 -138
  16. data/lib/skylight/config.rb +634 -199
  17. data/lib/skylight/deprecation.rb +17 -0
  18. data/lib/skylight/errors.rb +23 -9
  19. data/lib/skylight/extensions.rb +95 -0
  20. data/lib/skylight/extensions/source_location.rb +291 -0
  21. data/lib/skylight/formatters/http.rb +18 -0
  22. data/lib/skylight/gc.rb +99 -0
  23. data/lib/skylight/helpers.rb +81 -36
  24. data/lib/skylight/instrumenter.rb +336 -18
  25. data/lib/skylight/middleware.rb +134 -1
  26. data/lib/skylight/native.rb +60 -12
  27. data/lib/skylight/native_ext_fetcher.rb +13 -14
  28. data/lib/skylight/normalizers.rb +157 -0
  29. data/lib/skylight/normalizers/action_controller/process_action.rb +68 -0
  30. data/lib/skylight/normalizers/action_controller/send_file.rb +51 -0
  31. data/lib/skylight/normalizers/action_dispatch/process_middleware.rb +22 -0
  32. data/lib/skylight/normalizers/action_dispatch/route_set.rb +27 -0
  33. data/lib/skylight/normalizers/action_view/render_collection.rb +24 -0
  34. data/lib/skylight/normalizers/action_view/render_layout.rb +25 -0
  35. data/lib/skylight/normalizers/action_view/render_partial.rb +23 -0
  36. data/lib/skylight/normalizers/action_view/render_template.rb +23 -0
  37. data/lib/skylight/normalizers/active_job/perform.rb +90 -0
  38. data/lib/skylight/normalizers/active_model_serializers/render.rb +32 -0
  39. data/lib/skylight/normalizers/active_record/instantiation.rb +16 -0
  40. data/lib/skylight/normalizers/active_record/sql.rb +12 -0
  41. data/lib/skylight/normalizers/active_storage.rb +28 -0
  42. data/lib/skylight/normalizers/active_support/cache.rb +11 -0
  43. data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
  44. data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
  45. data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
  46. data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
  47. data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
  48. data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
  49. data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
  50. data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
  51. data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
  52. data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
  53. data/lib/skylight/normalizers/coach/handler_finish.rb +44 -0
  54. data/lib/skylight/normalizers/coach/middleware_finish.rb +33 -0
  55. data/lib/skylight/normalizers/couch_potato/query.rb +20 -0
  56. data/lib/skylight/normalizers/data_mapper/sql.rb +12 -0
  57. data/lib/skylight/normalizers/default.rb +24 -0
  58. data/lib/skylight/normalizers/elasticsearch/request.rb +20 -0
  59. data/lib/skylight/normalizers/faraday/request.rb +38 -0
  60. data/lib/skylight/normalizers/grape/endpoint.rb +28 -0
  61. data/lib/skylight/normalizers/grape/endpoint_render.rb +25 -0
  62. data/lib/skylight/normalizers/grape/endpoint_run.rb +39 -0
  63. data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +20 -0
  64. data/lib/skylight/normalizers/grape/format_response.rb +20 -0
  65. data/lib/skylight/normalizers/graphiti/render.rb +22 -0
  66. data/lib/skylight/normalizers/graphiti/resolve.rb +31 -0
  67. data/lib/skylight/normalizers/graphql/base.rb +127 -0
  68. data/lib/skylight/normalizers/render.rb +79 -0
  69. data/lib/skylight/normalizers/sequel/sql.rb +12 -0
  70. data/lib/skylight/normalizers/shrine.rb +32 -0
  71. data/lib/skylight/normalizers/sql.rb +45 -0
  72. data/lib/skylight/probes.rb +173 -0
  73. data/lib/skylight/probes/action_controller.rb +52 -0
  74. data/lib/skylight/probes/action_dispatch.rb +2 -0
  75. data/lib/skylight/probes/action_dispatch/request_id.rb +33 -0
  76. data/lib/skylight/probes/action_dispatch/routing/route_set.rb +30 -0
  77. data/lib/skylight/probes/action_view.rb +42 -0
  78. data/lib/skylight/probes/active_job.rb +27 -0
  79. data/lib/skylight/probes/active_job_enqueue.rb +35 -0
  80. data/lib/skylight/probes/active_model_serializers.rb +50 -0
  81. data/lib/skylight/probes/delayed_job.rb +144 -0
  82. data/lib/skylight/probes/elasticsearch.rb +36 -0
  83. data/lib/skylight/probes/excon.rb +25 -0
  84. data/lib/skylight/probes/excon/middleware.rb +65 -0
  85. data/lib/skylight/probes/faraday.rb +23 -0
  86. data/lib/skylight/probes/graphql.rb +38 -0
  87. data/lib/skylight/probes/httpclient.rb +44 -0
  88. data/lib/skylight/probes/middleware.rb +135 -0
  89. data/lib/skylight/probes/mongo.rb +156 -0
  90. data/lib/skylight/probes/mongoid.rb +13 -0
  91. data/lib/skylight/probes/net_http.rb +54 -0
  92. data/lib/skylight/probes/redis.rb +51 -0
  93. data/lib/skylight/probes/sequel.rb +29 -0
  94. data/lib/skylight/probes/sinatra.rb +66 -0
  95. data/lib/skylight/probes/sinatra_add_middleware.rb +10 -10
  96. data/lib/skylight/probes/tilt.rb +25 -0
  97. data/lib/skylight/railtie.rb +157 -27
  98. data/lib/skylight/sidekiq.rb +47 -0
  99. data/lib/skylight/subscriber.rb +108 -0
  100. data/lib/skylight/test.rb +151 -0
  101. data/lib/skylight/trace.rb +325 -22
  102. data/lib/skylight/user_config.rb +58 -0
  103. data/lib/skylight/util.rb +12 -0
  104. data/lib/skylight/util/allocation_free.rb +26 -0
  105. data/lib/skylight/util/clock.rb +57 -0
  106. data/lib/skylight/util/component.rb +22 -22
  107. data/lib/skylight/util/deploy.rb +16 -21
  108. data/lib/skylight/util/gzip.rb +20 -0
  109. data/lib/skylight/util/http.rb +106 -113
  110. data/lib/skylight/util/instrumenter_method.rb +26 -0
  111. data/lib/skylight/util/logging.rb +136 -0
  112. data/lib/skylight/util/lru_cache.rb +36 -0
  113. data/lib/skylight/util/platform.rb +1 -5
  114. data/lib/skylight/util/ssl.rb +1 -25
  115. data/lib/skylight/vendor/cli/thor/rake_compat.rb +1 -1
  116. data/lib/skylight/version.rb +5 -1
  117. data/lib/skylight/vm/gc.rb +60 -0
  118. metadata +126 -13
@@ -1,4 +1,137 @@
1
+ require "securerandom"
2
+
1
3
  module Skylight
2
- class Middleware < Core::Middleware
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
@@ -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
- Skylight::Core::Util::Clock.use_native!
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
- # Note: An unsupported arch doesn't count as an error.
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
- "[SKYLIGHT] [#{Skylight::VERSION}] The Skylight native extension failed to install. " \
60
- "Please check #{install_log} and notify support@skylight.io. " \
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
- "[SKYLIGHT] [#{Skylight::VERSION}] The Skylight native extension for " \
69
- "your platform wasn't found. Supported operating systems are " \
70
- "Linux 2.6.18+ and Mac OS X 10.8+. The missing extension will not " \
71
- "affect the functioning of your application. If you are on a " \
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; end
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(STDOUT)
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, logger:)
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
- "requested-arch=#{@arch}; version=#{@version}"
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}; remaining-attempts=#{remaining_attempts}", e
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 [:success, digest.hexdigest]
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 [:redirect, location]
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