skylight 3.1.4 → 5.3.4

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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +465 -294
  3. data/CLA.md +1 -1
  4. data/CONTRIBUTING.md +11 -3
  5. data/ERRORS.md +3 -0
  6. data/LICENSE.md +8 -18
  7. data/README.md +1 -2
  8. data/bin/skylight +1 -1
  9. data/ext/extconf.rb +118 -122
  10. data/ext/libskylight.yml +8 -6
  11. data/ext/skylight_native.c +56 -100
  12. data/lib/skylight/api.rb +41 -27
  13. data/lib/skylight/cli/doctor.rb +68 -70
  14. data/lib/skylight/cli/helpers.rb +3 -5
  15. data/lib/skylight/cli/merger.rb +99 -92
  16. data/lib/skylight/cli.rb +40 -43
  17. data/lib/skylight/config.rb +656 -201
  18. data/lib/skylight/data/cacert.pem +730 -1023
  19. data/lib/skylight/deprecation.rb +17 -0
  20. data/lib/skylight/errors.rb +34 -16
  21. data/lib/skylight/extensions/source_location.rb +291 -0
  22. data/lib/skylight/extensions.rb +95 -0
  23. data/lib/skylight/formatters/http.rb +18 -0
  24. data/lib/skylight/gc.rb +99 -0
  25. data/lib/skylight/helpers.rb +82 -39
  26. data/lib/skylight/instrumenter.rb +339 -9
  27. data/lib/skylight/middleware.rb +147 -1
  28. data/lib/skylight/native.rb +71 -23
  29. data/lib/skylight/native_ext_fetcher.rb +39 -47
  30. data/lib/skylight/normalizers/action_controller/process_action.rb +68 -0
  31. data/lib/skylight/normalizers/action_controller/send_file.rb +51 -0
  32. data/lib/skylight/normalizers/action_dispatch/process_middleware.rb +22 -0
  33. data/lib/skylight/normalizers/action_dispatch/route_set.rb +27 -0
  34. data/lib/skylight/normalizers/action_view/render_collection.rb +24 -0
  35. data/lib/skylight/normalizers/action_view/render_layout.rb +25 -0
  36. data/lib/skylight/normalizers/action_view/render_partial.rb +23 -0
  37. data/lib/skylight/normalizers/action_view/render_template.rb +23 -0
  38. data/lib/skylight/normalizers/active_job/perform.rb +87 -0
  39. data/lib/skylight/normalizers/active_model_serializers/render.rb +32 -0
  40. data/lib/skylight/normalizers/active_record/instantiation.rb +16 -0
  41. data/lib/skylight/normalizers/active_record/sql.rb +20 -0
  42. data/lib/skylight/normalizers/active_storage.rb +28 -0
  43. data/lib/skylight/normalizers/active_support/cache.rb +11 -0
  44. data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
  45. data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
  46. data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
  47. data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
  48. data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
  49. data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
  50. data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
  51. data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
  52. data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
  53. data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
  54. data/lib/skylight/normalizers/coach/handler_finish.rb +44 -0
  55. data/lib/skylight/normalizers/coach/middleware_finish.rb +33 -0
  56. data/lib/skylight/normalizers/couch_potato/query.rb +20 -0
  57. data/lib/skylight/normalizers/data_mapper/sql.rb +12 -0
  58. data/lib/skylight/normalizers/default.rb +24 -0
  59. data/lib/skylight/normalizers/elasticsearch/request.rb +20 -0
  60. data/lib/skylight/normalizers/faraday/request.rb +38 -0
  61. data/lib/skylight/normalizers/grape/endpoint.rb +28 -0
  62. data/lib/skylight/normalizers/grape/endpoint_render.rb +25 -0
  63. data/lib/skylight/normalizers/grape/endpoint_run.rb +39 -0
  64. data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +20 -0
  65. data/lib/skylight/normalizers/grape/format_response.rb +20 -0
  66. data/lib/skylight/normalizers/graphiti/render.rb +22 -0
  67. data/lib/skylight/normalizers/graphiti/resolve.rb +31 -0
  68. data/lib/skylight/normalizers/graphql/base.rb +127 -0
  69. data/lib/skylight/normalizers/render.rb +79 -0
  70. data/lib/skylight/normalizers/sequel/sql.rb +12 -0
  71. data/lib/skylight/normalizers/shrine.rb +32 -0
  72. data/lib/skylight/normalizers/sql.rb +41 -0
  73. data/lib/skylight/normalizers.rb +157 -0
  74. data/lib/skylight/probes/action_controller.rb +52 -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_dispatch.rb +2 -0
  78. data/lib/skylight/probes/action_view.rb +42 -0
  79. data/lib/skylight/probes/active_job.rb +27 -0
  80. data/lib/skylight/probes/active_job_enqueue.rb +35 -0
  81. data/lib/skylight/probes/active_model_serializers.rb +50 -0
  82. data/lib/skylight/probes/active_record_async.rb +96 -0
  83. data/lib/skylight/probes/delayed_job.rb +144 -0
  84. data/lib/skylight/probes/elasticsearch.rb +45 -0
  85. data/lib/skylight/probes/excon/middleware.rb +65 -0
  86. data/lib/skylight/probes/excon.rb +25 -0
  87. data/lib/skylight/probes/faraday.rb +23 -0
  88. data/lib/skylight/probes/graphql.rb +38 -0
  89. data/lib/skylight/probes/httpclient.rb +44 -0
  90. data/lib/skylight/probes/middleware.rb +135 -0
  91. data/lib/skylight/probes/mongo.rb +169 -0
  92. data/lib/skylight/probes/mongoid.rb +6 -0
  93. data/lib/skylight/probes/net_http.rb +54 -0
  94. data/lib/skylight/probes/rack_builder.rb +37 -0
  95. data/lib/skylight/probes/redis.rb +68 -0
  96. data/lib/skylight/probes/sequel.rb +29 -0
  97. data/lib/skylight/probes/sinatra.rb +66 -0
  98. data/lib/skylight/probes/sinatra_add_middleware.rb +10 -10
  99. data/lib/skylight/probes/tilt.rb +25 -0
  100. data/lib/skylight/probes.rb +172 -0
  101. data/lib/skylight/railtie.rb +172 -15
  102. data/lib/skylight/sidekiq.rb +47 -0
  103. data/lib/skylight/sinatra.rb +2 -2
  104. data/lib/skylight/subscriber.rb +130 -0
  105. data/lib/skylight/test.rb +147 -0
  106. data/lib/skylight/trace.rb +331 -15
  107. data/lib/skylight/user_config.rb +60 -0
  108. data/lib/skylight/util/allocation_free.rb +26 -0
  109. data/lib/skylight/util/clock.rb +57 -0
  110. data/lib/skylight/util/component.rb +47 -9
  111. data/lib/skylight/util/deploy.rb +24 -40
  112. data/lib/skylight/util/gzip.rb +20 -0
  113. data/lib/skylight/util/hostname.rb +4 -4
  114. data/lib/skylight/util/http.rb +62 -71
  115. data/lib/skylight/util/instrumenter_method.rb +26 -0
  116. data/lib/skylight/util/logging.rb +136 -0
  117. data/lib/skylight/util/lru_cache.rb +36 -0
  118. data/lib/skylight/util/platform.rb +74 -0
  119. data/lib/skylight/util/proxy.rb +13 -0
  120. data/lib/skylight/util/ssl.rb +4 -28
  121. data/lib/skylight/util.rb +12 -0
  122. data/lib/skylight/vendor/cli/thor/rake_compat.rb +1 -1
  123. data/lib/skylight/version.rb +5 -1
  124. data/lib/skylight/vm/gc.rb +60 -0
  125. data/lib/skylight.rb +213 -24
  126. metadata +171 -53
