skylight-core 2.0.0.beta3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/skylight/core.rb +1 -0
  3. data/lib/skylight/core/config.rb +2 -0
  4. data/lib/skylight/core/deprecation.rb +15 -0
  5. data/lib/skylight/core/instrumentable.rb +8 -0
  6. data/lib/skylight/core/instrumenter.rb +20 -12
  7. data/lib/skylight/core/middleware.rb +46 -14
  8. data/lib/skylight/core/normalizers.rb +34 -86
  9. data/lib/skylight/core/normalizers/action_view/render_collection.rb +2 -0
  10. data/lib/skylight/core/normalizers/action_view/render_partial.rb +2 -0
  11. data/lib/skylight/core/normalizers/action_view/render_template.rb +2 -0
  12. data/lib/skylight/core/normalizers/render.rb +77 -0
  13. data/lib/skylight/core/probes.rb +73 -73
  14. data/lib/skylight/core/probes/action_controller.rb +1 -1
  15. data/lib/skylight/core/probes/action_dispatch.rb +1 -0
  16. data/lib/skylight/core/probes/action_dispatch/request_id.rb +31 -0
  17. data/lib/skylight/core/probes/action_view.rb +1 -1
  18. data/lib/skylight/core/probes/active_model_serializers.rb +1 -1
  19. data/lib/skylight/core/probes/elasticsearch.rb +1 -1
  20. data/lib/skylight/core/probes/excon.rb +1 -1
  21. data/lib/skylight/core/probes/faraday.rb +1 -1
  22. data/lib/skylight/core/probes/httpclient.rb +1 -1
  23. data/lib/skylight/core/probes/middleware.rb +19 -3
  24. data/lib/skylight/core/probes/mongo.rb +1 -1
  25. data/lib/skylight/core/probes/mongoid.rb +3 -3
  26. data/lib/skylight/core/probes/moped.rb +1 -1
  27. data/lib/skylight/core/probes/net_http.rb +1 -1
  28. data/lib/skylight/core/probes/redis.rb +1 -1
  29. data/lib/skylight/core/probes/sequel.rb +1 -1
  30. data/lib/skylight/core/probes/sinatra.rb +1 -1
  31. data/lib/skylight/core/probes/tilt.rb +1 -1
  32. data/lib/skylight/core/test.rb +95 -82
  33. data/lib/skylight/core/trace.rb +48 -19
  34. data/lib/skylight/core/user_config.rb +1 -0
  35. data/lib/skylight/core/util.rb +0 -1
  36. data/lib/skylight/core/util/logging.rb +12 -4
  37. data/lib/skylight/core/version.rb +1 -1
  38. metadata +9 -8
  39. data/lib/skylight/core/normalizers/couch_potato/query.rb +0 -20
  40. data/lib/skylight/core/probes/grape.rb +0 -80
  41. data/lib/skylight/core/util/deploy.rb +0 -132
@@ -1,3 +1,5 @@
1
+ require 'skylight/core/normalizers/render'
2
+
1
3
  module Skylight::Core
2
4
  module Normalizers
3
5
  module ActionView
@@ -1,3 +1,5 @@
1
+ require 'skylight/core/normalizers/render'
2
+
1
3
  module Skylight::Core
2
4
  module Normalizers
3
5
  module ActionView
