skylight 0.0.16 → 0.1.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +3 -19
- data/bin/skylight +0 -2
- data/lib/skylight.rb +52 -42
- data/lib/skylight/api.rb +34 -0
- data/lib/skylight/cli.rb +68 -57
- data/lib/skylight/compat.rb +19 -5
- data/lib/skylight/config.rb +219 -98
- data/lib/skylight/gc.rb +109 -0
- data/lib/skylight/instrumenter.rb +53 -70
- data/lib/skylight/messages.rb +19 -0
- data/lib/skylight/messages/annotation.rb +13 -0
- data/lib/skylight/messages/base.rb +24 -0
- data/lib/skylight/messages/batch.rb +11 -0
- data/lib/skylight/messages/endpoint.rb +12 -0
- data/lib/skylight/messages/event.rb +12 -0
- data/lib/skylight/messages/hello.rb +53 -0
- data/lib/skylight/messages/span.rb +21 -0
- data/lib/skylight/messages/trace.rb +162 -0
- data/lib/skylight/middleware.rb +2 -4
- data/lib/skylight/normalizers.rb +89 -0
- data/lib/skylight/normalizers/default.rb +22 -0
- data/lib/skylight/normalizers/process_action.rb +19 -0
- data/lib/skylight/normalizers/render_collection.rb +14 -0
- data/lib/skylight/normalizers/render_partial.rb +14 -0
- data/lib/skylight/normalizers/render_template.rb +14 -0
- data/lib/skylight/{normalize → normalizers}/send_file.rb +15 -15
- data/lib/skylight/normalizers/sql.rb +25 -0
- data/lib/skylight/railtie.rb +21 -41
- data/lib/skylight/subscriber.rb +29 -19
- data/lib/skylight/util/clock.rb +8 -21
- data/lib/skylight/util/http.rb +93 -46
- data/lib/skylight/util/logging.rb +66 -0
- data/lib/skylight/util/queue.rb +7 -3
- data/lib/skylight/util/task.rb +154 -0
- data/lib/skylight/{compat → vendor/active_support}/notifications.rb +56 -24
- data/lib/skylight/{compat → vendor/active_support}/notifications/fanout.rb +19 -26
- data/lib/skylight/{compat → vendor/active_support}/notifications/instrumenter.rb +25 -18
- data/lib/skylight/vendor/active_support/per_thread_registry.rb +52 -0
- data/lib/skylight/vendor/beefcake.rb +256 -0
- data/lib/skylight/vendor/beefcake/buffer.rb +112 -0
- data/lib/skylight/vendor/beefcake/decode.rb +107 -0
- data/lib/skylight/vendor/beefcake/encode.rb +115 -0
- data/lib/skylight/vendor/{highline.rb → cli/highline.rb} +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/color_scheme.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/compatibility.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/import.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/menu.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/question.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/simulate.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/string_extensions.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/style.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/system_extensions.rb +0 -0
- data/lib/skylight/vendor/{thor.rb → cli/thor.rb} +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/create_file.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/create_link.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/directory.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/empty_directory.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/file_manipulation.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/inject_into_file.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/base.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/command.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/core_ext/hash_with_indifferent_access.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/core_ext/io_binary_read.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/core_ext/ordered_hash.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/error.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/group.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/invocation.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/parser.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/parser/argument.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/parser/arguments.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/parser/option.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/parser/options.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/rake_compat.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/runner.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/shell.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/shell/basic.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/shell/color.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/shell/html.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/util.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/version.rb +0 -0
- data/lib/skylight/vendor/thread_safe.rb +126 -0
- data/lib/skylight/vendor/thread_safe/non_concurrent_cache_backend.rb +133 -0
- data/lib/skylight/vendor/thread_safe/synchronized_cache_backend.rb +76 -0
- data/lib/skylight/version.rb +2 -1
- data/lib/skylight/worker.rb +12 -154
- data/lib/skylight/worker/builder.rb +72 -0
- data/lib/skylight/worker/collector.rb +124 -0
- data/lib/skylight/worker/connection.rb +77 -0
- data/lib/skylight/worker/embedded.rb +6 -0
- data/lib/skylight/worker/server.rb +307 -0
- data/lib/skylight/worker/standalone.rb +356 -0
- metadata +89 -77
- data/lib/skylight/connection.rb +0 -25
- data/lib/skylight/json_proto.rb +0 -88
- data/lib/skylight/normalize.rb +0 -63
- data/lib/skylight/normalize/default.rb +0 -17
- data/lib/skylight/normalize/process_action.rb +0 -17
- data/lib/skylight/normalize/render_collection.rb +0 -11
- data/lib/skylight/normalize/render_partial.rb +0 -14
- data/lib/skylight/normalize/render_template.rb +0 -13
- data/lib/skylight/normalize/sql.rb +0 -26
- data/lib/skylight/normalize/start_processing.rb +0 -12
- data/lib/skylight/sanity_checker.rb +0 -73
- data/lib/skylight/trace.rb +0 -160
- data/lib/skylight/util/atomic.rb +0 -73
- data/lib/skylight/util/bytes.rb +0 -40
- data/lib/skylight/util/ewma.rb +0 -32
- data/lib/skylight/util/uuid.rb +0 -33
data/lib/skylight/gc.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Skylight
|
4
|
+
class GC
|
5
|
+
METHODS = [ :enable, :total_time ]
|
6
|
+
TH_KEY = :SK_GC_CURR_WINDOW
|
7
|
+
|
8
|
+
def self.update
|
9
|
+
if win = Thread.current[TH_KEY]
|
10
|
+
win.update
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.time
|
15
|
+
if win = Thread.current[TH_KEY]
|
16
|
+
win.time
|
17
|
+
else
|
18
|
+
0.0
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(profiler)
|
23
|
+
@listeners = []
|
24
|
+
@lock = Mutex.new
|
25
|
+
|
26
|
+
if METHODS.all? { |m| profiler.respond_to?(m) }
|
27
|
+
@profiler = profiler
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def start_track
|
32
|
+
return if Thread.current[TH_KEY]
|
33
|
+
|
34
|
+
unless @profiler
|
35
|
+
win = Window.new(nil)
|
36
|
+
else
|
37
|
+
win = Window.new(self)
|
38
|
+
|
39
|
+
@lock.synchronize do
|
40
|
+
@listeners << win
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Thread.current[TH_KEY] = win
|
45
|
+
end
|
46
|
+
|
47
|
+
def stop_track
|
48
|
+
if win = Thread.current[TH_KEY]
|
49
|
+
Thread.current[TH_KEY] = nil
|
50
|
+
win.release
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def track
|
55
|
+
return unless block_given?
|
56
|
+
|
57
|
+
start_track
|
58
|
+
|
59
|
+
begin
|
60
|
+
yield
|
61
|
+
ensure
|
62
|
+
stop_track
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def release(win)
|
67
|
+
@lock.synchronize do
|
68
|
+
@listeners.delete(win)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def update
|
73
|
+
@lock.synchronize do
|
74
|
+
time = @profiler.total_time
|
75
|
+
|
76
|
+
if time > 0
|
77
|
+
@profiler.clear
|
78
|
+
@listeners.each do |l|
|
79
|
+
l.add(time)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
nil
|
85
|
+
end
|
86
|
+
|
87
|
+
class Window
|
88
|
+
attr_reader :time
|
89
|
+
|
90
|
+
def initialize(global)
|
91
|
+
@global = global
|
92
|
+
@time = 0.0
|
93
|
+
end
|
94
|
+
|
95
|
+
def update
|
96
|
+
@global.update if @global
|
97
|
+
end
|
98
|
+
|
99
|
+
def add(time)
|
100
|
+
@time += time
|
101
|
+
end
|
102
|
+
|
103
|
+
def release
|
104
|
+
@global.release(self) if @global
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
@@ -1,57 +1,52 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
1
3
|
module Skylight
|
2
4
|
class Instrumenter
|
5
|
+
KEY = :__skylight_current_trace
|
3
6
|
|
4
|
-
|
5
|
-
LOCK = Mutex.new
|
7
|
+
include Util::Logging
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
+
def self.current_trace
|
10
|
+
Thread.current[KEY]
|
11
|
+
end
|
9
12
|
|
10
|
-
|
11
|
-
|
13
|
+
def self.current_trace=(trace)
|
14
|
+
Thread.current[KEY] = trace
|
15
|
+
end
|
12
16
|
|
13
17
|
def self.start!(config = Config.new)
|
14
18
|
new(config).start!
|
15
19
|
end
|
16
20
|
|
17
|
-
attr_reader :config, :
|
21
|
+
attr_reader :config, :gc
|
18
22
|
|
19
23
|
def initialize(config)
|
20
|
-
# Convert a hash to a config object
|
21
24
|
if Hash === config
|
22
25
|
config = Config.new(config)
|
23
26
|
end
|
24
27
|
|
25
|
-
@
|
28
|
+
@gc = config.gc
|
29
|
+
@lock = Mutex.new
|
30
|
+
@config = config
|
31
|
+
@worker = config.worker.build
|
26
32
|
@started = false
|
27
|
-
@
|
33
|
+
@subscriber = Subscriber.new(config)
|
28
34
|
end
|
29
35
|
|
30
36
|
def start!
|
31
37
|
# Quick check
|
32
38
|
return self if @started
|
39
|
+
return unless config
|
33
40
|
|
34
|
-
|
41
|
+
@lock.synchronize do
|
35
42
|
# Ensure that the instrumenter has not been started now that the lock
|
36
|
-
#
|
43
|
+
# has been acquired.
|
37
44
|
return self if @started
|
38
45
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
return unless config
|
44
|
-
|
45
|
-
# Ensure that there is an API token
|
46
|
-
unless config.authentication_token
|
47
|
-
if logger = config.logger
|
48
|
-
logger.warn "[SKYLIGHT] No authentication token provided; cannot start agent."
|
49
|
-
end
|
50
|
-
|
51
|
-
return
|
52
|
-
end
|
53
|
-
|
54
|
-
config.gc_profiler.enable
|
46
|
+
t { "starting instrumenter" }
|
47
|
+
@config.validate!
|
48
|
+
@worker.spawn
|
49
|
+
@subscriber.register!
|
55
50
|
|
56
51
|
@started = true
|
57
52
|
end
|
@@ -59,74 +54,62 @@ module Skylight
|
|
59
54
|
self
|
60
55
|
|
61
56
|
rescue Exception => e
|
62
|
-
error
|
57
|
+
error "failed to start instrumenter; msg=%s", e.message
|
63
58
|
nil
|
64
59
|
end
|
65
60
|
|
66
|
-
def
|
61
|
+
def shutdown
|
62
|
+
@lock.synchronize do
|
63
|
+
return unless @started
|
64
|
+
@subscriber.unregister!
|
65
|
+
@worker.shutdown
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def trace(endpoint = 'Unknown')
|
67
70
|
# Ignore everything unless the instrumenter has been started
|
68
71
|
unless @started
|
69
72
|
return yield
|
70
73
|
end
|
71
74
|
|
72
|
-
# If
|
73
|
-
if
|
74
|
-
|
75
|
+
# If a trace is already in progress, continue with that one
|
76
|
+
if trace = Instrumenter.current_trace
|
77
|
+
t { "already tracing" }
|
78
|
+
return yield(trace)
|
75
79
|
end
|
76
80
|
|
77
|
-
|
78
|
-
unless trace = create_trace(endpoint)
|
79
|
-
return yield
|
80
|
-
end
|
81
|
+
trace = Messages::Trace::Builder.new(endpoint, Util::Clock.now, @config)
|
81
82
|
|
82
|
-
# Otherwise, setup the new trace and continue
|
83
83
|
begin
|
84
|
-
|
85
|
-
|
84
|
+
|
85
|
+
Instrumenter.current_trace = trace
|
86
|
+
yield trace
|
87
|
+
|
86
88
|
ensure
|
87
|
-
|
89
|
+
Instrumenter.current_trace = nil
|
88
90
|
|
89
91
|
begin
|
90
|
-
trace.
|
91
|
-
|
92
|
+
built = trace.build
|
93
|
+
|
94
|
+
if built.valid?
|
95
|
+
process(built)
|
96
|
+
else
|
97
|
+
debug "trace invalid -- dropping"
|
98
|
+
end
|
92
99
|
rescue Exception => e
|
93
|
-
error
|
100
|
+
error e
|
94
101
|
end
|
95
102
|
end
|
96
103
|
end
|
97
104
|
|
98
105
|
private
|
99
106
|
|
100
|
-
def create_trace(endpoint)
|
101
|
-
Trace.new(config, endpoint)
|
102
|
-
# Paranoia
|
103
|
-
rescue => e
|
104
|
-
error e
|
105
|
-
nil
|
106
|
-
end
|
107
|
-
|
108
107
|
def process(trace)
|
109
|
-
|
108
|
+
t { fmt "processing trace; spans=%d", trace.spans.length }
|
110
109
|
unless @worker.submit(trace)
|
111
|
-
|
110
|
+
warn "failed to submit trace to worker"
|
112
111
|
end
|
113
112
|
end
|
114
113
|
|
115
|
-
def error(msg)
|
116
|
-
return unless l = config.logger
|
117
|
-
|
118
|
-
if Error == msg
|
119
|
-
msg = "#{e.message} (#{e.class}) - #{e.backtrace && e.backtrace.first}"
|
120
|
-
end
|
121
|
-
|
122
|
-
l.error "[SKYLIGHT] #{msg}"
|
123
|
-
rescue
|
124
|
-
end
|
125
|
-
|
126
|
-
def debug(msg)
|
127
|
-
return unless l = config.logger
|
128
|
-
l.debug "[SKYLIGHT] #{msg}"
|
129
|
-
end
|
130
|
-
|
131
114
|
end
|
132
115
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Skylight
|
2
|
+
module Messages
|
3
|
+
def self.get(id)
|
4
|
+
(@id_map ||= {})[id]
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.set(id, klass)
|
8
|
+
(@id_map ||= {})[id] = klass
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'skylight/messages/annotation'
|
12
|
+
require 'skylight/messages/event'
|
13
|
+
require 'skylight/messages/span'
|
14
|
+
require 'skylight/messages/trace'
|
15
|
+
require 'skylight/messages/endpoint'
|
16
|
+
require 'skylight/messages/batch'
|
17
|
+
require 'skylight/messages/hello'
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Skylight
|
2
|
+
module Messages
|
3
|
+
class Annotation
|
4
|
+
include Beefcake::Message
|
5
|
+
|
6
|
+
optional :key, :string, 1
|
7
|
+
optional :int, :int64, 2
|
8
|
+
optional :double, :double, 3
|
9
|
+
optional :string, :string, 4
|
10
|
+
repeated :nested, Annotation, 5
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Skylight
|
2
|
+
module Messages
|
3
|
+
class Base
|
4
|
+
module ClassMethods
|
5
|
+
attr_accessor :message_id
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.inherited(klass)
|
9
|
+
klass.class_eval do
|
10
|
+
include Beefcake::Message
|
11
|
+
extend ClassMethods
|
12
|
+
end
|
13
|
+
|
14
|
+
klass.message_id = (@count ||= 0)
|
15
|
+
Messages.set(klass.message_id, klass)
|
16
|
+
@count += 1
|
17
|
+
end
|
18
|
+
|
19
|
+
def message_id
|
20
|
+
self.class.message_id
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'skylight/messages/base'
|
2
|
+
|
3
|
+
module Skylight
|
4
|
+
module Messages
|
5
|
+
class Hello < Base
|
6
|
+
|
7
|
+
DIGITS = /^\s*\d+\s*$/
|
8
|
+
|
9
|
+
required :version, :string, 1
|
10
|
+
optional :config, :uint32, 2
|
11
|
+
repeated :cmd, :string, 3
|
12
|
+
|
13
|
+
def newer?(other = VERSION)
|
14
|
+
other = split(other)
|
15
|
+
curr = split(version)
|
16
|
+
|
17
|
+
[other.length, curr.length].max.times do |i|
|
18
|
+
next if other[i] == curr[i]
|
19
|
+
return true unless other[i]
|
20
|
+
|
21
|
+
if other[i] =~ DIGITS
|
22
|
+
if curr[i] =~ DIGITS
|
23
|
+
other_i = other[i].to_i
|
24
|
+
curr_i = curr[i].to_i
|
25
|
+
|
26
|
+
next if other_i == curr_i
|
27
|
+
|
28
|
+
return curr_i > other_i
|
29
|
+
else
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
else
|
33
|
+
if curr[i] =~ DIGITS
|
34
|
+
return true
|
35
|
+
else
|
36
|
+
next if curr[i] == other[i]
|
37
|
+
return curr[i] > other[i]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def split(v)
|
48
|
+
v.split('.')
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|