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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -4
  3. data/ext/extconf.rb +92 -47
  4. data/ext/libskylight.yml +4 -4
  5. data/ext/skylight_native.c +248 -286
  6. data/lib/skylight.rb +19 -114
  7. data/lib/skylight/api.rb +1 -1
  8. data/lib/skylight/config.rb +176 -146
  9. data/lib/skylight/data/cacert.pem +717 -719
  10. data/lib/skylight/formatters/http.rb +1 -1
  11. data/lib/skylight/instrumenter.rb +28 -35
  12. data/lib/skylight/native.rb +58 -72
  13. data/lib/skylight/normalizers.rb +0 -1
  14. data/lib/skylight/normalizers/active_record/sql.rb +0 -4
  15. data/lib/skylight/probes/excon/middleware.rb +3 -1
  16. data/lib/skylight/probes/net_http.rb +3 -1
  17. data/lib/skylight/subscriber.rb +0 -4
  18. data/lib/skylight/trace.rb +189 -0
  19. data/lib/skylight/util.rb +10 -12
  20. data/lib/skylight/util/hostname.rb +17 -0
  21. data/lib/skylight/util/http.rb +33 -36
  22. data/lib/skylight/util/logging.rb +20 -1
  23. data/lib/skylight/util/multi_io.rb +21 -0
  24. data/lib/skylight/util/native_ext_fetcher.rb +83 -69
  25. data/lib/skylight/util/platform.rb +67 -0
  26. data/lib/skylight/util/ssl.rb +50 -0
  27. data/lib/skylight/version.rb +1 -1
  28. metadata +9 -34
  29. data/ext/rust_support/ruby.h +0 -93
  30. data/ext/skylight.h +0 -85
  31. data/ext/skylight.map +0 -4
  32. data/ext/test/extconf.rb +0 -18
  33. data/ext/test/skylight_native_test.c +0 -82
  34. data/ext/test/skylight_test.h +0 -20
  35. data/lib/skylight/formatters.rb +0 -6
  36. data/lib/skylight/messages.rb +0 -21
  37. data/lib/skylight/messages/error.rb +0 -15
  38. data/lib/skylight/messages/hello.rb +0 -13
  39. data/lib/skylight/messages/trace.rb +0 -179
  40. data/lib/skylight/messages/trace_envelope.rb +0 -19
  41. data/lib/skylight/metrics.rb +0 -9
  42. data/lib/skylight/metrics/ewma.rb +0 -69
  43. data/lib/skylight/metrics/meter.rb +0 -58
  44. data/lib/skylight/metrics/process_cpu_gauge.rb +0 -65
  45. data/lib/skylight/metrics/process_mem_gauge.rb +0 -34
  46. data/lib/skylight/util/conversions.rb +0 -9
  47. data/lib/skylight/util/queue.rb +0 -96
  48. data/lib/skylight/util/task.rb +0 -172
  49. data/lib/skylight/util/uniform_sample.rb +0 -63
  50. data/lib/skylight/worker.rb +0 -19
  51. data/lib/skylight/worker/builder.rb +0 -73
  52. data/lib/skylight/worker/collector.rb +0 -274
  53. data/lib/skylight/worker/connection.rb +0 -87
  54. data/lib/skylight/worker/connection_set.rb +0 -56
  55. data/lib/skylight/worker/embedded.rb +0 -24
  56. data/lib/skylight/worker/metrics_reporter.rb +0 -104
  57. data/lib/skylight/worker/server.rb +0 -336
  58. data/lib/skylight/worker/standalone.rb +0 -421
@@ -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
@@ -1,6 +0,0 @@
1
- module Skylight
2
- # @api private
3
- module Formatters
4
- autoload :HTTP, 'skylight/formatters/http'
5
- end
6
- end
@@ -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,13 +0,0 @@
1
- module Skylight
2
- # @api private
3
- module Messages
4
- class Hello
5
- def self.build(version, cmd=[])
6
- Skylight::Hello.native_new(version, 0).tap do |hello|
7
- cmd.each { |part| hello.native_add_cmd_part(part) }
8
- end
9
- end
10
-
11
- end
12
- end
13
- 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
@@ -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