@@ -1,23 +1,72 @@
1
- require 'skylight/core/util/platform'
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
- @@has_native_ext = false
55
+ @has_native_ext = false
7
56
 
8
57
  def self.native?
9
- @@has_native_ext
58
+ @has_native_ext
10
59
  end
11
60
 
12
61
  def self.libskylight_path
13
- ENV['SKYLIGHT_LIB_PATH'] || File.expand_path("../native/#{Core::Util::Platform.tuple}", __FILE__)
62
+ ENV.fetch("SKYLIGHT_LIB_PATH") { File.expand_path("../native/#{Util::Platform.tuple}", __FILE__) }
14
63
  end
15
64
 
16
- skylight_required = ENV.key?("SKYLIGHT_REQUIRED") && ENV['SKYLIGHT_REQUIRED'] !~ /^false$/i
65
+ skylight_required = ENV.key?("SKYLIGHT_REQUIRED") && ENV.fetch("SKYLIGHT_REQUIRED", nil) !~ /^false$/i
17
66
 
18
67
  begin
19
- unless ENV.key?("SKYLIGHT_DISABLE_AGENT") && ENV['SKYLIGHT_DISABLE_AGENT'] !~ /^false$/i
20
- lib = "#{libskylight_path}/libskylight.#{Core::Util::Platform.libext}"
68
+ unless ENV.key?("SKYLIGHT_DISABLE_AGENT") && ENV.fetch("SKYLIGHT_DISABLE_AGENT", nil) !~ /^false$/i
69
+ lib = "#{libskylight_path}/libskylight.#{Util::Platform.libext}"
21
70
 
