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,34 +0,0 @@
1
- module Skylight
2
- module Metrics
3
- class ProcessMemGauge
4
-
5
- def initialize(cache_for = 30, clock = Util::Clock.default)
6
- @value = nil
7
- @cache_for = cache_for
8
- @last_check_at = 0
9
- @clock = clock
10
- end
11
-
12
- def call(now = @clock.absolute_secs)
13
- if !@value || should_check?(now)
14
- @value = check
15
- @last_check_at = now
16
- end
17
-
18
- @value
19
- end
20
-
21
- private
22
-
23
- def check
24
- `ps -o rss= -p #{Process.pid}`.to_i / 1024
25
- rescue Errno::ENOENT, Errno::EINTR
26
- 0
27
- end
28
-
29
- def should_check?(now)
30
- now >= @last_check_at + @cache_for
31
- end
32
- end
33
- end
34
- end
@@ -1,9 +0,0 @@
1
- module Skylight
2
- module Util
3
- module Conversions
4
- def secs_to_nanos(secs)
5
- secs * 1_000_000_000
6
- end
7
- end
8
- end
9
- end
@@ -1,96 +0,0 @@
1
- require 'thread'
2
-
3
- module Skylight
4
- module Util
5
- # Simple thread-safe queue backed by a ring buffer. Will only block when
6
- # poping. Single consumer only
7
- class Queue
8
-
9
- def initialize(max)
10
- unless max > 0
11
- raise ArgumentError, "queue size must be positive"
12
- end
13
-
14
- @max = max
15
- @values = [nil] * max
16
- @consume = 0
17
- @produce = 0
18
- @waiting = nil
19
- @mutex = Mutex.new
20
- end
21
-
22
- def empty?
23
- @mutex.synchronize { __empty? }
24
- end
25
-
26
- def length
27
- @mutex.synchronize { __length }
28
- end
29
-
30
- # Returns the number of items in the queue or nil if the queue is full
31
- def push(obj)
32
- ret = nil
33
-
34
- @mutex.synchronize do
35
- return if __length == @max
36
- @values[@produce] = obj
37
- @produce = (@produce + 1) % @max
38
-
39
- ret = __length
40
-
41
- # Wakeup a blocked thread
42
- if t = @waiting
43
- t.run rescue nil
44
- end
45
- end
46
-
47
- ret
48
- end
49
-
50
- def pop(timeout = nil)
51
- if timeout && timeout < 0
52
- raise ArgumentError, "timeout must be nil or >= than 0"
53
- end
54
-
55
- @mutex.synchronize do
56
- if __empty?
57
- if !timeout || timeout > 0
58
- return if @waiting
59
- @waiting = Thread.current
60
- begin
61
- @mutex.sleep(timeout)
62
- ensure
63
- @waiting = nil
64
- end
65
- else
66
- return
67
- end
68
- end
69
-
70
- __pop unless __empty?
71
- end
72
- end
73
-
74
- private
75
-
76
- def __length
77
- ((@produce - @consume) % @max)
78
- end
79
-
80
- def __empty?
81
- @produce == @consume
82
- end
83
-
84
- def __pop
85
- i = @consume
86
- v = @values[i]
87
-
88
- @values[i] = nil
89
- @consume = (i + 1) % @max
90
-
91
- return v
92
- end
93
-
94
- end
95
- end
96
- end
@@ -1,172 +0,0 @@
1
- require 'thread'
2
-
3
- module Skylight
4
- module Util
5
- class Task
6
- SHUTDOWN = :__SK_TASK_SHUTDOWN
7
-
8
- # Requires the subclass to define `config`
9
- include Util::Logging
10
-
11
- attr_reader :queue_depth_metric
12
-
13
- def initialize(size, timeout = 0.1, &blk)
14
- @pid = Process.pid
15
- @thread = nil
16
- @size = size
17
- @lock = Mutex.new
18
- @timeout = timeout
19
- @blk = blk
20
-
21
- @queue_depth_metric = build_queue_depth_metric
22
- end
23
-
24
- def submit(msg, pid = Process.pid)
25
- return unless @pid
26
-
27
- spawn(pid)
28
-
29
- return unless q = @queue
30
-
31
- !!q.push(msg)
32
- end
33
-
34
- def spawn(pid = Process.pid)
35
- unless spawned?
36
- __spawn(pid)
37
- end
38
-
39
- true
40
- end
41
-
42
- def spawned?
43
- !!@thread
44
- end
45
-
46
- def running?
47
- spawned? && @pid
48
- end
49
-
50
- def shutdown(timeout = 5)
51
- t = nil
52
- m = false
53
-
54
- @lock.synchronize do
55
- t = @thread
56
-
57
- if q = @queue
58
- m = true
59
- q.push(SHUTDOWN)
60
- @pid = nil
61
- end
62
- end
63
-
64
- return true if timeout && timeout < 0
65
- return true unless t
66
-
67
- ret = nil
68
-
69
- begin
70
- ret = !!t.join(timeout)
71
- ensure
72
- if !ret && m
73
- begin
74
- t.kill # FORCE KILL!!!
75
- rescue ThreadError
76
- end
77
- end
78
- end
79
-
80
- ret
81
- end
82
-
83
- private
84
-
85
- def __spawn(pid)
86
- @lock.synchronize do
87
- return if spawned? && @pid == pid
88
- @pid = Process.pid
89
- @queue = Util::Queue.new(@size)
90
- @thread = Thread.new do
91
- begin
92
- prepare
93
-
94
- unless work
95
- @queue = nil
96
- end
97
-
98
- t { "shutting down task" }
99
- finish
100
- rescue Exception => e
101
- error "failed to execute task; msg=%s", e.message
102
- t { e.backtrace.join("\n") }
103
- end
104
- end
105
- end
106
-
107
- true
108
- end
109
-
110
- def work
111
- return unless q = @queue
112
-
113
- while @pid
114
- if msg = q.pop(@timeout)
115
- return true if SHUTDOWN == msg
116
-
117
- unless __handle(msg)
118
- return false
119
- end
120
- else
121
- return unless @queue
122
- # just a tick
123
- unless __handle(msg)
124
- return false
125
- end
126
- end
127
- end
128
-
129
- # Drain the queue
130
- while msg = q.pop(0)
131
- return true if SHUTDOWN == msg
132
-
133
- unless __handle(msg)
134
- return false
135
- end
136
- end
137
-
138
- true
139
- end
140
-
141
- def __handle(msg)
142
- begin
143
- handle(msg)
144
- rescue Exception => e
145
- error "error handling event; msg=%s; event=%p", e.message, msg
146
- t { e.backtrace.join("\n") }
147
- sleep 1
148
- true
149
- end
150
- end
151
-
152
- def handle(msg)
153
- return true unless @blk
154
- @blk.call(msg)
155
- end
156
-
157
- def prepare
158
- end
159
-
160
- def finish
161
- end
162
-
163
- def build_queue_depth_metric
164
- lambda do
165
- q = @queue
166
- q ? @queue.length : 0
167
- end
168
- end
169
-
170
- end
171
- end
172
- end
@@ -1,63 +0,0 @@
1
- module Skylight
2
- module Util
3
- class UniformSample
4
- include Enumerable
5
-
6
- attr_reader :size, :count
7
-
8
- def initialize(size)
9
- @size = size
10
- @count = 0
11
- @values = []
12
- end
13
-
14
- def clear
15
- @count = 0
16
- @values.clear
17
- self
18
- end
19
-
20
- def length
21
- @size < @count ? @size : @count
22
- end
23
-
24
- def empty?
25
- @count == 0
26
- end
27
-
28
- def each
29
- i = 0
30
- to = length
31
-
32
- while i < to
33
- yield @values[i]
34
- i += 1
35
- end
36
-
37
- self
38
- end
39
-
40
- def <<(v)
41
- if idx = increment!
42
- @values[idx] = v
43
- end
44
-
45
- self
46
- end
47
-
48
- private
49
-
50
- def increment!
51
- c = (@count += 1)
52
-
53
- if (c <= @size)
54
- c - 1
55
- else
56
- r = rand(@count)
57
- r if r < @size
58
- end
59
- end
60
-
61
- end
62
- end
63
- end
@@ -1,19 +0,0 @@
1
- module Skylight
2
- # @api private
3
- module Worker
4
-
5
- # === Constants
6
- CHUNK_SIZE = 16 * 1024
7
-
8
- # === Modules
9
- autoload :Builder, 'skylight/worker/builder'
10
- autoload :Collector, 'skylight/worker/collector'
11
- autoload :Connection, 'skylight/worker/connection'
12
- autoload :ConnectionSet, 'skylight/worker/connection_set'
13
- autoload :Embedded, 'skylight/worker/embedded'
14
- autoload :MetricsReporter, 'skylight/worker/metrics_reporter'
15
- autoload :Server, 'skylight/worker/server'
16
- autoload :Standalone, 'skylight/worker/standalone'
17
-
18
- end
19
- end
@@ -1,73 +0,0 @@
1
- module Skylight
2
- module Worker
3
- class Builder
4
- include Util::Logging
5
-
6
- attr_reader :config
7
-
8
- def initialize(config = Config.new)
9
- if Hash === config
10
- config = Config.new(config)
11
- end
12
-
13
- @config = config
14
- end
15
-
16
- def build
17
- s = strategy.to_s
18
-
19
- case s
20
- when 'embedded'
21
- trace "building embedded worker"
22
- Embedded.new(Collector.build(config))
23
- when 'standalone'
24
- trace "building standalone worker"
25
-
26
- unless config[:'agent.sockfile_path']
27
- raise ConfigError, 'agent.sockfile_path required'
28
- end
29
-
30
- Standalone.new(
31
- config,
32
- lockfile,
33
- server)
34
- else
35
- # We can assume that if it's unknown it's from the config
36
- raise ConfigError, "unknown agent.strategy: `#{s}`"
37
- end
38
- end
39
-
40
- private
41
-
42
- def strategy
43
- config.get(:'agent.strategy') || default_strategy
44
- end
45
-
46
- def default_strategy
47
- ret = if jruby?
48
- 'embedded'
49
- else
50
- 'standalone'
51
- end
52
-
53
- ret.downcase.strip
54
- end
55
-
56
- def lockfile
57
- config.get(:'agent.lockfile') do
58
- name = [ 'skylight', config.environment ].compact.join('-')
59
- File.join(config[:'agent.sockfile_path'], "#{name}.pid")
60
- end.to_s
61
- end
62
-
63
- def server
64
- config.get(:'agent.server', Server)
65
- end
66
-
67
- def jruby?
68
- defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
69
- end
70
-
71
- end
72
- end
73
- end