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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d65618c6d6e9fcecd44bca37e8d7e3fbade73ce213712ab8af7ca71c6707e8c
|
4
|
+
data.tar.gz: '01867c672012d9400da14b148f856745d611695f4a85677eca624de60c9f87dc'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e610c23d07e5e8c02f4be9ef602689e9d1a1abfdd2ee58a72dbdd643b7e6d6d9abef8eb256951563d5296bfd8f0c18d0de76af69be8d4e3f403a67293cd95423
|
7
|
+
data.tar.gz: 6dff8d6a3e452b7657f8c011c0dbf54205d01795effe34826ab38da5700bc778be3b99bff952684bfbaf5c312093f69c38907f35211f111dbb9c5bee4361d37d
|
data/lib/skylight/core.rb
CHANGED
data/lib/skylight/core/config.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'active_support/deprecation'
|
2
|
+
|
3
|
+
module Skylight
|
4
|
+
SKYLIGHT_GEM_ROOT = File.expand_path("../../..", __FILE__) + "/"
|
5
|
+
|
6
|
+
class Deprecation < ActiveSupport::Deprecation
|
7
|
+
private
|
8
|
+
|
9
|
+
def ignored_callstack(path)
|
10
|
+
path.start_with?(SKYLIGHT_GEM_ROOT)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
DEPRECATOR = Deprecation.new('3.0', 'skylight')
|
15
|
+
end
|
@@ -33,6 +33,10 @@ module Skylight
|
|
33
33
|
Skylight::Core::Probes.probe(*args)
|
34
34
|
end
|
35
35
|
|
36
|
+
def enable_normalizer(*names)
|
37
|
+
Skylight::Core::Normalizers.enable(*names)
|
38
|
+
end
|
39
|
+
|
36
40
|
# Start instrumenting
|
37
41
|
def start!(config=nil)
|
38
42
|
return @instrumenter if @instrumenter
|
@@ -63,7 +67,10 @@ module Skylight
|
|
63
67
|
|
64
68
|
# Stop instrumenting
|
65
69
|
def stop!
|
70
|
+
t { "stop!" }
|
71
|
+
|
66
72
|
const_get(:LOCK).synchronize do
|
73
|
+
t { "stop! synchronized" }
|
67
74
|
return unless @instrumenter
|
68
75
|
# This is only really helpful for getting specs to pass.
|
69
76
|
@instrumenter.current_trace = nil
|
@@ -75,6 +82,7 @@ module Skylight
|
|
75
82
|
|
76
83
|
# Check tracing
|
77
84
|
def tracing?
|
85
|
+
t { "checking tracing?; thread=#{Thread.current.object_id}"}
|
78
86
|
instrumenter && instrumenter.current_trace
|
79
87
|
end
|
80
88
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'thread'
|
2
2
|
require 'strscan'
|
3
|
+
require 'securerandom'
|
3
4
|
|
4
5
|
module Skylight::Core
|
5
6
|
# @api private
|
@@ -24,25 +25,27 @@ module Skylight::Core
|
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
|
-
attr_reader :config, :gc, :trace_info
|
28
|
+
attr_reader :uuid, :config, :gc, :trace_info
|
28
29
|
|
29
30
|
def self.trace_class
|
30
31
|
Trace
|
31
32
|
end
|
32
33
|
|
33
|
-
def self.native_new
|
34
|
+
def self.native_new(_uuid, _config_env)
|
34
35
|
raise "not implemented"
|
35
36
|
end
|
36
37
|
|
37
38
|
def self.new(config)
|
38
39
|
config.validate!
|
39
40
|
|
40
|
-
|
41
|
-
inst
|
41
|
+
uuid = SecureRandom.uuid
|
42
|
+
inst = native_new(uuid, config.to_native_env)
|
43
|
+
inst.send(:initialize, uuid, config)
|
42
44
|
inst
|
43
45
|
end
|
44
46
|
|
45
|
-
def initialize(config)
|
47
|
+
def initialize(uuid, config)
|
48
|
+
@uuid = uuid
|
46
49
|
@gc = config.gc
|
47
50
|
@config = config
|
48
51
|
@subscriber = Subscriber.new(config, self)
|
@@ -51,6 +54,10 @@ module Skylight::Core
|
|
51
54
|
@trace_info = @config[:trace_info] || TraceInfo.new(key)
|
52
55
|
end
|
53
56
|
|
57
|
+
def log_context
|
58
|
+
@log_context ||= { inst: uuid }
|
59
|
+
end
|
60
|
+
|
54
61
|
def native_start
|
55
62
|
raise "not implemented"
|
56
63
|
end
|
@@ -59,11 +66,11 @@ module Skylight::Core
|
|
59
66
|
raise "not implemented"
|
60
67
|
end
|
61
68
|
|
62
|
-
def native_track_desc
|
69
|
+
def native_track_desc(_endpoint, _description)
|
63
70
|
raise "not implemented"
|
64
71
|
end
|
65
72
|
|
66
|
-
def native_submit_trace
|
73
|
+
def native_submit_trace(_trace)
|
67
74
|
raise "not implemented"
|
68
75
|
end
|
69
76
|
|
@@ -72,6 +79,7 @@ module Skylight::Core
|
|
72
79
|
end
|
73
80
|
|
74
81
|
def current_trace=(trace)
|
82
|
+
t { "setting current_trace=#{trace ? trace.uuid : "nil"}; thread=#{Thread.current.object_id}" }
|
75
83
|
@trace_info.current = trace
|
76
84
|
end
|
77
85
|
|
@@ -135,7 +143,7 @@ module Skylight::Core
|
|
135
143
|
|
136
144
|
ensure
|
137
145
|
@trace_info.current = nil
|
138
|
-
t { "instrumenter submitting trace" }
|
146
|
+
t { "instrumenter submitting trace; trace=#{trace.uuid}" }
|
139
147
|
trace.submit
|
140
148
|
end
|
141
149
|
end
|
@@ -172,7 +180,7 @@ module Skylight::Core
|
|
172
180
|
cat = cat.to_s
|
173
181
|
|
174
182
|
unless match?(cat, Skylight::CATEGORY_REGEX)
|
175
|
-
warn "invalid skylight instrumentation category; value=%s", cat
|
183
|
+
warn "invalid skylight instrumentation category; trace=%s; value=%s", trace.uuid, cat
|
176
184
|
return yield if block_given?
|
177
185
|
return
|
178
186
|
end
|
@@ -225,10 +233,10 @@ module Skylight::Core
|
|
225
233
|
end
|
226
234
|
|
227
235
|
def process(trace)
|
228
|
-
t { fmt "processing trace" }
|
236
|
+
t { fmt "processing trace=#{trace.uuid}" }
|
229
237
|
|
230
238
|
if ignore?(trace)
|
231
|
-
t { fmt "ignoring trace" }
|
239
|
+
t { fmt "ignoring trace=#{trace.uuid}" }
|
232
240
|
return false
|
233
241
|
end
|
234
242
|
|
@@ -236,7 +244,7 @@ module Skylight::Core
|
|
236
244
|
native_submit_trace(trace)
|
237
245
|
true
|
238
246
|
rescue => e
|
239
|
-
warn "failed to submit trace to worker; err=%s", e
|
247
|
+
warn "failed to submit trace to worker; trace=%s, err=%s", trace.uuid, e
|
240
248
|
t { "BACKTRACE:\n#{e.backtrace.join("\n")}" }
|
241
249
|
false
|
242
250
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module Skylight::Core
|
2
4
|
# @api private
|
3
5
|
class Middleware
|
@@ -62,22 +64,11 @@ module Skylight::Core
|
|
62
64
|
@config = opts[:config]
|
63
65
|
end
|
64
66
|
|
65
|
-
def instrumentable
|
66
|
-
Skylight
|
67
|
-
end
|
68
|
-
|
69
|
-
# Allow for overwriting
|
70
|
-
def endpoint_name(_env)
|
71
|
-
"Rack"
|
72
|
-
end
|
73
|
-
|
74
|
-
def endpoint_meta(_env)
|
75
|
-
nil
|
76
|
-
end
|
77
|
-
|
78
67
|
def call(env)
|
68
|
+
set_request_id(env)
|
69
|
+
|
79
70
|
if instrumentable.tracing?
|
80
|
-
error "Already instrumenting. Make sure the Middleware hasn't been added more than once."
|
71
|
+
error "Already instrumenting. Make sure the Skylight Rack Middleware hasn't been added more than once."
|
81
72
|
end
|
82
73
|
|
83
74
|
if env["REQUEST_METHOD"] == "HEAD"
|
@@ -87,6 +78,8 @@ module Skylight::Core
|
|
87
78
|
begin
|
88
79
|
t { "middleware beginning trace" }
|
89
80
|
trace = instrumentable.trace(endpoint_name(env), 'app.rack.request', nil, endpoint_meta(env))
|
81
|
+
t { "middleware began trace=#{trace.uuid}" }
|
82
|
+
|
90
83
|
resp = @app.call(env)
|
91
84
|
|
92
85
|
if trace
|
@@ -101,5 +94,44 @@ module Skylight::Core
|
|
101
94
|
end
|
102
95
|
end
|
103
96
|
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def log_context
|
101
|
+
# Don't cache this, it will change
|
102
|
+
inst_id = instrumentable.instrumenter ? instrumentable.instrumenter.uuid : nil
|
103
|
+
{ request_id: @current_request_id, inst: inst_id }
|
104
|
+
end
|
105
|
+
|
106
|
+
def instrumentable
|
107
|
+
Skylight
|
108
|
+
end
|
109
|
+
|
110
|
+
# Allow for overwriting
|
111
|
+
def endpoint_name(_env)
|
112
|
+
"Rack"
|
113
|
+
end
|
114
|
+
|
115
|
+
def endpoint_meta(_env)
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
|
119
|
+
# Request ID code based on ActionDispatch::RequestId
|
120
|
+
def set_request_id(env)
|
121
|
+
existing_request_id = env["action_dispatch.request_id"] || env['HTTP_X_REQUEST_ID'];
|
122
|
+
@current_request_id = env["skylight.request_id"] = make_request_id(existing_request_id)
|
123
|
+
end
|
124
|
+
|
125
|
+
def make_request_id(request_id)
|
126
|
+
if request_id && !request_id.empty?
|
127
|
+
request_id.gsub(/[^\w\-]/, "".freeze).first(255)
|
128
|
+
else
|
129
|
+
internal_request_id
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def internal_request_id
|
134
|
+
SecureRandom.uuid
|
135
|
+
end
|
104
136
|
end
|
105
137
|
end
|
@@ -7,29 +7,51 @@ module Skylight::Core
|
|
7
7
|
|
8
8
|
DEFAULT = Default.new
|
9
9
|
|
10
|
-
def self.
|
11
|
-
|
12
|
-
|
10
|
+
def self.registry
|
11
|
+
@registry ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.register(name, klass, opts={})
|
15
|
+
enabled = opts[:enabled] != false
|
16
|
+
registry[name] = [klass, enabled]
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.unregister(name)
|
20
|
+
@registry.delete(name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.enable(*names, enabled: true)
|
24
|
+
names.each do |name|
|
25
|
+
matches = registry.select{|n,_| n =~ /(^|\.)#{name}$/ }
|
26
|
+
raise ArgumentError, "no normalizers match #{name}" if matches.empty?
|
27
|
+
matches.values.each{|v| v[1] = enabled }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.disable(*names)
|
32
|
+
enable(*names, enabled: false)
|
13
33
|
end
|
14
34
|
|
15
35
|
def self.build(config)
|
16
36
|
normalizers = {}
|
17
37
|
|
18
|
-
|
38
|
+
registry.each do |key, (klass, enabled)|
|
39
|
+
next if !enabled
|
40
|
+
|
19
41
|
unless klass.method_defined?(:normalize)
|
20
42
|
# TODO: Warn
|
21
43
|
next
|
22
44
|
end
|
23
45
|
|
24
|
-
normalizers[
|
46
|
+
normalizers[key] = klass.new(config)
|
25
47
|
end
|
26
48
|
|
27
49
|
Container.new(normalizers)
|
28
50
|
end
|
29
51
|
|
30
52
|
class Normalizer
|
31
|
-
def self.register(name)
|
32
|
-
Normalizers.register(name, self)
|
53
|
+
def self.register(name, opts={})
|
54
|
+
Normalizers.register(name, self, opts)
|
33
55
|
end
|
34
56
|
|
35
57
|
attr_reader :config
|
@@ -47,80 +69,6 @@ module Skylight::Core
|
|
47
69
|
end
|
48
70
|
end
|
49
71
|
|
50
|
-
# Base Normalizer for Rails rendering
|
51
|
-
class RenderNormalizer < Normalizer
|
52
|
-
include Util::AllocationFree
|
53
|
-
|
54
|
-
def setup
|
55
|
-
@paths = config['normalizers.render.view_paths'] || []
|
56
|
-
end
|
57
|
-
|
58
|
-
# Generic normalizer for renders
|
59
|
-
# @param category [String]
|
60
|
-
# @param payload [Hash]
|
61
|
-
# @option payload [String] :identifier
|
62
|
-
# @return [Array]
|
63
|
-
def normalize_render(category, payload)
|
64
|
-
if path = payload[:identifier]
|
65
|
-
title = relative_path(path)
|
66
|
-
path = nil if path == title
|
67
|
-
end
|
68
|
-
|
69
|
-
[ category, title, nil ]
|
70
|
-
end
|
71
|
-
|
72
|
-
def relative_path(path)
|
73
|
-
return path if relative_path?(path)
|
74
|
-
|
75
|
-
root = array_find(@paths) { |p| path.start_with?(p) }
|
76
|
-
type = :project
|
77
|
-
|
78
|
-
unless root
|
79
|
-
root = array_find(Gem.path) { |p| path.start_with?(p) }
|
80
|
-
type = :gem
|
81
|
-
end
|
82
|
-
|
83
|
-
if root
|
84
|
-
start = root.size
|
85
|
-
start += 1 if path.getbyte(start) == SEPARATOR_BYTE
|
86
|
-
if type == :gem
|
87
|
-
"$GEM_PATH/#{path[start, path.size]}"
|
88
|
-
else
|
89
|
-
path[start, path.size]
|
90
|
-
end
|
91
|
-
else
|
92
|
-
"Absolute Path"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
private
|
97
|
-
def relative_path?(path)
|
98
|
-
!absolute_path?(path)
|
99
|
-
end
|
100
|
-
|
101
|
-
SEPARATOR_BYTE = File::SEPARATOR.ord
|
102
|
-
|
103
|
-
if File.const_defined?(:NULL) ? File::NULL == "NUL" : RbConfig::CONFIG['host_os'] =~ /mingw|mswin32/
|
104
|
-
# This is a DOSish environment
|
105
|
-
ALT_SEPARATOR_BYTE = File::ALT_SEPARATOR && File::ALT_SEPARATOR.ord
|
106
|
-
COLON_BYTE = ":".ord
|
107
|
-
def absolute_path?(path)
|
108
|
-
if alpha?(path.getbyte(0)) && path.getbyte(1) == COLON_BYTE
|
109
|
-
byte2 = path.getbyte(2)
|
110
|
-
byte2 == SEPARATOR_BYTE || byte2 == ALT_SEPARATOR_BYTE
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def alpha?(byte)
|
115
|
-
byte >= 65 and byte <= 90 || byte >= 97 and byte <= 122
|
116
|
-
end
|
117
|
-
else
|
118
|
-
def absolute_path?(path)
|
119
|
-
path.getbyte(0) == SEPARATOR_BYTE
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
72
|
class Container
|
125
73
|
def initialize(normalizers)
|
126
74
|
@normalizers = normalizers
|
@@ -139,7 +87,10 @@ module Skylight::Core
|
|
139
87
|
end
|
140
88
|
|
141
89
|
def normalizer_for(name)
|
142
|
-
|
90
|
+
# We never expect to hit the default case since we only register listeners
|
91
|
+
# for items that we know have normalizers. For now, though, we'll play it
|
92
|
+
# safe and provide a fallback.
|
93
|
+
@normalizers.fetch(name, DEFAULT)
|
143
94
|
end
|
144
95
|
end
|
145
96
|
|
@@ -148,13 +99,13 @@ module Skylight::Core
|
|
148
99
|
action_view/render_collection
|
149
100
|
action_view/render_partial
|
150
101
|
action_view/render_template
|
102
|
+
active_job/enqueue_at
|
151
103
|
active_model_serializers/render
|
152
104
|
active_record/instantiation
|
153
105
|
active_record/sql
|
154
106
|
active_support/cache
|
155
107
|
coach/handler_finish
|
156
108
|
coach/middleware_finish
|
157
|
-
couch_potato/query
|
158
109
|
data_mapper/sql
|
159
110
|
elasticsearch/request
|
160
111
|
faraday/request
|
@@ -163,8 +114,5 @@ module Skylight::Core
|
|
163
114
|
sequel/sql).each do |file|
|
164
115
|
require "skylight/core/normalizers/#{file}"
|
165
116
|
end
|
166
|
-
|
167
|
-
# The following are not required by default as they are of dubious usefulness:
|
168
|
-
# - active_job/enqueue_at
|
169
117
|
end
|
170
118
|
end
|