skylight 5.0.0.beta4 → 5.1.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +399 -362
  3. data/CLA.md +1 -1
  4. data/CONTRIBUTING.md +1 -1
  5. data/LICENSE.md +7 -17
  6. data/README.md +1 -1
  7. data/ext/extconf.rb +42 -54
  8. data/ext/libskylight.yml +10 -5
  9. data/lib/skylight.rb +20 -30
  10. data/lib/skylight/api.rb +22 -18
  11. data/lib/skylight/cli.rb +47 -46
  12. data/lib/skylight/cli/doctor.rb +50 -50
  13. data/lib/skylight/cli/helpers.rb +19 -19
  14. data/lib/skylight/cli/merger.rb +141 -139
  15. data/lib/skylight/config.rb +267 -310
  16. data/lib/skylight/deprecation.rb +4 -4
  17. data/lib/skylight/errors.rb +3 -4
  18. data/lib/skylight/extensions.rb +17 -29
  19. data/lib/skylight/extensions/source_location.rb +128 -128
  20. data/lib/skylight/formatters/http.rb +1 -3
  21. data/lib/skylight/gc.rb +30 -40
  22. data/lib/skylight/helpers.rb +57 -30
  23. data/lib/skylight/instrumenter.rb +25 -18
  24. data/lib/skylight/middleware.rb +31 -35
  25. data/lib/skylight/native.rb +8 -10
  26. data/lib/skylight/native_ext_fetcher.rb +10 -12
  27. data/lib/skylight/normalizers.rb +43 -38
  28. data/lib/skylight/normalizers/action_controller/process_action.rb +24 -25
  29. data/lib/skylight/normalizers/action_controller/send_file.rb +7 -6
  30. data/lib/skylight/normalizers/action_dispatch/route_set.rb +7 -7
  31. data/lib/skylight/normalizers/active_job/perform.rb +48 -44
  32. data/lib/skylight/normalizers/active_model_serializers/render.rb +7 -3
  33. data/lib/skylight/normalizers/active_storage.rb +11 -13
  34. data/lib/skylight/normalizers/active_support/cache.rb +1 -12
  35. data/lib/skylight/normalizers/coach/handler_finish.rb +1 -3
  36. data/lib/skylight/normalizers/default.rb +1 -9
  37. data/lib/skylight/normalizers/faraday/request.rb +1 -3
  38. data/lib/skylight/normalizers/grape/endpoint.rb +13 -19
  39. data/lib/skylight/normalizers/grape/endpoint_run.rb +16 -18
  40. data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +1 -3
  41. data/lib/skylight/normalizers/graphql/base.rb +23 -28
  42. data/lib/skylight/normalizers/render.rb +19 -21
  43. data/lib/skylight/normalizers/shrine.rb +32 -0
  44. data/lib/skylight/normalizers/sql.rb +4 -4
  45. data/lib/skylight/probes.rb +38 -46
  46. data/lib/skylight/probes/action_controller.rb +32 -28
  47. data/lib/skylight/probes/action_dispatch/request_id.rb +9 -5
  48. data/lib/skylight/probes/action_dispatch/routing/route_set.rb +7 -5
  49. data/lib/skylight/probes/action_view.rb +9 -10
  50. data/lib/skylight/probes/active_job_enqueue.rb +3 -9
  51. data/lib/skylight/probes/active_model_serializers.rb +8 -8
  52. data/lib/skylight/probes/delayed_job.rb +37 -42
  53. data/lib/skylight/probes/elasticsearch.rb +4 -6
  54. data/lib/skylight/probes/excon.rb +1 -1
  55. data/lib/skylight/probes/excon/middleware.rb +22 -23
  56. data/lib/skylight/probes/graphql.rb +2 -7
  57. data/lib/skylight/probes/middleware.rb +14 -5
  58. data/lib/skylight/probes/mongo.rb +83 -91
  59. data/lib/skylight/probes/net_http.rb +1 -1
  60. data/lib/skylight/probes/redis.rb +5 -17
  61. data/lib/skylight/probes/sequel.rb +7 -11
  62. data/lib/skylight/probes/sinatra.rb +8 -5
  63. data/lib/skylight/probes/tilt.rb +2 -4
  64. data/lib/skylight/railtie.rb +121 -135
  65. data/lib/skylight/sidekiq.rb +4 -5
  66. data/lib/skylight/subscriber.rb +31 -33
  67. data/lib/skylight/test.rb +89 -84
  68. data/lib/skylight/trace.rb +121 -115
  69. data/lib/skylight/user_config.rb +14 -17
  70. data/lib/skylight/util/clock.rb +1 -0
  71. data/lib/skylight/util/component.rb +18 -21
  72. data/lib/skylight/util/deploy.rb +11 -13
  73. data/lib/skylight/util/http.rb +104 -105
  74. data/lib/skylight/util/logging.rb +4 -6
  75. data/lib/skylight/util/lru_cache.rb +2 -6
  76. data/lib/skylight/util/platform.rb +2 -6
  77. data/lib/skylight/util/ssl.rb +1 -25
  78. data/lib/skylight/version.rb +1 -1
  79. data/lib/skylight/vm/gc.rb +1 -9
  80. metadata +20 -5
