skylight 0.3.21 → 0.4.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
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