skylight 3.1.4 → 5.3.4

Sign up to get free protection for your applications and to get access to all the features.
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