@@ -7,42 +7,46 @@ module Skylight
7
7
  ::ActionController::Instrumentation.class_eval do
8
8
  private
9
9
 
10
- alias_method :append_info_to_payload_without_sk, :append_info_to_payload
11
- def append_info_to_payload(payload)
12
- append_info_to_payload_without_sk(payload)
10
+ alias_method :append_info_to_payload_without_sk, :append_info_to_payload
11
+ def append_info_to_payload(payload)
12
+ append_info_to_payload_without_sk(payload)
13
13
 
14
- payload[:sk_rendered_format] = sk_rendered_mime.try(:ref)
15
- payload[:sk_variant] = request.respond_to?(:variant) ? request.variant : nil
16
- end
14
+ payload[:sk_rendered_format] = sk_rendered_mime.try(:ref)
15
+ payload[:sk_variant] = request.respond_to?(:variant) ? request.variant : nil
16
+ end
17
17
 
18
- def sk_rendered_mime
19
- if respond_to?(:media_type)
20
- mt = media_type
21
- return mt && Mime::Type.lookup(mt)
22
- end
18
+ def sk_rendered_mime
19
+ if respond_to?(:media_type)
20
+ mt = media_type
21
+ return mt && Mime::Type.lookup(mt)
22
+ end
23
23
 
24
- if content_type.is_a?(Mime::Type)
25
- content_type
26
- elsif content_type.respond_to?(:to_s)
27
- type_str = content_type.to_s.split(";").first
28
- Mime::Type.lookup(type_str) unless type_str.blank?
29
- elsif respond_to?(:rendered_format) && rendered_format
30
- rendered_format
31
- end
32
- rescue
33
- # There are cases in which actionpack can return
34
- # a stringified representation of a Mime::NullType instance,
35
- # which is invalid for a number of reasons. This string raises
36
- # errors when piped through Mime::Type.lookup, so it's probably
37
- # best to just return nil in those cases.
38
- nil
24
+ if content_type.is_a?(Mime::Type)
25
+ content_type
26
+ elsif content_type.respond_to?(:to_s)
27
+ type_str = content_type.to_s.split(";").first
28
+ Mime::Type.lookup(type_str) unless type_str.blank?
29
+ elsif respond_to?(:rendered_format) && rendered_format
30
+ rendered_format
39
31
  end
32
+ rescue StandardError
33
+ # There are cases in which actionpack can return
34
+ # a stringified representation of a Mime::NullType instance,
35
+ # which is invalid for a number of reasons. This string raises
36
+ # errors when piped through Mime::Type.lookup, so it's probably
37
+ # best to just return nil in those cases.
38
+ nil
39
+ end
40
40
  end