@@ -0,0 +1,77 @@
1
+ module Skylight::Core
2
+ module Normalizers
3
+ # Base Normalizer for Rails rendering
4
+ class RenderNormalizer < Normalizer
5
+ include Util::AllocationFree
6
+
7
+ def setup
8
+ @paths = config['normalizers.render.view_paths'] || []
9
+ end
10
+
11
+ # Generic normalizer for renders
12
+ # @param category [String]
13
+ # @param payload [Hash]
14
+ # @option payload [String] :identifier
15
+ # @return [Array]
16
+ def normalize_render(category, payload)
17
+ if path = payload[:identifier]
18
+ title = relative_path(path)
19
+ path = nil if path == title
20
+ end
21
+
22
+ [ category, title, nil ]
23
+ end
24
+
25
+ def relative_path(path)
26
+ return path if relative_path?(path)
27
+
28
+ root = array_find(@paths) { |p| path.start_with?(p) }
29
+ type = :project
30
+
31
+ unless root
32
+ root = array_find(Gem.path) { |p| path.start_with?(p) }
33
+ type = :gem
34
+ end
35
+
36
+ if root
37
+ start = root.size
38
+ start += 1 if path.getbyte(start) == SEPARATOR_BYTE
39
+ if type == :gem
40
+ "$GEM_PATH/#{path[start, path.size]}"
41
+ else
42
+ path[start, path.size]
43
+ end
44
+ else
45
+ "Absolute Path"
46
+ end
47
+ end
48
+
49
+ private
50
+ def relative_path?(path)
51
+ !absolute_path?(path)
52
+ end
53
+
54
+ SEPARATOR_BYTE = File::SEPARATOR.ord
55
+
56
+ if File.const_defined?(:NULL) ? File::NULL == "NUL" : RbConfig::CONFIG['host_os'] =~ /mingw|mswin32/
57
+ # This is a DOSish environment
58
+ ALT_SEPARATOR_BYTE = File::ALT_SEPARATOR && File::ALT_SEPARATOR.ord
59
+ COLON_BYTE = ":".ord
60
+ def absolute_path?(path)
61
+ if alpha?(path.getbyte(0)) && path.getbyte(1) == COLON_BYTE
62
+ byte2 = path.getbyte(2)
63
+ byte2 == SEPARATOR_BYTE || byte2 == ALT_SEPARATOR_BYTE
64
+ end
65
+ end
66
+
67
+ def alpha?(byte)
68
+ byte >= 65 and byte <= 90 || byte >= 97 and byte <= 122
69
+ end
70
+ else
71
+ def absolute_path?(path)
72
+ path.getbyte(0) == SEPARATOR_BYTE
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -1,110 +1,118 @@
1
+ require 'pathname'
2
+
1
3
  module Skylight::Core
2
4
  # @api private
3
5
  module Probes
6
+ class ProbeRegistration
7
+ attr_reader :name, :klass_name, :require_paths, :probe
4
8
 
5
- @@available = nil
9
+ def initialize(name, klass_name, require_paths, probe)
10
+ @name = name
11
+ @klass_name = klass_name
12
+ @require_paths = Array(require_paths)
13
+ @probe = probe
14
+ end
6
15
 
7
- def self.available
8
- unless @@available
9
- root = File.expand_path("../probes", __FILE__)
10
- @@available = {}
11
- Dir["#{root}/*.rb"].each do |f|
12
- name = File.basename(f, '.rb')
13
- @@available[name] = "skylight/core/probes/#{name}"
14
- end
16
+ def install
17
+ probe.install
15
18
  end
16
- @@available
17
19
  end
18
20
 
19
- def self.probe(*probes)
20
- unknown = probes.map(&:to_s) - available.keys
21
- unless unknown.empty?
22
- raise ArgumentError, "unknown probes: #{unknown.join(', ')}"
23
- end
21
+ class << self
24
22
 
25
- probes.each do |p|
26
- require available[p.to_s]
23
+ def paths
24
+ @paths ||= []
27
25
  end
28
- end
29
26
 
30
- class ProbeRegistration
31
- attr_reader :klass_name, :require_paths, :probe
27
+ def add_path(path)
28
+ root = Pathname.new(path)
29
+ Pathname.glob(root.join("./**/*.rb")).each do |f|
30
+ name = f.relative_path_from(root).sub_ext('').to_s
31
+ if available.key?(name)
32
+ raise "duplicate probe name: #{name}; original=#{available[name]}; new=#{f}"
33
+ end
34
+ available[name] = f
35
+ end
36
+ end
32
37
 
33
- def initialize(klass_name, require_paths, probe)
34
- @klass_name = klass_name
35
- @require_paths = Array(require_paths)
36
- @probe = probe
38
+ def available
39
+ @available ||= {}
37
40
  end
38
41
 
39
- def install
40
- probe.install
42
+ def probe(*probes)
43
+ unknown = probes.map(&:to_s) - available.keys
44
+ unless unknown.empty?
45
+ raise ArgumentError, "unknown probes: #{unknown.join(', ')}"
46
+ end
47
+
48
+ probes.each do |p|
49
+ require available[p.to_s]
50
+ end
41
51
  end
42
- end
43
52
 
44
- def self.require_hooks
45
- @require_hooks ||= {}
46
- end
53
+ def require_hooks
54
+ @require_hooks ||= {}
55
+ end
47
56
 
48
- def self.installed
49
- @installed ||= {}
50
- end
57
+ def installed
58
+ @installed ||= {}
59
+ end
51
60
 
52
- def self.is_available?(klass_name)
53
- !!Util::Inflector.safe_constantize(klass_name)
54
- end
61
+ def is_available?(klass_name)
62
+ !!Skylight::Core::Util::Inflector.safe_constantize(klass_name)
63
+ end
55
64
 