22
71
  if File.exist?(lib)
23
72
  # First attempt to require the native extension
@@ -27,7 +76,7 @@ module Skylight
27
76
  load_libskylight(lib)
28
77
 
29
78
  # If nothing was thrown, then the native extension is present
30
- @@has_native_ext = true
79
+ @has_native_ext = true
31
80
  elsif skylight_required
32
81
  raise LoadError, "Cannot find native extensions in #{libskylight_path}"
33
82
  end
@@ -35,15 +84,16 @@ module Skylight
35
84
  rescue RuntimeError => e
36
85
  # Old versions of OS X can have dlerrors, just treat it like a missing native
37
86
  raise if skylight_required || e.message !~ /dlerror/
38
- rescue LoadError => e
87
+ rescue LoadError
39
88
  raise if skylight_required
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
- def self.native_new(*args)
96
+ def self.native_new(*_args)
47
97
  allocate
48
98
  end
49
99
  end
@@ -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.
55
- install_log = File.expand_path("../../../ext/install.log", __FILE__)
104
+ # NOTE: An unsupported arch doesn't count as an error.
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
@@ -1,38 +1,31 @@
1
- require 'uri'
2
- require 'logger'
3
- require 'net/http'
4
- require 'fileutils'
5
- require 'digest/sha2'
6
- require 'open3'
7
- require 'skylight/util/ssl'
8
- require 'skylight/core/util/proxy'
1
+ require "uri"
2
+ require "logger"
3
+ require "net/http"
4
+ require "fileutils"
5
+ require "digest/sha2"
6
+ require "open3"
7
+ require "skylight/util/ssl"
8
+ require "skylight/util/proxy"
9
9
 
10
10
  # Used from extconf.rb
11
11
  module Skylight
12
12
  # Utility class for fetching the native extension from a URL
13
13
  class NativeExtFetcher
14
- BASE_URL = "https://s3.amazonaws.com/skylight-agent-packages/skylight-native"
14
+ BASE_URL = "https://s3.amazonaws.com/skylight-agent-packages/skylight-native".freeze
15
15
  MAX_REDIRECTS = 5
16
16
  MAX_RETRIES = 3
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
- def self.fetch(opts = {})
25
- fetcher = new(
26
- opts[:source] || BASE_URL,
27
- opts[:target],
28
- opts[:version],
29
- opts[:checksum],
30
- opts[:arch],
31
- opts[:required],
32
- opts[:platform],
33
- opts[:logger] || Logger.new(STDOUT))
34
-
35
- fetcher.fetch
25
+ def self.fetch(**args)
26
+ args[:source] ||= BASE_URL
27
+ args[:logger] ||= Logger.new($stdout)
28
+ new(**args).fetch
36
29
  end
37
30
 
38
31
  # @param source [String] the base url to download from
@@ -43,7 +36,7 @@ module Skylight
43
36
  # @param required [Boolean] whether the download is required to be successful
44
37
  # @param platform
45
38
  # @param log [Logger]
46
- def initialize(source, target, version, checksum, arch, required, platform, log)
39
+ def initialize(source:, target:, version:, checksum:, arch:, logger:, required: false, platform: nil)
47
40
  raise "source required" unless source