41
41
  end
42
42
  end
43
43
  end
44
44
 
45
- register(:action_controller, "ActionController::Instrumentation", "action_controller/metal/instrumentation",
46
- ActionController::Probe.new)
45
+ register(
46
+ :action_controller,
47
+ "ActionController::Instrumentation",
48
+ "action_controller/metal/instrumentation",
49
+ ActionController::Probe.new
50
+ )
47
51
  end
48
52
  end
@@ -10,9 +10,9 @@ module Skylight
10
10
 
11
11
  private
12
12
 
13
- def internal_request_id
14
- @skylight_request_id || super
15
- end
13
+ def internal_request_id
14
+ @skylight_request_id || super
15
+ end
16
16
  end
17
17
 
18
18
  class Probe
@@ -23,7 +23,11 @@ module Skylight
23
23
  end
24
24
  end
25
25
 
26
- register(:action_dispatch, "ActionDispatch::RequestId", "action_dispatch/middleware/request_id",
27
- ActionDispatch::RequestId::Probe.new)
26
+ register(
27
+ :action_dispatch,
28
+ "ActionDispatch::RequestId",
29
+ "action_dispatch/middleware/request_id",
30
+ ActionDispatch::RequestId::Probe.new
31
+ )
28
32
  end
29
33
  end
@@ -7,9 +7,7 @@ module Skylight
7
7
  module RouteSet
8
8
  module Instrumentation
9
9
  def call(env)
10
- ActiveSupport::Notifications.instrument("route_set.action_dispatch") do
11
- super
12
- end
10
+ ActiveSupport::Notifications.instrument("route_set.action_dispatch") { super }
13
11
  end
14
12
  end
15
13
 
@@ -22,7 +20,11 @@ module Skylight
22
20
  end
23
21
  end
24
22
 
25
- register(:rails_router, "ActionDispatch::Routing::RouteSet", "action_dispatch/routing/route_set",
26
- ActionDispatch::Routing::RouteSet::Probe.new)
23
+ register(
24
+ :rails_router,
25
+ "ActionDispatch::Routing::RouteSet",
26
+ "action_dispatch/routing/route_set",
27
+ ActionDispatch::Routing::RouteSet::Probe.new
28
+ )
27
29
  end
28
30
  end
@@ -5,19 +5,18 @@ module Skylight
5
5
  module ActionView
6
6
  module Instrumentation
7
7
  def render_with_layout(*args) #:nodoc:
8
- path, locals = case args.length
9
- when 2
10
- args
11
- when 4
12
- # Rails > 6.0.0.beta3 arguments are (view, template, path, locals)
13
- [args[2], args[3]]
14
- end
8
+ path, locals =
9
+ case args.length
10
+ when 2
11
+ args
12
+ when 4
13
+ # Rails > 6.0.0.beta3 arguments are (view, template, path, locals)
14
+ [args[2], args[3]]
15
+ end
15
16
 
16
17
  layout = nil
17
18
 
18
- if path
19
- layout = find_layout(path, locals.keys, [formats.first])
20
- end
19
+ layout = find_layout(path, locals.keys, [formats.first]) if path
21
20
 
22
21
  if layout
23
22
  ActiveSupport::Notifications.instrument("render_template.action_view", identifier: layout.identifier) do
@@ -14,17 +14,11 @@ module Skylight
14
14
  name, job_class_name = Normalizers::ActiveJob::Perform.normalize_title(job)
15
15
  descriptors = ["adapter: '#{adapter_name}'", "queue: '#{job.queue_name}'"]
16
16
  descriptors << "job: '#{job_class_name}'" if job_class_name
17
- desc = "{ #{descriptors.join(', ')} }"
18
- rescue
17
+ desc = "{ #{descriptors.join(", ")} }"
18
+ rescue StandardError
19
19
  block.call
