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