skylight 0.3.10 → 0.3.11
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 +9 -0
- data/README.md +2 -0
- data/ext/extconf.rb +34 -4
- data/lib/skylight.rb +68 -45
- data/lib/skylight/api.rb +1 -0
- data/lib/skylight/cli.rb +1 -0
- data/lib/skylight/compat.rb +1 -0
- data/lib/skylight/config.rb +11 -6
- data/lib/skylight/formatters.rb +6 -0
- data/lib/skylight/gc.rb +1 -0
- data/lib/skylight/helpers.rb +60 -0
- data/lib/skylight/instrumenter.rb +3 -0
- data/lib/skylight/messages.rb +1 -0
- data/lib/skylight/messages/hello.rb +1 -0
- data/lib/skylight/metrics.rb +9 -0
- data/lib/skylight/middleware.rb +1 -0
- data/lib/skylight/native.rb +11 -0
- data/lib/skylight/normalizers.rb +2 -2
- data/lib/skylight/probes.rb +2 -1
- data/lib/skylight/railtie.rb +2 -1
- data/lib/skylight/subscriber.rb +1 -0
- data/lib/skylight/util.rb +18 -0
- data/lib/skylight/util/allocation_free.rb +11 -9
- data/lib/skylight/util/http.rb +28 -5
- data/lib/skylight/util/native_ext_fetcher.rb +27 -31
- data/lib/skylight/version.rb +1 -1
- data/lib/skylight/vm/gc.rb +1 -0
- data/lib/skylight/worker.rb +1 -0
- data/lib/skylight/worker/metrics_reporter.rb +1 -1
- data/lib/skylight/worker/server.rb +2 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba7ee3852dc0f4d87a9d974aeade1100cde21613
|
4
|
+
data.tar.gz: 4101c8d467fbbd2c5fccb0124a02b2cf0634232d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df39f86e95a05dc50973fc6a0ceda455eec6ffb9ca77bc19a3a8726e9099349303905eb282e845886aa220ff88da413d516754215234cb5194b274b60a4f5bb9
|
7
|
+
data.tar.gz: c54def8443d4ebc20d576ad38891acf1b58252fd62d34534e3c905385474bd1b759794f4fc55097c60be47e5b8397fb319808618d7ad091014a7aeea0a10a1bf
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 0.3.11 (April 11, 2014)
|
2
|
+
|
3
|
+
* Improved error handling and internal metrics
|
4
|
+
* Improved missing native agent message
|
5
|
+
* Improved install logging
|
6
|
+
* Added initial inline docs
|
7
|
+
* Respects HTTP_PROXY env var during installation
|
8
|
+
* Don't overwrite sockfile_path if set explicitly
|
9
|
+
|
1
10
|
## 0.3.10 (April 8, 2014)
|
2
11
|
|
3
12
|
* Don't raise on missing native agent path
|
data/README.md
CHANGED
data/ext/extconf.rb
CHANGED
@@ -2,7 +2,27 @@ require 'mkmf'
|
|
2
2
|
require 'yaml'
|
3
3
|
require 'logger'
|
4
4
|
|
5
|
-
|
5
|
+
# Must require 'rubygems/platform' vs. just requiring 'rubygems' to avoid a
|
6
|
+
# stack overflow bug on ruby 1.9.2.
|
7
|
+
require 'rubygems/platform'
|
8
|
+
|
9
|
+
class MultiIO
|
10
|
+
def initialize(*targets)
|
11
|
+
@targets = targets
|
12
|
+
end
|
13
|
+
|
14
|
+
def write(*args)
|
15
|
+
@targets.each {|t| t.write(*args)}
|
16
|
+
end
|
17
|
+
|
18
|
+
def close
|
19
|
+
@targets.each(&:close)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
log_file = File.open(File.expand_path("../install.log", __FILE__), "a")
|
24
|
+
LOG = Logger.new(MultiIO.new(STDOUT, log_file))
|
25
|
+
|
6
26
|
SKYLIGHT_REQUIRED = ENV.key?("SKYLIGHT_REQUIRED") && ENV['SKYLIGHT_REQUIRED'] !~ /^false$/i
|
7
27
|
|
8
28
|
require_relative '../lib/skylight/version'
|
@@ -14,8 +34,8 @@ include Skylight::Util
|
|
14
34
|
# want to break our customer's deploy, but extconf.rb requires a Makefile to be
|
15
35
|
# present upon a successful exit. To satisfy this requirement, we create a
|
16
36
|
# dummy Makefile.
|
17
|
-
def fail(msg)
|
18
|
-
LOG.
|
37
|
+
def fail(msg, type=:error)
|
38
|
+
LOG.send type, msg
|
19
39
|
|
20
40
|
if SKYLIGHT_REQUIRED
|
21
41
|
exit 1
|
@@ -50,11 +70,21 @@ unless File.exist?(libskylight_a)
|
|
50
70
|
fail "libskylight checksums missing from `#{libskylight_yml}`"
|
51
71
|
end
|
52
72
|
|
73
|
+
platform = Gem::Platform.local
|
74
|
+
arch = "#{platform.os}-#{platform.cpu}"
|
75
|
+
|
76
|
+
unless checksum = checksums[arch]
|
77
|
+
fail "no checksum entry for requested architecture -- " \
|
78
|
+
"this probably means the requested architecture is not supported; " \
|
79
|
+
"arch=#{arch}; available=#{checksums.keys}", :info
|
80
|
+
end
|
81
|
+
|
53
82
|
begin
|
54
83
|
res = NativeExtFetcher.fetch(
|
55
84
|
version: version,
|
56
85
|
target: libskylight_a,
|
57
|
-
|
86
|
+
checksum: checksum,
|
87
|
+
arch: arch,
|
58
88
|
required: SKYLIGHT_REQUIRED,
|
59
89
|
logger: LOG)
|
60
90
|
|
data/lib/skylight.rb
CHANGED
@@ -3,10 +3,16 @@ require 'socket'
|
|
3
3
|
require 'skylight/version'
|
4
4
|
|
5
5
|
module Skylight
|
6
|
+
# @api private
|
6
7
|
TRACE_ENV_KEY = 'SKYLIGHT_ENABLE_TRACE_LOGS'.freeze
|
8
|
+
|
9
|
+
# @api private
|
7
10
|
STANDALONE_ENV_KEY = 'SKYLIGHT_STANDALONE'.freeze
|
11
|
+
|
12
|
+
# @api private
|
8
13
|
STANDALONE_ENV_VAL = 'server'.freeze
|
9
14
|
|
15
|
+
# @api private
|
10
16
|
# Whether or not the native extension is present
|
11
17
|
@@has_native_ext = false
|
12
18
|
|
@@ -29,39 +35,41 @@ module Skylight
|
|
29
35
|
raise if ENV.key?("SKYLIGHT_REQUIRED")
|
30
36
|
end
|
31
37
|
|
32
|
-
|
33
|
-
|
34
|
-
autoload :Config, 'skylight/config'
|
35
|
-
autoload :Helpers, 'skylight/helpers'
|
36
|
-
|
37
|
-
module Util
|
38
|
-
autoload :Logging, 'skylight/util/logging'
|
39
|
-
autoload :HTTP, 'skylight/util/http'
|
38
|
+
if defined?(Rails)
|
39
|
+
require 'skylight/railtie'
|
40
40
|
end
|
41
41
|
|
42
|
-
#
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
class TraceError < RuntimeError; end
|
47
|
-
class SerializeError < RuntimeError; end
|
42
|
+
# @api private
|
43
|
+
def self.check_install_errors
|
44
|
+
# Note: An unsupported arch doesn't count as an error.
|
45
|
+
install_log = File.expand_path("../../ext/install.log", __FILE__)
|
48
46
|
|
49
|
-
|
50
|
-
|
47
|
+
if File.exist?(install_log) && File.read(install_log) =~ /ERROR/
|
48
|
+
puts "[SKYLIGHT] [#{Skylight::VERSION}] The Skylight native extension failed to install. " \
|
49
|
+
"Please check #{install_log} and notify support@skylight.io." \
|
50
|
+
"The missing extension will not affect the functioning of your application."
|
51
|
+
end
|
51
52
|
end
|
52
53
|
|
54
|
+
# @api private
|
53
55
|
def self.warn_skylight_native_missing
|
54
56
|
# TODO: Dumping the error messages this way is pretty hacky
|
55
57
|
is_rails = defined?(Rails)
|
56
58
|
env_name = is_rails ? Rails.env : "development"
|
57
59
|
|
58
60
|
if env_name == "development" || env_name == "test"
|
59
|
-
puts "[SKYLIGHT] [#{Skylight::VERSION}] Running Skylight in #{env_name} mode.
|
61
|
+
puts "[SKYLIGHT] [#{Skylight::VERSION}] Running Skylight in #{env_name} mode. " \
|
62
|
+
"No data will be reported until you deploy your app."
|
60
63
|
else
|
61
|
-
puts "[SKYLIGHT] [#{Skylight::VERSION}] The Skylight native extension for your platform wasn't found.
|
64
|
+
puts "[SKYLIGHT] [#{Skylight::VERSION}] The Skylight native extension for your platform wasn't found. " \
|
65
|
+
"The monitoring portion of Skylight is only supported on production servers running 32- or " \
|
66
|
+
"64-bit Linux. The missing extension will not affect the functioning of your application " \
|
67
|
+
"and you can continue local development without data being reported. If you are on a " \
|
68
|
+
"supported platform, please contact support at support@skylight.io."
|
62
69
|
end
|
63
70
|
end
|
64
71
|
|
72
|
+
# @api private
|
65
73
|
def self.daemon?
|
66
74
|
ENV[STANDALONE_ENV_KEY] == STANDALONE_ENV_VAL
|
67
75
|
end
|
@@ -74,38 +82,41 @@ module Skylight
|
|
74
82
|
require 'skylight/vm/gc'
|
75
83
|
end
|
76
84
|
|
85
|
+
autoload :Api, 'skylight/api'
|
86
|
+
autoload :CLI, 'skylight/cli'
|
87
|
+
autoload :Config, 'skylight/config'
|
88
|
+
autoload :Helpers, 'skylight/helpers'
|
89
|
+
autoload :Formatters, 'skylight/formatters'
|
77
90
|
autoload :GC, 'skylight/gc'
|
78
91
|
autoload :Instrumenter, 'skylight/instrumenter'
|
79
92
|
autoload :Messages, 'skylight/messages'
|
93
|
+
autoload :Metrics, 'skylight/metrics'
|
80
94
|
autoload :Middleware, 'skylight/middleware'
|
81
95
|
autoload :Normalizers, 'skylight/normalizers'
|
82
96
|
autoload :Subscriber, 'skylight/subscriber'
|
83
97
|
autoload :Worker, 'skylight/worker'
|
84
98
|
|
85
|
-
|
86
|
-
|
87
|
-
autoload :EWMA, 'skylight/metrics/ewma'
|
88
|
-
autoload :ProcessMemGauge, 'skylight/metrics/process_mem_gauge'
|
89
|
-
autoload :ProcessCpuGauge, 'skylight/metrics/process_cpu_gauge'
|
90
|
-
end
|
99
|
+
# Skylight::Util is defined by the native ext so we can't autoload
|
100
|
+
require 'skylight/util'
|
91
101
|
|
92
|
-
|
93
|
-
require 'skylight/util/clock'
|
94
|
-
|
95
|
-
autoload :Conversions, 'skylight/util/conversions'
|
96
|
-
autoload :Gzip, 'skylight/util/gzip'
|
97
|
-
autoload :HTTP, 'skylight/util/http'
|
98
|
-
autoload :Inflector, 'skylight/util/inflector'
|
99
|
-
autoload :Logging, 'skylight/util/logging'
|
100
|
-
autoload :Queue, 'skylight/util/queue'
|
101
|
-
autoload :Task, 'skylight/util/task'
|
102
|
-
autoload :UniformSample, 'skylight/util/uniform_sample'
|
103
|
-
end
|
102
|
+
# ==== Exceptions ====
|
104
103
|
|
105
|
-
|
106
|
-
|
107
|
-
|
104
|
+
# @api private
|
105
|
+
class IpcProtoError < RuntimeError; end
|
106
|
+
|
107
|
+
# @api private
|
108
|
+
class WorkerStateError < RuntimeError; end
|
109
|
+
|
110
|
+
# @api private
|
111
|
+
class ConfigError < RuntimeError; end
|
112
|
+
|
113
|
+
# @api private
|
114
|
+
class TraceError < RuntimeError; end
|
115
|
+
|
116
|
+
# @api private
|
117
|
+
class SerializeError < RuntimeError; end
|
108
118
|
|
119
|
+
# @api private
|
109
120
|
TIERS = %w(
|
110
121
|
api
|
111
122
|
app
|
@@ -114,25 +125,29 @@ module Skylight
|
|
114
125
|
noise
|
115
126
|
other)
|
116
127
|
|
128
|
+
# @api private
|
117
129
|
TIER_REGEX = /^(?:#{TIERS.join('|')})(?:\.|$)/u
|
130
|
+
|
131
|
+
# @api private
|
118
132
|
CATEGORY_REGEX = /^[a-z0-9_-]+(?:\.[a-z0-9_-]+)*$/iu
|
133
|
+
|
134
|
+
# @api private
|
119
135
|
DEFAULT_CATEGORY = "app.block".freeze
|
120
|
-
DEFAULT_OPTIONS = { category: DEFAULT_CATEGORY }
|
121
136
|
|
122
|
-
#
|
123
|
-
|
124
|
-
# ===== Public API =====
|
125
|
-
#
|
126
|
-
#
|
137
|
+
# @api private
|
138
|
+
DEFAULT_OPTIONS = { category: DEFAULT_CATEGORY }
|
127
139
|
|
140
|
+
# Start instrumenting
|
128
141
|
def self.start!(*args)
|
129
142
|
Instrumenter.start!(*args)
|
130
143
|
end
|
131
144
|
|
145
|
+
# Stop instrumenting
|
132
146
|
def self.stop!(*args)
|
133
147
|
Instrumenter.stop!(*args)
|
134
148
|
end
|
135
149
|
|
150
|
+
# Start a trace
|
136
151
|
def self.trace(endpoint=nil, cat=nil, title=nil)
|
137
152
|
unless inst = Instrumenter.instance
|
138
153
|
return yield if block_given?
|
@@ -146,11 +161,13 @@ module Skylight
|
|
146
161
|
end
|
147
162
|
end
|
148
163
|
|
164
|
+
# End a trace
|
149
165
|
def self.done(span)
|
150
166
|
return unless inst = Instrumenter.instance
|
151
167
|
inst.done(span)
|
152
168
|
end
|
153
169
|
|
170
|
+
# Instrument
|
154
171
|
def self.instrument(opts = DEFAULT_OPTIONS)
|
155
172
|
unless inst = Instrumenter.instance
|
156
173
|
return yield if block_given?
|
@@ -176,6 +193,7 @@ module Skylight
|
|
176
193
|
end
|
177
194
|
end
|
178
195
|
|
196
|
+
# Temporarily disable
|
179
197
|
def self.disable
|
180
198
|
unless inst = Instrumenter.instance
|
181
199
|
return yield if block_given?
|
@@ -185,6 +203,7 @@ module Skylight
|
|
185
203
|
inst.disable { yield }
|
186
204
|
end
|
187
205
|
|
206
|
+
# @api private
|
188
207
|
RUBYBIN = File.join(
|
189
208
|
RbConfig::CONFIG['bindir'],
|
190
209
|
"#{RbConfig::CONFIG['ruby_install_name']}#{RbConfig::CONFIG['EXEEXT']}")
|
@@ -194,3 +213,7 @@ module Skylight
|
|
194
213
|
|
195
214
|
require 'skylight/probes'
|
196
215
|
end
|
216
|
+
|
217
|
+
# Warn as soon as possible if there was an error installing Skylight.
|
218
|
+
# We do this here since we can't report these issues via Gem install without stopping install entirely.
|
219
|
+
Skylight.check_install_errors
|
data/lib/skylight/api.rb
CHANGED
data/lib/skylight/cli.rb
CHANGED
data/lib/skylight/compat.rb
CHANGED
@@ -34,6 +34,7 @@ end
|
|
34
34
|
|
35
35
|
if defined?(ActiveSupport::Notifications::Fanout::Subscribers::Evented)
|
36
36
|
# Handle early RCs of rails 4.0
|
37
|
+
# @api private
|
37
38
|
class ActiveSupport::Notifications::Fanout::Subscribers::Evented
|
38
39
|
unless method_defined?(:publish)
|
39
40
|
def publish(name, *args)
|
data/lib/skylight/config.rb
CHANGED
@@ -6,6 +6,7 @@ require 'socket'
|
|
6
6
|
|
7
7
|
module Skylight
|
8
8
|
class Config
|
9
|
+
# @api private
|
9
10
|
MUTEX = Mutex.new
|
10
11
|
|
11
12
|
def self.default_hostname
|
@@ -102,6 +103,7 @@ module Skylight
|
|
102
103
|
self.load(nil, nil, env)
|
103
104
|
end
|
104
105
|
|
106
|
+
# @api private
|
105
107
|
def self.remap_env(env)
|
106
108
|
ret = {}
|
107
109
|
|
@@ -125,8 +127,10 @@ module Skylight
|
|
125
127
|
ret
|
126
128
|
end
|
127
129
|
|
130
|
+
# @api private
|
128
131
|
attr_reader :environment
|
129
132
|
|
133
|
+
# @api private
|
130
134
|
def initialize(*args)
|
131
135
|
attrs = {}
|
132
136
|
|
@@ -155,10 +159,12 @@ module Skylight
|
|
155
159
|
end
|
156
160
|
end
|
157
161
|
|
162
|
+
# @api private
|
158
163
|
def skip_validation?
|
159
164
|
!!get(:skip_validation)
|
160
165
|
end
|
161
166
|
|
167
|
+
# @api private
|
162
168
|
def validate!
|
163
169
|
return true if skip_validation?
|
164
170
|
|
@@ -171,6 +177,7 @@ module Skylight
|
|
171
177
|
true
|
172
178
|
end
|
173
179
|
|
180
|
+
# @api private
|
174
181
|
def validate_token
|
175
182
|
return :ok if skip_validation?
|
176
183
|
|
@@ -255,12 +262,6 @@ module Skylight
|
|
255
262
|
ret
|
256
263
|
end
|
257
264
|
|
258
|
-
#
|
259
|
-
#
|
260
|
-
# ===== Writing =====
|
261
|
-
#
|
262
|
-
#
|
263
|
-
|
264
265
|
def write(path)
|
265
266
|
FileUtils.mkdir_p(File.dirname(path))
|
266
267
|
|
@@ -282,18 +283,22 @@ authentication: #{self[:authentication]}
|
|
282
283
|
#
|
283
284
|
#
|
284
285
|
|
286
|
+
# @api private
|
285
287
|
def worker
|
286
288
|
Worker::Builder.new(self)
|
287
289
|
end
|
288
290
|
|
291
|
+
# @api private
|
289
292
|
def gc
|
290
293
|
@gc ||= GC.new(self, get('gc.profiler', VM::GC.new))
|
291
294
|
end
|
292
295
|
|
296
|
+
# @api private
|
293
297
|
def constant_flush?
|
294
298
|
get('test.constant_flush')
|
295
299
|
end
|
296
300
|
|
301
|
+
# @api private
|
297
302
|
def ignore_token?
|
298
303
|
get('test.ignore_token')
|
299
304
|
end
|
data/lib/skylight/gc.rb
CHANGED
data/lib/skylight/helpers.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
module Skylight
|
2
|
+
# Instrumenting a specific method will cause an event to be created every time that method is called.
|
3
|
+
# The event will be inserted at the appropriate place in the Skylight trace.
|
4
|
+
#
|
5
|
+
# To instrument a method, the first thing to do is include {Skylight::Helpers Skylight::Helpers}
|
6
|
+
# into the class that you will be instrumenting. Then, annotate each method that
|
7
|
+
# you wish to instrument with {Skylight::Helpers::ClassMethods#instrument_method instrument_method}.
|
2
8
|
module Helpers
|
9
|
+
|
10
|
+
# @see Skylight::Helpers
|
3
11
|
module ClassMethods
|
12
|
+
# @api private
|
4
13
|
def method_added(name)
|
5
14
|
super
|
6
15
|
|
@@ -11,6 +20,7 @@ module Skylight
|
|
11
20
|
end
|
12
21
|
end
|
13
22
|
|
23
|
+
# @api private
|
14
24
|
def singleton_method_added(name)
|
15
25
|
super
|
16
26
|
|
@@ -21,6 +31,55 @@ module Skylight
|
|
21
31
|
end
|
22
32
|
end
|
23
33
|
|
34
|
+
# @overload instrument_method
|
35
|
+
# Instruments the following method
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# class MyClass
|
39
|
+
# include Skylight::Helpers
|
40
|
+
#
|
41
|
+
# instrument_method
|
42
|
+
# def my_method
|
43
|
+
# do_expensive_stuff
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# @overload instrument_method([name], opts={})
|
49
|
+
# @param [Symbol|String] [name]
|
50
|
+
# @param [Hash] opts
|
51
|
+
# @option opts [String] :category ('app.method')
|
52
|
+
# @option opts [String] :title (ClassName#method_name)
|
53
|
+
# @option opts [String] :description
|
54
|
+
#
|
55
|
+
# You may also declare the methods to instrument at any time by passing the name
|
56
|
+
# of the method as the first argument to `instrument_method`.
|
57
|
+
#
|
58
|
+
# @example With name
|
59
|
+
# class MyClass
|
60
|
+
# include Skylight::Helpers
|
61
|
+
#
|
62
|
+
# def my_method
|
63
|
+
# do_expensive_stuff
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# instrument_method :my_method
|
67
|
+
#
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# By default, the event will be titled using the name of the class and the
|
71
|
+
# method. For example, in our previous example, the event name will be:
|
72
|
+
# +MyClass#my_method+. You can customize this by passing using the *:title* option.
|
73
|
+
#
|
74
|
+
# @example Without name
|
75
|
+
# class MyClass
|
76
|
+
# include Skylight::Helpers
|
77
|
+
#
|
78
|
+
# instrument_method title: 'Expensive work'
|
79
|
+
# def my_method
|
80
|
+
# do_expensive_stuff
|
81
|
+
# end
|
82
|
+
# end
|
24
83
|
def instrument_method(*args)
|
25
84
|
opts = args.pop if Hash === args.last
|
26
85
|
|
@@ -66,6 +125,7 @@ module Skylight
|
|
66
125
|
end
|
67
126
|
end
|
68
127
|
|
128
|
+
# @api private
|
69
129
|
def self.included(base)
|
70
130
|
base.class_eval do
|
71
131
|
@__sk_instrument_next_method = nil
|
@@ -4,6 +4,7 @@ require 'base64'
|
|
4
4
|
require 'strscan'
|
5
5
|
|
6
6
|
module Skylight
|
7
|
+
# @api private
|
7
8
|
class Instrumenter
|
8
9
|
KEY = :__skylight_current_trace
|
9
10
|
LOCK = Mutex.new
|
@@ -27,6 +28,8 @@ module Skylight
|
|
27
28
|
@instance
|
28
29
|
end
|
29
30
|
|
31
|
+
# Do start
|
32
|
+
# @param [Config] config The config
|
30
33
|
def self.start!(config = Config.new)
|
31
34
|
return @instance if @instance
|
32
35
|
|
data/lib/skylight/messages.rb
CHANGED
@@ -0,0 +1,9 @@
|
|
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
|
data/lib/skylight/middleware.rb
CHANGED
data/lib/skylight/native.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Skylight
|
2
2
|
|
3
3
|
if native?
|
4
|
+
|
5
|
+
# @api private
|
4
6
|
class Hello
|
5
7
|
DIGITS = /^\s*\d+\s*$/
|
6
8
|
|
@@ -57,6 +59,7 @@ module Skylight
|
|
57
59
|
|
58
60
|
end
|
59
61
|
|
62
|
+
# @api private
|
60
63
|
class Error
|
61
64
|
alias serialize native_serialize
|
62
65
|
alias type native_get_group
|
@@ -68,12 +71,20 @@ module Skylight
|
|
68
71
|
end
|
69
72
|
end
|
70
73
|
|
74
|
+
# @api private
|
71
75
|
class Trace
|
72
76
|
alias serialize native_serialize
|
73
77
|
end
|
74
78
|
|
79
|
+
# @api private
|
75
80
|
class Batch
|
76
81
|
alias serialize native_serialize
|
77
82
|
end
|
78
83
|
end
|
84
|
+
|
85
|
+
# @api private
|
86
|
+
# We have to declare this again due to a YARD bug
|
87
|
+
# https://github.com/lsegal/yard/issues/761
|
88
|
+
class Hello; end
|
89
|
+
|
79
90
|
end
|
data/lib/skylight/normalizers.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'skylight/normalizers/default'
|
2
|
-
require 'skylight/util/allocation_free'
|
3
2
|
|
4
3
|
module Skylight
|
4
|
+
# @api private
|
5
5
|
# Convert AS::N events to Skylight events
|
6
6
|
module Normalizers
|
7
7
|
|
@@ -41,7 +41,7 @@ module Skylight
|
|
41
41
|
end
|
42
42
|
|
43
43
|
class RenderNormalizer < Normalizer
|
44
|
-
include AllocationFree
|
44
|
+
include Util::AllocationFree
|
45
45
|
|
46
46
|
def setup
|
47
47
|
@paths = config['normalizers.render.view_paths'] || []
|
data/lib/skylight/probes.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Skylight
|
2
|
+
# @api private
|
2
3
|
module Probes
|
3
|
-
|
4
4
|
class ProbeRegistration
|
5
5
|
attr_reader :klass_name, :require_paths, :probe
|
6
6
|
|
@@ -73,6 +73,7 @@ module Skylight
|
|
73
73
|
end
|
74
74
|
|
75
75
|
# Allow hooking require
|
76
|
+
# @api private
|
76
77
|
module ::Kernel
|
77
78
|
alias require_without_sk require
|
78
79
|
|
data/lib/skylight/railtie.rb
CHANGED
@@ -2,6 +2,7 @@ require 'skylight'
|
|
2
2
|
require 'rails'
|
3
3
|
|
4
4
|
module Skylight
|
5
|
+
# @api private
|
5
6
|
class Railtie < Rails::Railtie
|
6
7
|
config.skylight = ActiveSupport::OrderedOptions.new
|
7
8
|
|
@@ -51,7 +52,7 @@ module Skylight
|
|
51
52
|
|
52
53
|
configure_logging(config, app)
|
53
54
|
|
54
|
-
config['agent.sockfile_path']
|
55
|
+
config['agent.sockfile_path'] ||= tmp
|
55
56
|
config['normalizers.render.view_paths'] = existent_paths(app.config.paths["app/views"]) + [Rails.root.to_s]
|
56
57
|
config.validate!
|
57
58
|
config
|
data/lib/skylight/subscriber.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Skylight
|
2
|
+
# @api private
|
3
|
+
module Util
|
4
|
+
# Already defined by the native extension so we can't autoload
|
5
|
+
require 'skylight/util/clock'
|
6
|
+
|
7
|
+
autoload :AllocationFree, 'skylight/util/allocation_free'
|
8
|
+
autoload :Conversions, 'skylight/util/conversions'
|
9
|
+
autoload :Gzip, 'skylight/util/gzip'
|
10
|
+
autoload :HTTP, 'skylight/util/http'
|
11
|
+
autoload :Inflector, 'skylight/util/inflector'
|
12
|
+
autoload :Logging, 'skylight/util/logging'
|
13
|
+
autoload :Queue, 'skylight/util/queue'
|
14
|
+
autoload :Task, 'skylight/util/task'
|
15
|
+
autoload :UniformSample, 'skylight/util/uniform_sample'
|
16
|
+
autoload :NativeExtFetcher, 'skylight/util/native_ext_fetcher'
|
17
|
+
end
|
18
|
+
end
|
@@ -1,15 +1,17 @@
|
|
1
1
|
module Skylight
|
2
|
-
module
|
3
|
-
|
4
|
-
|
2
|
+
module Util
|
3
|
+
module AllocationFree
|
4
|
+
def array_find(array)
|
5
|
+
i = 0
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
while i < array.size
|
8
|
+
item = array[i]
|
9
|
+
return item if yield item
|
10
|
+
i += 1
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
+
nil
|
14
|
+
end
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
data/lib/skylight/util/http.rb
CHANGED
@@ -22,6 +22,9 @@ module Skylight
|
|
22
22
|
attr_accessor :authentication, :config
|
23
23
|
attr_reader :host, :port
|
24
24
|
|
25
|
+
class StartError < StandardError; end
|
26
|
+
class ReadResponseError < StandardError; end
|
27
|
+
|
25
28
|
def initialize(config, service = :report)
|
26
29
|
@config = config
|
27
30
|
@ssl = config["#{service}.ssl"]
|
@@ -83,6 +86,25 @@ module Skylight
|
|
83
86
|
type.new(endpoint, headers)
|
84
87
|
end
|
85
88
|
|
89
|
+
def start(http)
|
90
|
+
begin
|
91
|
+
client = http.start
|
92
|
+
rescue => e
|
93
|
+
# TODO: Retry here
|
94
|
+
raise StartError, e.inspect
|
95
|
+
end
|
96
|
+
|
97
|
+
yield client
|
98
|
+
ensure
|
99
|
+
client.finish if client
|
100
|
+
end
|
101
|
+
|
102
|
+
def read_code_and_body(res)
|
103
|
+
code, body = res.code, res.body
|
104
|
+
rescue Net::ReadTimeout, Timeout::Error, EOFError => e
|
105
|
+
raise ReadResponseError, e.inspect
|
106
|
+
end
|
107
|
+
|
86
108
|
def execute(req, body=nil)
|
87
109
|
t { fmt "executing HTTP request; host=%s; port=%s; path=%s, body=%s",
|
88
110
|
@host, @port, req.path, body && body.bytesize }
|
@@ -104,15 +126,16 @@ module Skylight
|
|
104
126
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
105
127
|
end
|
106
128
|
|
107
|
-
http
|
129
|
+
start(http) do |client|
|
108
130
|
res = client.request(req)
|
131
|
+
code, body = read_code_and_body(res)
|
109
132
|
|
110
|
-
unless
|
111
|
-
debug "server responded with #{
|
112
|
-
t { fmt "body=%s",
|
133
|
+
unless code =~ /2\d\d/
|
134
|
+
debug "server responded with #{code}"
|
135
|
+
t { fmt "body=%s", body }
|
113
136
|
end
|
114
137
|
|
115
|
-
Response.new(
|
138
|
+
Response.new(code.to_i, res, body)
|
116
139
|
end
|
117
140
|
rescue Exception => e
|
118
141
|
error "http %s %s failed; error=%s; msg=%s", req.method, req.path, e.class, e.message
|
@@ -18,45 +18,33 @@ module Skylight
|
|
18
18
|
class FetchError < StandardError; end
|
19
19
|
|
20
20
|
def self.fetch(opts = {})
|
21
|
-
platform = Gem::Platform.local
|
22
|
-
|
23
21
|
fetcher = new(
|
24
22
|
BASE_URL,
|
25
23
|
opts[:target],
|
26
24
|
opts[:version],
|
27
|
-
opts[:
|
28
|
-
opts[:
|
29
|
-
opts[:os] || platform.os,
|
25
|
+
opts[:checksum],
|
26
|
+
opts[:arch],
|
30
27
|
opts[:required],
|
31
28
|
opts[:logger] || Logger.new(STDOUT))
|
32
29
|
|
33
30
|
fetcher.fetch
|
34
31
|
end
|
35
32
|
|
36
|
-
def initialize(source, target, version,
|
33
|
+
def initialize(source, target, version, checksum, arch, required, log)
|
37
34
|
raise "source required" unless source
|
38
|
-
raise "
|
39
|
-
raise "
|
40
|
-
raise "os required" unless os
|
35
|
+
raise "checksum required" unless checksum
|
36
|
+
raise "arch required" unless arch
|
41
37
|
|
42
38
|
@source = source
|
43
39
|
@target = target
|
44
40
|
@version = version
|
45
|
-
@
|
41
|
+
@checksum = checksum
|
46
42
|
@required = required
|
47
|
-
@arch =
|
43
|
+
@arch = arch
|
48
44
|
@log = log
|
49
45
|
end
|
50
46
|
|
51
47
|
def fetch
|
52
|
-
# Ensure that the requested arch is valid
|
53
|
-
unless @checksums[@arch]
|
54
|
-
maybe_raise "no checksum entry for requested architecture -- " \
|
55
|
-
"this probably means the requested architecture is not supported; " \
|
56
|
-
"arch=#{@arch}; available=#{@checksums.keys}"
|
57
|
-
return
|
58
|
-
end
|
59
|
-
|
60
48
|
log "fetching native ext; curr-platform=#{Gem::Platform.local.to_s}; " \
|
61
49
|
"requested-arch=#{@arch}; version=#{@version}"
|
62
50
|
|
@@ -81,8 +69,15 @@ module Skylight
|
|
81
69
|
archive
|
82
70
|
end
|
83
71
|
|
84
|
-
def
|
85
|
-
|
72
|
+
def http_get(host, port, use_ssl, path)
|
73
|
+
if http_proxy = ENV['HTTP_PROXY'] || ENV['http_proxy']
|
74
|
+
log "connecting with proxy: #{http_proxy}"
|
75
|
+
uri = URI.parse(http_proxy)
|
76
|
+
p_host, p_port = uri.host, uri.port
|
77
|
+
p_user, p_pass = uri.userinfo.split(/:/) if uri.userinfo
|
78
|
+
end
|
79
|
+
|
80
|
+
Net::HTTP.start(host, port, p_host, p_port, p_user, p_pass, use_ssl: use_ssl) do |http|
|
86
81
|
case response = http.get(path)
|
87
82
|
when Net::HTTPSuccess
|
88
83
|
return [ :success, response.body ]
|
@@ -107,7 +102,7 @@ module Skylight
|
|
107
102
|
begin
|
108
103
|
host, port, use_ssl, path = deconstruct_uri(uri)
|
109
104
|
|
110
|
-
status, body =
|
105
|
+
status, body = http_get(host, port, use_ssl, path)
|
111
106
|
|
112
107
|
case status
|
113
108
|
when :success
|
@@ -130,7 +125,7 @@ module Skylight
|
|
130
125
|
rescue => e
|
131
126
|
remaining_attempts -= 1
|
132
127
|
|
133
|
-
|
128
|
+
error "failed to fetch native extension; uri=#{uri}; msg=#{e.message}; remaining-attempts=#{remaining_attempts}", e
|
134
129
|
|
135
130
|
if remaining_attempts > 0
|
136
131
|
sleep 2
|
@@ -146,11 +141,7 @@ module Skylight
|
|
146
141
|
end
|
147
142
|
|
148
143
|
def verify_checksum(archive)
|
149
|
-
|
150
|
-
log "no checksum provided; arch=#{@arch}"
|
151
|
-
return false
|
152
|
-
end
|
153
|
-
|
144
|
+
expected = @checksum
|
154
145
|
actual = Digest::SHA2.hexdigest(archive)
|
155
146
|
|
156
147
|
unless expected == actual
|
@@ -178,18 +169,23 @@ module Skylight
|
|
178
169
|
end
|
179
170
|
|
180
171
|
def maybe_raise(err)
|
181
|
-
|
172
|
+
error err
|
182
173
|
|
183
174
|
if @required
|
184
175
|
raise err
|
185
176
|
end
|
186
177
|
end
|
187
178
|
|
188
|
-
def log(msg
|
179
|
+
def log(msg)
|
189
180
|
msg = "[SKYLIGHT] #{msg}"
|
190
|
-
msg << "\n#{e.backtrace.join("\n")}" if e
|
191
181
|
@log.info msg
|
192
182
|
end
|
183
|
+
|
184
|
+
def error(msg, e=nil)
|
185
|
+
msg = "[SKYLIGHT] #{msg}"
|
186
|
+
msg << "\n#{e.backtrace.join("\n")}" if e
|
187
|
+
@log.error msg
|
188
|
+
end
|
193
189
|
end
|
194
190
|
end
|
195
191
|
end
|
data/lib/skylight/version.rb
CHANGED
data/lib/skylight/vm/gc.rb
CHANGED
data/lib/skylight/worker.rb
CHANGED
@@ -52,7 +52,7 @@ module Skylight
|
|
52
52
|
report = {
|
53
53
|
"hostname" => config[:'hostname'],
|
54
54
|
"host.info" => RbConfig::CONFIG['arch'],
|
55
|
-
"ruby.version" => RUBY_VERSION,
|
55
|
+
"ruby.version" => "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}",
|
56
56
|
"ruby.engine" => RUBY_ENGINE,
|
57
57
|
"skylight.version" => Skylight::VERSION
|
58
58
|
}
|
@@ -204,7 +204,8 @@ module Skylight
|
|
204
204
|
sanity_check
|
205
205
|
end
|
206
206
|
|
207
|
-
|
207
|
+
memory_usage = @process_mem_gauge.call
|
208
|
+
if memory_usage > max_memory
|
208
209
|
raise WorkerStateError, "Memory limit exceeded: #{memory_usage} (max: #{max_memory})"
|
209
210
|
end
|
210
211
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skylight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tilde, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -47,6 +47,7 @@ files:
|
|
47
47
|
- lib/skylight/compat.rb
|
48
48
|
- lib/skylight/config.rb
|
49
49
|
- lib/skylight/data/cacert.pem
|
50
|
+
- lib/skylight/formatters.rb
|
50
51
|
- lib/skylight/formatters/http.rb
|
51
52
|
- lib/skylight/gc.rb
|
52
53
|
- lib/skylight/helpers.rb
|
@@ -56,6 +57,7 @@ files:
|
|
56
57
|
- lib/skylight/messages/hello.rb
|
57
58
|
- lib/skylight/messages/trace.rb
|
58
59
|
- lib/skylight/messages/trace_envelope.rb
|
60
|
+
- lib/skylight/metrics.rb
|
59
61
|
- lib/skylight/metrics/ewma.rb
|
60
62
|
- lib/skylight/metrics/meter.rb
|
61
63
|
- lib/skylight/metrics/process_cpu_gauge.rb
|
@@ -77,6 +79,7 @@ files:
|
|
77
79
|
- lib/skylight/probes/net_http.rb
|
78
80
|
- lib/skylight/railtie.rb
|
79
81
|
- lib/skylight/subscriber.rb
|
82
|
+
- lib/skylight/util.rb
|
80
83
|
- lib/skylight/util/allocation_free.rb
|
81
84
|
- lib/skylight/util/clock.rb
|
82
85
|
- lib/skylight/util/conversions.rb
|
@@ -167,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
170
|
version: '0'
|
168
171
|
requirements: []
|
169
172
|
rubyforge_project:
|
170
|
-
rubygems_version: 2.2.
|
173
|
+
rubygems_version: 2.2.2
|
171
174
|
signing_key:
|
172
175
|
specification_version: 4
|
173
176
|
summary: Skylight is a ruby application monitoring tool. Currently in closed beta.
|