20
20
  else
21
- Skylight.instrument(
22
- title: "Enqueue #{name}",
23
- category: CAT,
24
- description: desc,
25
- internal: true,
26
- &block
27
- )
21
+ Skylight.instrument(title: "Enqueue #{name}", category: CAT, description: desc, internal: true, &block)
28
22
  end
29
23
 
30
24
  self.class.instance_eval do
@@ -18,9 +18,7 @@ module Skylight
18
18
  rescue LoadError # rubocop:disable Lint/SuppressedException
19
19
  end
20
20
 
21
- if Gem.loaded_specs["active_model_serializers"]
22
- version = Gem.loaded_specs["active_model_serializers"].version
23
- end
21
+ version = Gem.loaded_specs["active_model_serializers"].version if Gem.loaded_specs["active_model_serializers"]
24
22
 
25
23
  if !version || version < Gem::Version.new("0.5.0")
26
24
  Skylight.error "Instrumention is only available for ActiveModelSerializers version 0.5.0 and greater."
@@ -37,14 +35,16 @@ module Skylight
37
35
  # End users could override as_json without calling super, but it's likely safer
38
36
  # than overriding serializable_array/hash/object.
39
37
 
40
- [::ActiveModel::Serializer, ::ActiveModel::ArraySerializer].each do |klass|
41
- klass.prepend(Instrumentation)
42
- end
38
+ [::ActiveModel::Serializer, ::ActiveModel::ArraySerializer].each { |klass| klass.prepend(Instrumentation) }
43
39
  end
44
40
  end
45
41
  end
46
42
 
47
- register(:active_model_serializers, "ActiveModel::Serializer", "active_model/serializer",
48
- ActiveModelSerializers::Probe.new)
43
+ register(
44
+ :active_model_serializers,
45
+ "ActiveModel::Serializer",
46
+ "active_model/serializer",
47
+ ActiveModelSerializers::Probe.new
48
+ )
49
49
  end
50
50
  end
@@ -10,13 +10,9 @@ module Skylight
10
10
 
11
11
  class Plugin < ::Delayed::Plugin
12
12
  callbacks do |lifecycle|
13
- lifecycle.around(:perform) do |worker, job, &block|
14
- sk_instrument(worker, job, &block)
15
- end
13
+ lifecycle.around(:perform) { |worker, job, &block| sk_instrument(worker, job, &block) }
16
14
 
17
- lifecycle.after(:error) do |_worker, _job|
18
- Skylight.trace&.segment = "error"
19
- end
15
+ lifecycle.after(:error) { |_worker, _job| Skylight.trace&.segment = "error" }
20
16
  end
21
17
 
22
18
  class << self
@@ -25,15 +21,19 @@ module Skylight
25
21
  def sk_instrument(_worker, job)
26
22
  endpoint = Skylight::Probes::DelayedJob.handler_name(job)
27
23
 
28
- Skylight.trace(endpoint,
29
- "app.delayed_job.worker",
30
- "Delayed::Worker#run",
31
- component: :worker,
32
- segment: job.queue,
33
- meta: { source_location: "delayed_job" }) do
34
- t { "Delayed::Job beginning trace" }
35
- yield
36
- end
24
+ Skylight.trace(
25
+ endpoint,
26
+ "app.delayed_job.worker",
27
+ "Delayed::Worker#run",
28
+ component: :worker,
29
+ segment: job.queue,
30
+ meta: {
31
+ source_location: "delayed_job"
32
+ }
33
+ ) do
34
+ t { "Delayed::Job beginning trace" }
35
+ yield
36
+ end
37
37
  end
38
38
  end
39
39
  end
@@ -44,11 +44,8 @@ module Skylight
44
44
  UNKNOWN = "<Delayed::Job Unknown>"
45
45
 
46
46
  def self.handler_name(job)
