skylight 0.3.21 → 0.4.0.alpha1
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/CHANGELOG.md +0 -4
- data/ext/extconf.rb +92 -47
- data/ext/libskylight.yml +4 -4
- data/ext/skylight_native.c +248 -286
- data/lib/skylight.rb +19 -114
- data/lib/skylight/api.rb +1 -1
- data/lib/skylight/config.rb +176 -146
- data/lib/skylight/data/cacert.pem +717 -719
- data/lib/skylight/formatters/http.rb +1 -1
- data/lib/skylight/instrumenter.rb +28 -35
- data/lib/skylight/native.rb +58 -72
- data/lib/skylight/normalizers.rb +0 -1
- data/lib/skylight/normalizers/active_record/sql.rb +0 -4
- data/lib/skylight/probes/excon/middleware.rb +3 -1
- data/lib/skylight/probes/net_http.rb +3 -1
- data/lib/skylight/subscriber.rb +0 -4
- data/lib/skylight/trace.rb +189 -0
- data/lib/skylight/util.rb +10 -12
- data/lib/skylight/util/hostname.rb +17 -0
- data/lib/skylight/util/http.rb +33 -36
- data/lib/skylight/util/logging.rb +20 -1
- data/lib/skylight/util/multi_io.rb +21 -0
- data/lib/skylight/util/native_ext_fetcher.rb +83 -69
- data/lib/skylight/util/platform.rb +67 -0
- data/lib/skylight/util/ssl.rb +50 -0
- data/lib/skylight/version.rb +1 -1
- metadata +9 -34
- data/ext/rust_support/ruby.h +0 -93
- data/ext/skylight.h +0 -85
- data/ext/skylight.map +0 -4
- data/ext/test/extconf.rb +0 -18
- data/ext/test/skylight_native_test.c +0 -82
- data/ext/test/skylight_test.h +0 -20
- data/lib/skylight/formatters.rb +0 -6
- data/lib/skylight/messages.rb +0 -21
- data/lib/skylight/messages/error.rb +0 -15
- data/lib/skylight/messages/hello.rb +0 -13
- data/lib/skylight/messages/trace.rb +0 -179
- data/lib/skylight/messages/trace_envelope.rb +0 -19
- data/lib/skylight/metrics.rb +0 -9
- data/lib/skylight/metrics/ewma.rb +0 -69
- data/lib/skylight/metrics/meter.rb +0 -58
- data/lib/skylight/metrics/process_cpu_gauge.rb +0 -65
- data/lib/skylight/metrics/process_mem_gauge.rb +0 -34
- data/lib/skylight/util/conversions.rb +0 -9
- data/lib/skylight/util/queue.rb +0 -96
- data/lib/skylight/util/task.rb +0 -172
- data/lib/skylight/util/uniform_sample.rb +0 -63
- data/lib/skylight/worker.rb +0 -19
- data/lib/skylight/worker/builder.rb +0 -73
- data/lib/skylight/worker/collector.rb +0 -274
- data/lib/skylight/worker/connection.rb +0 -87
- data/lib/skylight/worker/connection_set.rb +0 -56
- data/lib/skylight/worker/embedded.rb +0 -24
- data/lib/skylight/worker/metrics_reporter.rb +0 -104
- data/lib/skylight/worker/server.rb +0 -336
- data/lib/skylight/worker/standalone.rb +0 -421
data/ext/test/skylight_test.h
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
#ifndef __SKYLIGHT_TEST_H__
|
2
|
-
#define __SKYLIGHT_TEST_H__
|
3
|
-
|
4
|
-
#include <stddef.h>
|
5
|
-
#include <stdint.h>
|
6
|
-
#include <stdbool.h>
|
7
|
-
|
8
|
-
#include <rust_support/ruby.h>
|
9
|
-
|
10
|
-
typedef void * RustPerson;
|
11
|
-
|
12
|
-
bool skylight_test_numeric_multiply(uint64_t, uint64_t, uint64_t*);
|
13
|
-
bool skylight_test_strings_reverse(RustSlice, RustString*);
|
14
|
-
|
15
|
-
bool skylight_test_person_new(RustSlice, uint64_t, RustPerson*);
|
16
|
-
bool skylight_test_person_get_name(RustPerson, RustSlice*);
|
17
|
-
bool skylight_test_person_get_age(RustPerson, uint64_t*);
|
18
|
-
bool skylight_test_person_free(RustPerson);
|
19
|
-
|
20
|
-
#endif
|
data/lib/skylight/formatters.rb
DELETED
data/lib/skylight/messages.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
module Skylight
|
2
|
-
# @api private
|
3
|
-
module Messages
|
4
|
-
require 'skylight/messages/trace'
|
5
|
-
require 'skylight/messages/hello'
|
6
|
-
require 'skylight/messages/error'
|
7
|
-
require 'skylight/messages/trace_envelope'
|
8
|
-
|
9
|
-
KLASS_TO_ID = {
|
10
|
-
Skylight::Trace => 0,
|
11
|
-
Skylight::Hello => 1,
|
12
|
-
Skylight::Error => 2
|
13
|
-
}
|
14
|
-
|
15
|
-
ID_TO_KLASS = {
|
16
|
-
0 => Skylight::Messages::TraceEnvelope,
|
17
|
-
1 => Skylight::Hello,
|
18
|
-
2 => Skylight::Error
|
19
|
-
}
|
20
|
-
end
|
21
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Skylight
|
2
|
-
module Messages
|
3
|
-
class Error
|
4
|
-
def self.deserialize(buf)
|
5
|
-
decode(buf)
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.build(group, description, details = nil)
|
9
|
-
Skylight::Error.native_new(group, description).tap do |error|
|
10
|
-
error.native_set_details(details) if details
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,179 +0,0 @@
|
|
1
|
-
module Skylight
|
2
|
-
module Messages
|
3
|
-
class Trace
|
4
|
-
class Builder
|
5
|
-
GC_CAT = 'noise.gc'.freeze
|
6
|
-
|
7
|
-
include Util::Logging
|
8
|
-
|
9
|
-
attr_reader :endpoint, :spans, :notifications
|
10
|
-
|
11
|
-
def endpoint=(value)
|
12
|
-
@endpoint = value.is_a?(String) ? value.freeze : value
|
13
|
-
@native_builder.native_set_name(value)
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize(instrumenter, endpoint, start, cat, title=nil, desc=nil, annot=nil)
|
17
|
-
raise ArgumentError, 'instrumenter is required' unless instrumenter
|
18
|
-
|
19
|
-
start = normalize_time(start)
|
20
|
-
|
21
|
-
@native_builder = ::Skylight::Trace.native_new(start, "TODO")
|
22
|
-
@native_builder.native_set_name(endpoint)
|
23
|
-
|
24
|
-
@instrumenter = instrumenter
|
25
|
-
@endpoint = endpoint
|
26
|
-
@submitted = false
|
27
|
-
@start = start
|
28
|
-
|
29
|
-
@notifications = []
|
30
|
-
|
31
|
-
if Hash === title
|
32
|
-
annot = title
|
33
|
-
title = desc = nil
|
34
|
-
elsif Hash === desc
|
35
|
-
annot = desc
|
36
|
-
desc = nil
|
37
|
-
end
|
38
|
-
|
39
|
-
# create the root node
|
40
|
-
@root = @native_builder.native_start_span(@start, cat)
|
41
|
-
@native_builder.native_span_set_title(@root, title) if title
|
42
|
-
@native_builder.native_span_set_description(@root, desc) if desc
|
43
|
-
|
44
|
-
@gc = config.gc.track unless ENV.key?("SKYLIGHT_DISABLE_GC_TRACKING")
|
45
|
-
end
|
46
|
-
|
47
|
-
def serialize
|
48
|
-
raise "Can only serialize once" if @serialized
|
49
|
-
@serialized = true
|
50
|
-
@native_builder.native_serialize
|
51
|
-
end
|
52
|
-
|
53
|
-
def config
|
54
|
-
@instrumenter.config
|
55
|
-
end
|
56
|
-
|
57
|
-
def record(cat, title=nil, desc=nil, annot=nil)
|
58
|
-
if Hash === title
|
59
|
-
annot = title
|
60
|
-
title = desc = nil
|
61
|
-
elsif Hash === desc
|
62
|
-
annot = desc
|
63
|
-
desc = nil
|
64
|
-
end
|
65
|
-
|
66
|
-
title.freeze if title.is_a?(String)
|
67
|
-
desc.freeze if desc.is_a?(String)
|
68
|
-
|
69
|
-
desc = @instrumenter.limited_description(desc)
|
70
|
-
|
71
|
-
time = Util::Clock.nanos - gc_time
|
72
|
-
|
73
|
-
stop(start(time, cat, title, desc), time)
|
74
|
-
|
75
|
-
nil
|
76
|
-
end
|
77
|
-
|
78
|
-
def instrument(cat, title=nil, desc=nil, annot=nil)
|
79
|
-
t { "instrument: #{cat}, #{title}" }
|
80
|
-
|
81
|
-
if Hash === title
|
82
|
-
annot = title
|
83
|
-
title = desc = nil
|
84
|
-
elsif Hash === desc
|
85
|
-
annot = desc
|
86
|
-
desc = nil
|
87
|
-
end
|
88
|
-
|
89
|
-
title.freeze if title.is_a?(String)
|
90
|
-
desc.freeze if desc.is_a?(String)
|
91
|
-
|
92
|
-
original_desc = desc
|
93
|
-
now = Util::Clock.nanos
|
94
|
-
desc = @instrumenter.limited_description(desc)
|
95
|
-
|
96
|
-
if desc == Instrumenter::TOO_MANY_UNIQUES
|
97
|
-
debug "[SKYLIGHT] [#{Skylight::VERSION}] A payload description produced <too many uniques>"
|
98
|
-
debug "original desc=%s", original_desc
|
99
|
-
debug "cat=%s, title=%s, desc=%s, annot=%s", cat, title, desc, annot.inspect
|
100
|
-
end
|
101
|
-
|
102
|
-
start(now - gc_time, cat, title, desc, annot)
|
103
|
-
end
|
104
|
-
|
105
|
-
def done(span)
|
106
|
-
return unless span
|
107
|
-
stop(span, Util::Clock.nanos - gc_time)
|
108
|
-
end
|
109
|
-
|
110
|
-
def release
|
111
|
-
return unless @instrumenter.current_trace == self
|
112
|
-
@instrumenter.current_trace = nil
|
113
|
-
end
|
114
|
-
|
115
|
-
def traced
|
116
|
-
time = gc_time
|
117
|
-
now = Util::Clock.nanos
|
118
|
-
|
119
|
-
if time > 0
|
120
|
-
t { fmt "tracking GC time; duration=%d", time }
|
121
|
-
stop(start(now - time, GC_CAT, nil, nil, {}), now)
|
122
|
-
end
|
123
|
-
|
124
|
-
stop(@root, now)
|
125
|
-
end
|
126
|
-
|
127
|
-
def submit
|
128
|
-
t { "submitting trace" }
|
129
|
-
|
130
|
-
if @submitted
|
131
|
-
t { "already submitted" }
|
132
|
-
return
|
133
|
-
end
|
134
|
-
|
135
|
-
release
|
136
|
-
@submitted = true
|
137
|
-
|
138
|
-
traced
|
139
|
-
|
140
|
-
@instrumenter.process(@native_builder)
|
141
|
-
rescue Exception => e
|
142
|
-
error e
|
143
|
-
t { e.backtrace.join("\n") }
|
144
|
-
end
|
145
|
-
|
146
|
-
private
|
147
|
-
|
148
|
-
def start(time, cat, title, desc, annot=nil)
|
149
|
-
span(normalize_time(time), cat, title, desc, annot)
|
150
|
-
end
|
151
|
-
|
152
|
-
def stop(span, time)
|
153
|
-
@native_builder.native_stop_span(span, normalize_time(time))
|
154
|
-
nil
|
155
|
-
end
|
156
|
-
|
157
|
-
def normalize_time(time)
|
158
|
-
# At least one customer has extensions that cause integer division to produce rationals.
|
159
|
-
# Since the native code expects an integer, we force it again.
|
160
|
-
(time.to_i / 100_000).to_i
|
161
|
-
end
|
162
|
-
|
163
|
-
def span(time, cat, title=nil, desc=nil, annot=nil)
|
164
|
-
sp = @native_builder.native_start_span(time, cat.to_s)
|
165
|
-
@native_builder.native_span_set_title(sp, title.to_s) if title
|
166
|
-
@native_builder.native_span_set_description(sp, desc.to_s) if desc
|
167
|
-
sp
|
168
|
-
end
|
169
|
-
|
170
|
-
def gc_time
|
171
|
-
return 0 unless @gc
|
172
|
-
@gc.update
|
173
|
-
@gc.time
|
174
|
-
end
|
175
|
-
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module Skylight
|
2
|
-
module Messages
|
3
|
-
class TraceEnvelope
|
4
|
-
def self.deserialize(data)
|
5
|
-
new(data)
|
6
|
-
end
|
7
|
-
|
8
|
-
attr_reader :data
|
9
|
-
|
10
|
-
def initialize(data)
|
11
|
-
@data = data
|
12
|
-
end
|
13
|
-
|
14
|
-
def endpoint_name
|
15
|
-
Skylight::Trace.native_name_from_serialized(@data)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
data/lib/skylight/metrics.rb
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
module Skylight
|
2
|
-
# @api private
|
3
|
-
module Metrics
|
4
|
-
autoload :Meter, 'skylight/metrics/meter'
|
5
|
-
autoload :EWMA, 'skylight/metrics/ewma'
|
6
|
-
autoload :ProcessMemGauge, 'skylight/metrics/process_mem_gauge'
|
7
|
-
autoload :ProcessCpuGauge, 'skylight/metrics/process_cpu_gauge'
|
8
|
-
end
|
9
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
module Skylight
|
2
|
-
module Metrics
|
3
|
-
|
4
|
-
# An exponentially-weighted moving average. Not thread-safe
|
5
|
-
class EWMA
|
6
|
-
include Util::Conversions
|
7
|
-
|
8
|
-
INTERVAL = 5
|
9
|
-
|
10
|
-
# Some common EWMA
|
11
|
-
attr_reader :interval
|
12
|
-
|
13
|
-
def initialize(alpha, interval)
|
14
|
-
@rate = 0.0
|
15
|
-
@alpha = alpha
|
16
|
-
@interval = secs_to_nanos(interval).to_f
|
17
|
-
@uncounted = 0
|
18
|
-
@initialized = false
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.alpha(minutes, interval = INTERVAL)
|
22
|
-
1 - Math.exp(-interval / 60.0 / minutes)
|
23
|
-
end
|
24
|
-
|
25
|
-
# Some common EWMA
|
26
|
-
|
27
|
-
M1 = alpha(1)
|
28
|
-
M5 = alpha(5)
|
29
|
-
M15 = alpha(15)
|
30
|
-
|
31
|
-
def self.one_minute_ewma
|
32
|
-
EWMA.new M1, INTERVAL
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.five_minute_ewma
|
36
|
-
EWMA.new M5, INTERVAL
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.fifteen_minute_ewma
|
40
|
-
EWMA.new M15, INTERVAL
|
41
|
-
end
|
42
|
-
|
43
|
-
def update(count)
|
44
|
-
@uncounted += count
|
45
|
-
end
|
46
|
-
|
47
|
-
def tick
|
48
|
-
# Compute the rate this interval (aka the num of occurences this tick)
|
49
|
-
instant_rate = @uncounted / @interval
|
50
|
-
|
51
|
-
# Reset the count
|
52
|
-
@uncounted = 0
|
53
|
-
|
54
|
-
if @initialized
|
55
|
-
@rate += (@alpha * (instant_rate - @rate))
|
56
|
-
else
|
57
|
-
@rate = instant_rate
|
58
|
-
@initialized = true
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# Get the rate in the requested interval (where the interval is specified
|
63
|
-
# in number of seconds
|
64
|
-
def rate(interval = 1)
|
65
|
-
@rate * secs_to_nanos(interval)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'thread'
|
2
|
-
|
3
|
-
module Skylight
|
4
|
-
module Metrics
|
5
|
-
class Meter
|
6
|
-
def initialize(ewma = EWMA.one_minute_ewma, clock = Util::Clock.default)
|
7
|
-
@ewma = ewma
|
8
|
-
@lock = Mutex.new
|
9
|
-
@clock = clock
|
10
|
-
@start_time = @clock.tick
|
11
|
-
@last_tick = @start_time
|
12
|
-
end
|
13
|
-
|
14
|
-
def mark(n = 1)
|
15
|
-
@lock.synchronize do
|
16
|
-
tick_if_necessary
|
17
|
-
@ewma.update(n)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def rate
|
22
|
-
@lock.synchronize do
|
23
|
-
tick_if_necessary
|
24
|
-
@ewma.rate(1)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def call
|
29
|
-
rate
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def tick_if_necessary
|
35
|
-
old_tick = @last_tick
|
36
|
-
new_tick = @clock.tick
|
37
|
-
|
38
|
-
# How far behind are we
|
39
|
-
age = new_tick - old_tick
|
40
|
-
|
41
|
-
if age >= @ewma.interval
|
42
|
-
new_tick = new_tick - age % @ewma.interval
|
43
|
-
|
44
|
-
# Update the last seen tick
|
45
|
-
@last_tick = new_tick
|
46
|
-
|
47
|
-
# Number of missing ticks
|
48
|
-
required_ticks = age / @ewma.interval
|
49
|
-
|
50
|
-
while required_ticks > 0
|
51
|
-
@ewma.tick
|
52
|
-
required_ticks -= 1
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
module Skylight
|
2
|
-
module Metrics
|
3
|
-
class ProcessCpuGauge
|
4
|
-
|
5
|
-
def initialize(cache_for = 5, clock = Util::Clock.default)
|
6
|
-
@value = nil
|
7
|
-
@cache_for = cache_for
|
8
|
-
@last_check_at = 0
|
9
|
-
@clock = clock
|
10
|
-
|
11
|
-
@last_totaltime = nil
|
12
|
-
@last_usagetime = nil
|
13
|
-
@last_utime = nil
|
14
|
-
@last_stime = nil
|
15
|
-
end
|
16
|
-
|
17
|
-
def call(now = @clock.absolute_secs)
|
18
|
-
if !@value || should_check?(now)
|
19
|
-
@value = check
|
20
|
-
@last_check_at = now
|
21
|
-
end
|
22
|
-
|
23
|
-
@value
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def check
|
29
|
-
ret = nil
|
30
|
-
|
31
|
-
statfile = "/proc/stat"
|
32
|
-
pidstatfile = "/proc/#{Process.pid}/stat"
|
33
|
-
|
34
|
-
if File.exist?(statfile) && File.exist?(pidstatfile)
|
35
|
-
cpustats = File.readlines(statfile).grep(/^cpu /).first.split(' ')
|
36
|
-
usagetime = cpustats[1..3].reduce(0){|sum, i| sum + i.to_i }
|
37
|
-
totaltime = usagetime + cpustats[4].to_i
|
38
|
-
|
39
|
-
pidstats = File.read(pidstatfile).split(' ')
|
40
|
-
utime, stime = pidstats[13].to_i, pidstats[14].to_i
|
41
|
-
|
42
|
-
if @last_totaltime && @last_usagetime && @last_utime && @last_stime
|
43
|
-
elapsed = totaltime - @last_totaltime
|
44
|
-
ret = [(usagetime - @last_usagetime).to_f / elapsed,
|
45
|
-
(utime - @last_utime).to_f / elapsed,
|
46
|
-
(stime - @last_stime).to_f / elapsed]
|
47
|
-
end
|
48
|
-
|
49
|
-
@last_totaltime = totaltime
|
50
|
-
@last_usagetime = usagetime
|
51
|
-
@last_utime = utime
|
52
|
-
@last_stime = stime
|
53
|
-
end
|
54
|
-
|
55
|
-
ret
|
56
|
-
rescue Errno::ENOENT
|
57
|
-
nil
|
58
|
-
end
|
59
|
-
|
60
|
-
def should_check?(now)
|
61
|
-
now >= @last_check_at + @cache_for
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|