48
41
  raise "target required" unless target
49
42
  raise "checksum required" unless checksum
@@ -56,7 +49,7 @@ module Skylight
56
49
  @required = required
57
50
  @platform = platform
58
51
  @arch = arch
59
- @log = log
52
+ @logger = logger
60
53
  end
61
54
 
62
55
  # Fetch the native extension, verify, inflate, and save (if applicable)
@@ -64,11 +57,11 @@ module Skylight
64
57
  # @return [String] the inflated archive
65
58
  def fetch
66
59
  log "fetching native ext; curr-platform=#{@platform}; " \
67
- "requested-arch=#{@arch}; version=#{@version}"
60
+ "requested-arch=#{@arch}; version=#{@version}"
68
61
 
69
62
  tar_gz = "#{@target}/#{basename}"
70
63
 
71
- unless sha2 = fetch_native_ext(source_uri, tar_gz, MAX_RETRIES, MAX_REDIRECTS)
64
+ unless (sha2 = fetch_native_ext(source_uri, tar_gz, MAX_RETRIES, MAX_REDIRECTS))
72
65
  maybe_raise "could not fetch native extension"
73
66
  return
74
67
  end
@@ -91,7 +84,7 @@ module Skylight
91
84
  end
92
85
 
93
86
  def fetch_native_ext(uri, out, attempts, redirects)
94
- redirects.times do |i|
87
+ redirects.times do
95
88
  # Ensure the location is available
96
89
  mkdir_p File.dirname(out)
97
90
  rm_f out
@@ -103,7 +96,7 @@ module Skylight
103
96
  begin
104
97
  host, port, use_ssl, path = deconstruct_uri(uri)
105
98
 
106
- File.open out, 'w' do |f|
99
+ File.open out, "w" do |f|
107
100
  res, extra = http_get(host, port, use_ssl, path, f)
108
101
 
109
102
  case res
@@ -117,10 +110,12 @@ module Skylight
117
110
  next
118
111
  end
119
112
  end
120
- rescue => e
113
+ rescue StandardError => e
121
114
  remaining_attempts -= 1
122
115
 
123
- 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
124
119
 
125
120
  if remaining_attempts > 0
126
121
  sleep 2
@@ -132,7 +127,7 @@ module Skylight
132
127
  end
133
128
 
134
129
  log "exceeded max redirects"
135
- return
130
+ nil
136
131
  end
137
132
 
138
133
  # Get with `Net::HTTP`
@@ -145,19 +140,18 @@ module Skylight
145
140
  #
146
141
  # If `ENV['HTTP_PROXY']` is set, it will be used as a proxy for this request.
147
142
  def http_get(host, port, use_ssl, path, out)
148
- if http_proxy = Core::Util::Proxy.detect_url(ENV)
143
+ if (http_proxy = Util::Proxy.detect_url(ENV))
149
144
  log "connecting with proxy: #{http_proxy}"
150
145
  uri = URI.parse(http_proxy)
151
- p_host, p_port = uri.host, uri.port
146
+ p_host = uri.host
147
+ p_port = uri.port
152
148
  p_user, p_pass = uri.userinfo.split(/:/) if uri.userinfo
153
149
  end
154
150
 
155
151
  opts = {}
156
152
  opts[:use_ssl] = use_ssl
157
153
 
158
- if use_ssl
159
- opts[:ca_file] = Util::SSL.ca_cert_file_or_default
160
- end
154
+ opts[:ca_file] = Util::SSL.ca_cert_file_or_default if use_ssl
161
155
 
162
156
  Net::HTTP.start(host, port, p_host, p_port, p_user, p_pass, use_ssl: use_ssl) do |http|
163
157
  http.request_get path do |resp|
@@ -170,13 +164,13 @@ module Skylight
170
164
  out.write chunk
171
165
  end
172
166
 
173
- return [ :success, digest.hexdigest ]
167
+ return :success, digest.hexdigest
174
168
  when Net::HTTPRedirection
175
- unless location = resp['location']
169
+ unless (location = resp["location"])
176
170
  raise "received redirect but no location"
177
171
  end
178
172
 
