skylight-core 2.0.0.beta3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|