56
- def self.register(*args)
57
- registration = ProbeRegistration.new(*args)
65
+ def register(name, *args)
66
+ registration = ProbeRegistration.new(name, *args)
58
67
 
59
- if is_available?(registration.klass_name)
60
- installed[registration.klass_name] ||= []
61
- installed[registration.klass_name] << registration
62
- registration.install
63
- else
64
- register_require_hook(registration)
68
+ if is_available?(registration.klass_name)
69
+ installed[registration.klass_name] = registration
70
+ registration.install
71
+ else
72
+ register_require_hook(registration)
73
+ end
65
74
  end
66
- end
67
75
 
68
- def self.require_hook(require_path)
69
- registrations = lookup_by_require_path(require_path)
70
- return unless registrations
76
+ def require_hook(require_path)
77
+ registration = lookup_by_require_path(require_path)
78
+ return unless registration
71
79
 
72
- registrations.each do |registration|
73
80
  # Double check constant is available
74
81
  if is_available?(registration.klass_name)
75
- installed[registration.klass_name] ||= []
76
- installed[registration.klass_name] << registration
82
+ installed[registration.klass_name] = registration
77
83
  registration.install
78
84
 
79
85
  # Don't need this to be called again
80
86
  unregister_require_hook(registration)
81
87
  end
82
88
  end
83
- end
84
89
 
85
- def self.register_require_hook(registration)
86
- registration.require_paths.each do |p|
87
- require_hooks[p] ||= []
88
- require_hooks[p] << registration
90
+ def register_require_hook(registration)
91
+ registration.require_paths.each do |p|
92
+ require_hooks[p] = registration
93
+ end
89
94
  end
90
- end
91
95
 
92
- def self.unregister_require_hook(registration)
93
- registration.require_paths.each do |p|
94
- require_hooks[p].delete(registration)
95
- require_hooks.delete(p) if require_hook[p].empty?
96
+ def unregister_require_hook(registration)
97
+ registration.require_paths.each do |p|
98
+ require_hooks.delete(p)
99
+ end
96
100
  end
97
- end
98
101
 
99
- def self.lookup_by_require_path(require_path)
100
- require_hooks[require_path]
102
+ def lookup_by_require_path(require_path)
103
+ require_hooks[require_path]
104
+ end
101
105
  end
106
+
107
+ add_path(File.expand_path("./probes", __dir__))
102
108
  end
103
109
  end
104
110
 
105
111
  # Allow hooking require
106
112
  # @api private
107
113
  module ::Kernel
114
+ private
115
+
108
116
  alias require_without_sk require
109
117
 
110
118
  def require(name)
@@ -117,13 +125,5 @@ module ::Kernel
117
125
  end
118
126
 
119
127
  ret
120
- rescue LoadError
121
- # Support pre-2.0 style requires
122
- if name =~ %r{^skylight/probes/(.+)}
123
- warn "[DEPRECATION] Requiring Skylight probes by path is deprecated. Use `Skylight.probe(:#{$1})` instead."
124
- require "skylight/core/probes/#{$1}"
125
- else
126
- raise
127
- end
128
128
  end
129
- end
129
+ end
@@ -26,6 +26,6 @@ module Skylight::Core
26
26
  end
27
27
  end
28
28
 
29
- register("ActionController::Instrumentation", "action_controller/metal/instrumentation", ActionController::Probe.new)
29
+ register(:action_controller, "ActionController::Instrumentation", "action_controller/metal/instrumentation", ActionController::Probe.new)
30
30
  end
31
31
  end
@@ -0,0 +1 @@
1
+ Skylight::Core::Probes.probe('action_dispatch/request_id')
@@ -0,0 +1,31 @@
1
+ module Skylight::Core
2
+ module Probes
3
+ module ActionDispatch
4
+ module RequestId
5
+ class Probe
6
+ def install
7
+ ::ActionDispatch::RequestId.class_eval do
8
+ alias call_without_sk call
9
+
10
+ def call(env)
11
+ @skylight_request_id = env["skylight.request_id"]
12
+ call_without_sk(env)
13
+ end
14
+
15
+ private
16
+
17
+ alias internal_request_id_without_sk internal_request_id
18
+
19
+ def internal_request_id
20
+ @skylight_request_id || internal_request_id_without_sk
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ register(:action_dispatch, "ActionDispatch::RequestId", "action_dispatch/middleware/request_id", ActionDispatch::RequestId::Probe.new)
30
+ end
31
+ end
@@ -30,6 +30,6 @@ module Skylight::Core
30
30
  end
31
31
  end