179
- return [ :redirect, location ]
173
+ return :redirect, location
180
174
  else
181
175
  raise "received HTTP status code #{resp.code}"
182
176
  end
@@ -217,7 +211,7 @@ module Skylight
217
211
  # @return [Array<String>] the host, port, scheme, and request_uri
218
212
  def deconstruct_uri(uri)
219
213
  uri = URI(uri)
220
- [ uri.host, uri.port, uri.scheme == 'https', uri.request_uri ]
214
+ [uri.host, uri.port, uri.scheme == "https", uri.request_uri]
221
215
  end
222
216
 
223
217
  # Log an error and raise if `required` is `true`
@@ -227,9 +221,7 @@ module Skylight
227
221
  def maybe_raise(err)
228
222
  error err
229
223
 
230
- if @required
231
- raise err
232
- end
224
+ raise err if @required
233
225
  end
234
226
 
235
227
  # Log an `info` to the `logger`
@@ -238,7 +230,7 @@ module Skylight
238
230
  # @return [void]
239
231
  def log(msg)
240
232
  msg = "[SKYLIGHT] #{msg}"
241
- @log.info msg
233
+ @logger.info msg
242
234
  end
243
235
 
244
236
  # Log an `error` to the `logger`
@@ -246,10 +238,10 @@ module Skylight
246
238
  # @param msg [String]
247
239
  # @param e [Exception] the exception associated with the error
248
240
  # @return [void]
249
- def error(msg, e=nil)
241
+ def error(msg, err = nil)
250
242
  msg = "[SKYLIGHT] #{msg}"
251
- msg << "\n#{e.backtrace.join("\n")}" if e
252
- @log.error msg
243
+ msg << "\n#{err.backtrace.join("\n")}" if err
244
+ @logger.error msg
253
245
  end
254
246
  end
255
247
  end
