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.
- checksums.yaml +4 -4
- data/lib/skylight/core.rb +1 -0
- data/lib/skylight/core/config.rb +2 -0
- data/lib/skylight/core/deprecation.rb +15 -0
- data/lib/skylight/core/instrumentable.rb +8 -0
- data/lib/skylight/core/instrumenter.rb +20 -12
- data/lib/skylight/core/middleware.rb +46 -14
- data/lib/skylight/core/normalizers.rb +34 -86
- data/lib/skylight/core/normalizers/action_view/render_collection.rb +2 -0
- data/lib/skylight/core/normalizers/action_view/render_partial.rb +2 -0
- data/lib/skylight/core/normalizers/action_view/render_template.rb +2 -0
- data/lib/skylight/core/normalizers/render.rb +77 -0
- data/lib/skylight/core/probes.rb +73 -73
- data/lib/skylight/core/probes/action_controller.rb +1 -1
- data/lib/skylight/core/probes/action_dispatch.rb +1 -0
- data/lib/skylight/core/probes/action_dispatch/request_id.rb +31 -0
- data/lib/skylight/core/probes/action_view.rb +1 -1
- data/lib/skylight/core/probes/active_model_serializers.rb +1 -1
- data/lib/skylight/core/probes/elasticsearch.rb +1 -1
- data/lib/skylight/core/probes/excon.rb +1 -1
- data/lib/skylight/core/probes/faraday.rb +1 -1
- data/lib/skylight/core/probes/httpclient.rb +1 -1
- data/lib/skylight/core/probes/middleware.rb +19 -3
- data/lib/skylight/core/probes/mongo.rb +1 -1
- data/lib/skylight/core/probes/mongoid.rb +3 -3
- data/lib/skylight/core/probes/moped.rb +1 -1
- data/lib/skylight/core/probes/net_http.rb +1 -1
- data/lib/skylight/core/probes/redis.rb +1 -1
- data/lib/skylight/core/probes/sequel.rb +1 -1
- data/lib/skylight/core/probes/sinatra.rb +1 -1
- data/lib/skylight/core/probes/tilt.rb +1 -1
- data/lib/skylight/core/test.rb +95 -82
- data/lib/skylight/core/trace.rb +48 -19
- data/lib/skylight/core/user_config.rb +1 -0
- data/lib/skylight/core/util.rb +0 -1
- data/lib/skylight/core/util/logging.rb +12 -4
- data/lib/skylight/core/version.rb +1 -1
- metadata +9 -8
- data/lib/skylight/core/normalizers/couch_potato/query.rb +0 -20
- data/lib/skylight/core/probes/grape.rb +0 -80
- data/lib/skylight/core/util/deploy.rb +0 -132
@@ -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
|
data/lib/skylight/core/probes.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
8
|
-
|
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
|
-
|
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
|
-
|
26
|
-
|
23
|
+
def paths
|
24
|
+
@paths ||= []
|
27
25
|
end
|
28
|
-
end
|
29
26
|
|
30
|
-
|
31
|
-
|
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
|
34
|
-
@
|
35
|
-
@require_paths = Array(require_paths)
|
36
|
-
@probe = probe
|
38
|
+
def available
|
39
|
+
@available ||= {}
|
37
40
|
end
|
38
41
|
|
39
|
-
def
|
40
|
-
|
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
|
-
|
45
|
-
|
46
|
-
|
53
|
+
def require_hooks
|
54
|
+
@require_hooks ||= {}
|
55
|
+
end
|
47
56
|
|
48
|
-
|
49
|
-
|
50
|
-
|
57
|
+
def installed
|
58
|
+
@installed ||= {}
|
59
|
+
end
|
51
60
|
|
52
|
-
|
53
|
-
|
54
|
-
|
61
|
+
def is_available?(klass_name)
|
62
|
+
!!Skylight::Core::Util::Inflector.safe_constantize(klass_name)
|
63
|
+
end
|
55
64
|
|
56
|
-
|
57
|
-
|
65
|
+
def register(name, *args)
|
66
|
+
registration = ProbeRegistration.new(name, *args)
|
58
67
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
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
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
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
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
100
|
-
|
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
|
@@ -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
|
@@ -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
|