47
- payload_object = if job.respond_to?(:payload_object_without_sk)
48
- job.payload_object_without_sk
49
- else
50
- job.payload_object
51
- end
47
+ payload_object =
48
+ job.respond_to?(:payload_object_without_sk) ? job.payload_object_without_sk : job.payload_object
52
49
 
53
50
  payload_object_name(payload_object)
54
51
  end
@@ -62,7 +59,7 @@ module Skylight
62
59
  # Use class name instead to avoid this.
63
60
  payload_object.class.name
64
61
  end
65
- rescue
62
+ rescue StandardError
66
63
  UNKNOWN
67
64
  end
68
65
 
@@ -84,8 +81,10 @@ module Skylight
84
81
 
85
82
  opts = {
86
83
  category: "app.delayed_job.job",
87
- title: format_source(*source_meta),
88
- meta: { source_location_hint: source_meta },
84
+ title: format_source(*source_meta),
85
+ meta: {
86
+ source_location_hint: source_meta
87
+ },
89
88
  internal: true
90
89
  }
91
90
 
@@ -99,13 +98,9 @@ module Skylight
99
98
 
100
99
  private
101
100
 
102
- def format_source(method_type, constant_name, method_name)
103
- if method_type == :instance_method
104
- "#{constant_name}##{method_name}"
105
- else
106
- "#{constant_name}.#{method_name}"
107
- end
108
- end
101
+ def format_source(method_type, constant_name, method_name)
102
+ method_type == :instance_method ? "#{constant_name}##{method_name}" : "#{constant_name}.#{method_name}"
103
+ end
109
104
  end
110
105
 
111
106
  class Probe
@@ -124,23 +119,23 @@ module Skylight
124
119
 
125
120
  private
126
121
 
127
- def plugin_defined?
128
- defined?(::Skylight::Probes::DelayedJob::Plugin)
129
- end
122
+ def plugin_defined?
123
+ defined?(::Skylight::Probes::DelayedJob::Plugin)
124
+ end
130
125
 
131
- def validate_version
132
- spec = Gem.loaded_specs["delayed_job"]
133
- version = spec&.version
126
+ def validate_version
127
+ spec = Gem.loaded_specs["delayed_job"]
128
+ version = spec&.version
134
129
 
135
- if !version || version < Gem::Version.new("4.0.0")
136
- Skylight.error "The installed version of DelayedJob is not supported on Skylight. " \
130
+ if !version || version < Gem::Version.new("4.0.0")
131
+ Skylight.error "The installed version of DelayedJob is not supported on Skylight. " \
137
132
  "Your jobs will not be tracked."
138
133
 
139
- return false
140
- end
141
-
142
- true
134
+ return false
143
135
  end
136
+
137
+ true
138
+ end
144
139
  end
145
140
  end
146
141
 
@@ -9,16 +9,14 @@ module Skylight
9
9
  def perform_request(method, path, *args, &block)
10
10
  ActiveSupport::Notifications.instrument(
11
11
  "request.elasticsearch",
12
- name: "Request",
12
+ name: "Request",
13
13
  method: method,
14
- path: path
14
+ path: path
15
15
  ) do
16
16
  # Prevent HTTP-related probes from firing
17
17
  Skylight::Normalizers::Faraday::Request.disable do
18
18
  disable_skylight_probe(:NetHTTP) do
19
- disable_skylight_probe(:HTTPClient) do
20
- perform_request_without_sk(method, path, *args, &block)
21
- end
19
+ disable_skylight_probe(:HTTPClient) { perform_request_without_sk(method, path, *args, &block) }
22
20
  end
23
21
  end
24
22
  end
@@ -26,7 +24,7 @@ module Skylight
26
24
 
27
25
  def disable_skylight_probe(class_name)
28
26
  klass = ::ActiveSupport::Inflector.safe_constantize("Skylight::Probes::#{class_name}::Probe")