32
32
 
33
- register("ActionView::TemplateRenderer", "action_view", ActionView::Probe.new)
33
+ register(:action_view, "ActionView::TemplateRenderer", "action_view", ActionView::Probe.new)
34
34
  end
35
35
  end
@@ -50,6 +50,6 @@ module Skylight::Core
50
50
  end
51
51
  end
52
52
 
53
- register("ActiveModel::Serializer", "active_model/serializer", ActiveModelSerializers::Probe.new)
53
+ register(:active_model_serializers, "ActiveModel::Serializer", "active_model/serializer", ActiveModelSerializers::Probe.new)
54
54
  end
55
55
  end
@@ -32,6 +32,6 @@ module Skylight::Core
32
32
  end
33
33
  end
34
34
 
35
- register("Elasticsearch", "elasticsearch", Elasticsearch::Probe.new)
35
+ register(:elasticsearch, "Elasticsearch", "elasticsearch", Elasticsearch::Probe.new)
36
36
  end
37
37
  end
@@ -21,6 +21,6 @@ module Skylight::Core
21
21
  end
22
22
  end
23
23
 
24
- register("Excon", "excon", Excon::Probe.new)
24
+ register(:excon, "Excon", "excon", Excon::Probe.new)
25
25
  end
26
26
  end
@@ -17,6 +17,6 @@ module Skylight::Core
17
17
  end
18
18
  end
19
19
 
20
- register("Faraday", "faraday", Faraday::Probe.new)
20
+ register(:faraday, "Faraday", "faraday", Faraday::Probe.new)
21
21
  end
22
22
  end
@@ -41,6 +41,6 @@ module Skylight::Core
41
41
  end # class Probe
42
42
  end # module Probes::HTTPClient
43
43
 
44
- register("HTTPClient", "httpclient", HTTPClient::Probe.new)
44
+ register(:httpclient, "HTTPClient", "httpclient", HTTPClient::Probe.new)
45
45
  end
46
46
  end
@@ -2,10 +2,26 @@ module Skylight::Core
2
2
  module Probes
3
3
  module Middleware
4
4
  class Probe
5
+ DISABLED_KEY = :__skylight_middleware_disabled
6
+
7
+ def self.disable!
8
+ @disabled = true
9
+ end
10
+
11
+ def self.enable!
12
+ @disabled = false
13
+ end
14
+
15
+ def self.disabled?
16
+ !!@disabled
17
+ end
18
+
5
19
  def self.add_instrumentation(middleware, default_name: "Anonymous Middleware", category: "rack.middleware")
6
20
  middleware.instance_eval <<-RUBY, __FILE__, __LINE__ + 1
7
21
  alias call_without_sk call
8
22
  def call(*args, &block)
23
+ return call_without_sk(*args, &block) if Skylight::Core::Probes::Middleware::Probe.disabled?
24
+
9
25
  traces = Skylight::Core::Fanout.registered.map do |r|
10
26
  r.instrumenter ? r.instrumenter.current_trace : nil
11
27
  end.compact
@@ -33,7 +49,7 @@ module Skylight::Core
33
49
  end
34
50
 
35
51
  def install
36
- ActionDispatch::MiddlewareStack.class_eval do
52
+ ::ActionDispatch::MiddlewareStack.class_eval do
37
53
  alias build_without_sk build
38
54
 
39
55
  if ::ActionPack.gem_version >= Gem::Version.new('5.x')
@@ -53,7 +69,7 @@ module Skylight::Core
53
69
  end
54
70
  end
55
71
 
56
- ActionDispatch::MiddlewareStack::Middleware.class_eval do
72
+ ::ActionDispatch::MiddlewareStack::Middleware.class_eval do
57
73
  alias build_without_sk build
58
74
  def build(*args)
59
75
  sk_instrument_middleware(build_without_sk(*args))
@@ -77,6 +93,6 @@ module Skylight::Core
77
93
  end
78
94
  end
79
95
 
80
- register("ActionDispatch::MiddlewareStack::Middleware", "actionpack/action_dispatch", Middleware::Probe.new)
96
+ register(:middleware, "ActionDispatch::MiddlewareStack::Middleware", "actionpack/action_dispatch", Middleware::Probe.new)
81
97
  end
82
98
  end
@@ -166,6 +166,6 @@ module Skylight::Core
166
166
  end
167
167
  end
168
168
 
169
- register("Mongo", "mongo", Mongo::Probe.new)
169
+ register(:mongo, "Mongo", "mongo", Mongo::Probe.new)
170
170
  end
171
171
  end