@@ -0,0 +1,68 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActionController
4
+ # Normalizer for processing a Rails controller action
5
+ class ProcessAction < Normalizer
6
+ register "process_action.action_controller"
7
+
8
+ CAT = "app.controller.request".freeze
9
+
10
+ # Payload Keys: controller, action, params, format, method, path
11
+ # Additional keys available in `normalize_after`: status, view_runtime
12
+ # Along with ones added by probe: variant
13
+
14
+ # @param trace [Skylight::Messages::Trace::Builder]
15
+ # @param name [String] ignored, only present to match API
16
+ # @param payload [Hash]
17
+ # @option payload [String] :controller Controller name
18
+ # @option payload [String] :action Action name
19
+ # @return [Array]
20
+ def normalize(trace, _name, payload)
21
+ trace.endpoint = controller_action(payload)
22
+ [CAT, trace.endpoint, nil]
23
+ end
24
+
25
+ def normalize_after(trace, _span, _name, payload)
26
+ return unless config.enable_segments?
27
+
28
+ if (segment = segment_from_payload(payload))
29
+ trace.segment = segment
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def controller_action(payload)
36
+ "#{payload[:controller]}##{payload[:action]}"
37
+ end
38
+
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
+
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
+
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("+")
52
+ end
53
+ end
54
+
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"
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,51 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActionController
4
+ enabled = true
5
+
6
+ # Temporary hacks
7
+ begin
8
+ require "action_dispatch/http/mime_type"
9
+ require "action_dispatch/http/mime_types"
10
+ require "rack/utils"
11
+ rescue LoadError
12
+ enabled = false
13
+ end
14
+
15
+ if enabled
16
+ class SendFile < Normalizer
17
+ register "send_file.action_controller"
18
+
19
+ CAT = "app.controller.send_file".freeze
20
+ TITLE = "send file".freeze
21
+
22
+ def normalize(_trace, _name, _payload)
23
+ title = TITLE
24
+
25
+ # depending on normalization, we probably want this to eventually
26
+ # include the full path, but we need to make sure we have a good
27
+ # deduping strategy first.
28
+ desc = nil
29
+
30
+ [CAT, title, desc]
31
+ end
32
+
33
+ private
34
+
35
+ OCTET_STREAM = "application/octet-stream".freeze
36
+ ATTACHMENT = "attachment".freeze
37
+
38
+ def initialize(*)
39
+ super
40
+
41
+ @mimes =
42
+ Mime::SET.each_with_object({}) do |mime, hash|
43
+ hash[mime.symbol] = mime.to_s.dup.freeze
44
+ hash
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Skylight
4
+ module Normalizers
5
+ module ActionDispatch
6
+ class ProcessMiddleware < Normalizer
7
+ register "process_middleware.action_dispatch"
8
+
9
+ CAT = "rack.middleware"
10
+ ANONYMOUS_MIDDLEWARE = "Anonymous Middleware"
11
+ ANONYMOUS = /\A#<(Class|Module|Proc):/.freeze
12
+
13
+ def normalize(trace, _name, payload)
14
+ name = payload[:middleware].to_s
15
+ name = ANONYMOUS_MIDDLEWARE if name[ANONYMOUS]
16
+ trace.endpoint = name
17
+ [CAT, name, nil]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActionDispatch
4
+ class RouteSet < Normalizer
5
+ register "route_set.action_dispatch"
6
+
7
+ CAT = "rack.app".freeze
8
+
9
+ def normalize(trace, _name, _payload)
10
+ trace.endpoint = router_class_name
11
+ [CAT, trace.endpoint, nil]
12
+ end
13
+
14
+ private
15
+
16
+ def router_class_name
17
+ "ActionDispatch::Routing::RouteSet"
18
+ end
19
+
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
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ require "skylight/normalizers/render"
2
+
3
+ module Skylight
4
+ module Normalizers
5
+ module ActionView
6
+ # Normalizer for Rails collection rendering
7
+ class RenderCollection < RenderNormalizer
8
+ register "render_collection.action_view"
9
+
10
+ CAT = "view.render.collection".freeze
11
+
12
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
13
+ # @param name [String] ignored, only present to match API
14
+ # @param payload (see RenderNormalizer#normalize_render)
15
+ # @option payload (see RenderNormalizer#normalize_render)
16
+ # @option payload [Integer] :count
17
+ # @return (see RenderNormalizer#normalize_render)
18
+ def normalize(_trace, _name, payload)
19
+ normalize_render(CAT, payload)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "skylight/normalizers/render"
4
+
5
+ module Skylight
6
+ module Normalizers
7
+ module ActionView
8
+ # Normalizer for Rails layout rendering
9
+ class RenderLayout < RenderNormalizer
10
+ register "render_layout.action_view"
11
+
12
+ CAT = "view.render.layout"
13
+
14
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
15
+ # @param name [String] ignored, only present to match API
16
+ # @param payload (see RenderNormalizer#normalize_render)
17
+ # @option payload (see RenderNormalizer#normalize_render)
18
+ # @return (see RenderNormalizer#normalize_render)
19
+ def normalize(_trace, _name, payload)
20
+ normalize_render(CAT, payload)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ require "skylight/normalizers/render"
2
+
3
+ module Skylight
4
+ module Normalizers
5
+ module ActionView
6
+ # Normalizer for Rails partial rendering
7
+ class RenderPartial < RenderNormalizer
8
+ register "render_partial.action_view"
9
+
10
+ CAT = "view.render.template".freeze
11
+
12
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
13
+ # @param name [String] ignored, only present to match API
14
+ # @param payload (see RenderNormalizer#normalize_render)
15
+ # @option payload (see RenderNormalizer#normalize_render)
16
+ # @return (see RenderNormalizer#normalize_render)
17
+ def normalize(_trace, _name, payload)
18
+ normalize_render(CAT, payload)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require "skylight/normalizers/render"
2
+
3
+ module Skylight
4
+ module Normalizers
5
+ module ActionView
6
+ # Normalizer for Rails template rendering
7
+ class RenderTemplate < RenderNormalizer
8
+ register "render_template.action_view"
9
+
10
+ CAT = "view.render.template".freeze
11
+
12
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
13
+ # @param name [String] ignored, only present to match API
14
+ # @param payload (see RenderNormalizer#normalize_render)
15
+ # @option payload (see RenderNormalizer#normalize_render)
16
+ # @return (see RenderNormalizer#normalize_render)
17
+ def normalize(_trace, _name, payload)
18
+ normalize_render(CAT, payload)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end