29
- (klass ? klass.disable { yield } : yield).tap { puts "re-enabling: #{klass}" }
27
+ (klass ? klass.disable { yield } : yield).tap { Skylight.log(:debug, "re-enabling: #{klass}") }
30
28
  end
31
29
  end
32
30
  end
@@ -14,7 +14,7 @@ module Skylight
14
14
  ::Excon.defaults[:middlewares].insert(idx, Probes::Excon::Middleware)
15
15
  else
16
16
  Skylight.error "The installed version of Excon doesn't support Middlewares. " \
17
- "The Excon probe will be disabled."
17
+ "The Excon probe will be disabled."
18
18
  end
19
19
  end
20
20
  end
@@ -33,33 +33,32 @@ module Skylight
33
33
 
34
34
  private
35
35
 
36
- def begin_instrumentation(datum)
37
- method = datum[:method].to_s
38
- scheme = datum[:scheme]
39
- host = datum[:host]
40
- # TODO: Maybe don't show other default ports like 443
41
- port = datum[:port] == 80 ? nil : datum[:port]
42
- path = datum[:path]
43
- query = datum[:query]
36
+ def begin_instrumentation(datum)
37
+ method = datum[:method].to_s
38
+ scheme = datum[:scheme]
39
+ host = datum[:host]
44
40
 
45
- opts = Formatters::HTTP.build_opts(method, scheme, host, port, path, query)
41
+ # TODO: Maybe don't show other default ports like 443
42
+ port = datum[:port] == 80 ? nil : datum[:port]
43
+ path = datum[:path]
44
+ query = datum[:query]
46
45
 
47
- @requests[datum] = Skylight.instrument(opts)
48
- rescue Exception => e
49
- Skylight.error "failed to begin instrumentation for Excon; msg=%s", e.message
50
- end
46
+ opts = Formatters::HTTP.build_opts(method, scheme, host, port, path, query)
47
+
48
+ @requests[datum] = Skylight.instrument(opts)
49
+ rescue Exception => e
50
+ Skylight.error "failed to begin instrumentation for Excon; msg=%s", e.message
51
+ end
51
52
 
52
- def end_instrumentation(datum)
53
- if (request = @requests.delete(datum))
54
- meta = {}
55
- if datum[:error].is_a?(Exception)
56
- meta[:exception_object] = datum[:error]
57
- end
58
- Skylight.done(request, meta)
59
- end
60
- rescue Exception => e
61
- Skylight.error "failed to end instrumentation for Excon; msg=%s", e.message
53
+ def end_instrumentation(datum)
54
+ if (request = @requests.delete(datum))
55
+ meta = {}
56
+ meta[:exception_object] = datum[:error] if datum[:error].is_a?(Exception)
57
+ Skylight.done(request, meta)
62
58
  end
59
+ rescue Exception => e
60
+ Skylight.error "failed to end instrumentation for Excon; msg=%s", e.message
61
+ end
63
62
  end
64
63
  end
65
64
  end
@@ -20,16 +20,11 @@ module Skylight
20
20
  class Probe
21
21
  def install
22
22
  tracing_klass_name = "::GraphQL::Tracing::ActiveSupportNotificationsTracing"
23
- klasses_to_probe = %w[
24
- ::GraphQL::Execution::Multiplex
25
- ::GraphQL::Query
26
- ]
23
+ klasses_to_probe = %w[::GraphQL::Execution::Multiplex ::GraphQL::Query]
27
24
 
28
25
  return unless ([tracing_klass_name] + klasses_to_probe).all?(&method(:safe_constantize))
29
26
 
30
- klasses_to_probe.each do |klass_name|
31
- safe_constantize(klass_name).prepend(Instrumentation)
32
- end
27
+ klasses_to_probe.each { |klass_name| safe_constantize(klass_name).prepend(Instrumentation) }
33
28
  end
34
29
 
35
30
  def safe_constantize(klass_name)