skylight 0.0.10 → 0.0.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.
- data/lib/skylight/cli.rb +10 -2
- data/lib/skylight/config.rb +10 -1
- data/lib/skylight/instrumenter.rb +40 -18
- data/lib/skylight/middleware.rb +8 -30
- data/lib/skylight/normalize/send_file.rb +43 -36
- data/lib/skylight/railtie.rb +32 -23
- data/lib/skylight/subscriber.rb +0 -2
- data/lib/skylight/trace.rb +8 -1
- data/lib/skylight/version.rb +1 -1
- metadata +16 -10
- checksums.yaml +0 -7
data/lib/skylight/cli.rb
CHANGED
@@ -4,6 +4,7 @@ $:.unshift File.expand_path('../vendor', __FILE__)
|
|
4
4
|
require "skylight"
|
5
5
|
require "thor"
|
6
6
|
require "highline"
|
7
|
+
require "active_support/inflector"
|
7
8
|
|
8
9
|
module Skylight
|
9
10
|
class CLI < Thor
|
@@ -77,8 +78,15 @@ module Skylight
|
|
77
78
|
end
|
78
79
|
|
79
80
|
def app_name
|
80
|
-
|
81
|
-
|
81
|
+
@app_name ||=
|
82
|
+
begin
|
83
|
+
if File.exist?("config/application.rb")
|
84
|
+
require "./config/application"
|
85
|
+
Rails.application.class.name.split("::").first.underscore.humanize
|
86
|
+
else
|
87
|
+
File.basename(File.expand_path('.')).humanize
|
88
|
+
end
|
89
|
+
end
|
82
90
|
end
|
83
91
|
end
|
84
92
|
end
|
data/lib/skylight/config.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'logger'
|
3
|
+
require 'fileutils'
|
3
4
|
|
4
5
|
module Skylight
|
5
6
|
class Config
|
@@ -22,6 +23,7 @@ module Skylight
|
|
22
23
|
end
|
23
24
|
|
24
25
|
private
|
26
|
+
|
25
27
|
def apply_env(config, env)
|
26
28
|
env.each do |key, value|
|
27
29
|
name = normalize_env(key)
|
@@ -46,7 +48,7 @@ module Skylight
|
|
46
48
|
@port = 443
|
47
49
|
@interval = 5
|
48
50
|
@protocol = JsonProto.new(self)
|
49
|
-
@max_pending_traces
|
51
|
+
@max_pending_traces = 500
|
50
52
|
@samples_per_interval = 100
|
51
53
|
|
52
54
|
@logger = Logger.new(STDOUT)
|
@@ -60,6 +62,9 @@ module Skylight
|
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
65
|
+
@http ||= Util::HTTP.new(self)
|
66
|
+
@gc_profiler ||= GC::Profiler
|
67
|
+
|
63
68
|
yield self if block_given?
|
64
69
|
end
|
65
70
|
|
@@ -88,6 +93,7 @@ module Skylight
|
|
88
93
|
attr_reader :normalizer
|
89
94
|
|
90
95
|
attr_reader :protocol
|
96
|
+
|
91
97
|
def protocol=(val)
|
92
98
|
if val.is_a?(String) || val.is_a?(Symbol)
|
93
99
|
class_name = val.to_s.capitalize+"Proto"
|
@@ -114,10 +120,13 @@ module Skylight
|
|
114
120
|
attr_writer :gc_profiler
|
115
121
|
|
116
122
|
def gc_profiler
|
123
|
+
# TODO: Move this into tests
|
117
124
|
@gc_profiler ||= Struct.new(:enable, :disable, :clear, :total_time).new(nil, nil, nil, 0)
|
118
125
|
end
|
119
126
|
|
120
127
|
def save(filename=yaml_file)
|
128
|
+
FileUtils.mkdir_p File.dirname(filename)
|
129
|
+
|
121
130
|
File.open(filename, "w") do |file|
|
122
131
|
config = {}
|
123
132
|
config["authentication_token"] = authentication_token if authentication_token
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module Skylight
|
2
2
|
class Instrumenter
|
3
3
|
|
4
|
+
# Guards starting the instrumenter
|
5
|
+
LOCK = Mutex.new
|
6
|
+
|
4
7
|
# Maximum number of traces to sample for each interval
|
5
8
|
SAMPLE_SIZE = 100
|
6
9
|
|
@@ -8,44 +11,63 @@ module Skylight
|
|
8
11
|
INTERVAL = 5
|
9
12
|
|
10
13
|
def self.start!(config = Config.new)
|
11
|
-
# Convert a hash to a config object
|
12
|
-
if Hash === config
|
13
|
-
config = Config.new config
|
14
|
-
end
|
15
|
-
|
16
14
|
new(config).start!
|
17
15
|
end
|
18
16
|
|
19
17
|
attr_reader :config, :worker, :samples
|
20
18
|
|
21
19
|
def initialize(config)
|
22
|
-
|
20
|
+
# Convert a hash to a config object
|
21
|
+
if Hash === config
|
22
|
+
config = Config.new(config)
|
23
|
+
end
|
23
24
|
|
24
|
-
@
|
25
|
+
@config = config
|
26
|
+
@started = false
|
27
|
+
@worker = Worker.new(self)
|
25
28
|
end
|
26
29
|
|
27
30
|
def start!
|
28
|
-
|
29
|
-
|
31
|
+
# Quick check
|
32
|
+
return self if @started
|
33
|
+
|
34
|
+
LOCK.synchronize do
|
35
|
+
# Ensure that the instrumenter has not been started now that the lock
|
36
|
+
# as been acquired
|
37
|
+
return self if @started
|
38
|
+
|
39
|
+
@worker.start!
|
40
|
+
Subscriber.register!(config)
|
30
41
|
|
31
|
-
|
32
|
-
|
42
|
+
# Ensure properly configured
|
43
|
+
return unless config
|
33
44
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
45
|
+
# Ensure that there is an API token
|
46
|
+
unless config.authentication_token
|
47
|
+
if logger = config.logger
|
48
|
+
logger.warn "[SKYLIGHT] No authentication token provided; cannot start agent."
|
49
|
+
end
|
50
|
+
|
51
|
+
return
|
38
52
|
end
|
39
53
|
|
40
|
-
|
41
|
-
end
|
54
|
+
config.gc_profiler.enable
|
42
55
|
|
43
|
-
|
56
|
+
@started = true
|
57
|
+
end
|
44
58
|
|
45
59
|
self
|
60
|
+
|
61
|
+
rescue
|
62
|
+
nil
|
46
63
|
end
|
47
64
|
|
48
65
|
def trace(endpoint = nil)
|
66
|
+
# Ignore everything unless the instrumenter has been started
|
67
|
+
unless @started
|
68
|
+
return yield
|
69
|
+
end
|
70
|
+
|
49
71
|
# If there already is a trace going on, then just continue
|
50
72
|
if Thread.current[Trace::KEY]
|
51
73
|
return yield
|
data/lib/skylight/middleware.rb
CHANGED
@@ -1,46 +1,24 @@
|
|
1
1
|
module Skylight
|
2
2
|
class Middleware
|
3
|
-
|
4
|
-
|
3
|
+
|
4
|
+
def self.new(app, instrumenter, *)
|
5
|
+
return app unless instrumenter
|
5
6
|
super
|
6
7
|
end
|
7
8
|
|
8
|
-
def initialize(app,
|
9
|
+
def initialize(app, instrumenter)
|
9
10
|
@app = app
|
10
|
-
@
|
11
|
-
@config.gc_profiler = GC::Profiler
|
12
|
-
@instrumenter_class = instrumenter_class
|
11
|
+
@instrumenter = instrumenter
|
13
12
|
end
|
14
13
|
|
15
14
|
def call(env)
|
16
|
-
instrumenter.
|
15
|
+
@instrumenter.start!
|
16
|
+
|
17
|
+
@instrumenter.trace("Rack") do
|
17
18
|
ActiveSupport::Notifications.instrument("app.rack.request") do
|
18
19
|
@app.call(env)
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
22
|
-
|
23
|
-
private
|
24
|
-
LOCK = Mutex.new
|
25
|
-
|
26
|
-
def instrumenter
|
27
|
-
return @instrumenter if defined?(@instrumenter)
|
28
|
-
|
29
|
-
LOCK.synchronize do
|
30
|
-
return @instrumeter if defined?(@instrumenter)
|
31
|
-
@instrumenter = @instrumenter_class.start!(@config)
|
32
|
-
return @instrumenter
|
33
|
-
end
|
34
|
-
rescue Exception
|
35
|
-
@instrumenter = stub
|
36
|
-
end
|
37
|
-
|
38
|
-
def stub
|
39
|
-
Class.new do
|
40
|
-
def trace(*)
|
41
|
-
yield
|
42
|
-
end
|
43
|
-
end.new
|
44
|
-
end
|
45
23
|
end
|
46
24
|
end
|
@@ -1,44 +1,51 @@
|
|
1
|
-
require "action_dispatch/http/mime_type"
|
2
|
-
require "action_dispatch/http/mime_types"
|
3
|
-
require "rack/utils"
|
4
|
-
|
5
1
|
module Skylight
|
6
2
|
module Normalize
|
7
|
-
class SendFile < Normalizer
|
8
|
-
register "send_file.action_controller"
|
9
|
-
|
10
|
-
def normalize
|
11
|
-
path = @payload[:path]
|
12
|
-
|
13
|
-
annotations = {
|
14
|
-
path: path,
|
15
|
-
filename: @payload[:filename],
|
16
|
-
type: normalize_type,
|
17
|
-
disposition: normalize_disposition,
|
18
|
-
status: normalize_status
|
19
|
-
}
|
20
|
-
|
21
|
-
# These will eventually be different
|
22
|
-
title = desc = "send file: #{path}"
|
23
|
-
|
24
|
-
[ "app.controller.send_file", title, desc, annotations ]
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
def normalize_type
|
29
|
-
type = @payload[:type] || "application/octet-stream"
|
30
|
-
type = Mime[type].to_s if type.is_a?(Symbol)
|
31
|
-
type
|
32
|
-
end
|
33
3
|
|
34
|
-
|
35
|
-
|
36
|
-
|
4
|
+
# Temporary hacks
|
5
|
+
begin
|
6
|
+
require "action_dispatch/http/mime_type"
|
7
|
+
require "action_dispatch/http/mime_types"
|
8
|
+
require "rack/utils"
|
9
|
+
|
10
|
+
class SendFile < Normalizer
|
11
|
+
register "send_file.action_controller"
|
12
|
+
|
13
|
+
def normalize
|
14
|
+
path = @payload[:path]
|
15
|
+
|
16
|
+
annotations = {
|
17
|
+
path: path,
|
18
|
+
filename: @payload[:filename],
|
19
|
+
type: normalize_type,
|
20
|
+
disposition: normalize_disposition,
|
21
|
+
status: normalize_status
|
22
|
+
}
|
23
|
+
|
24
|
+
# These will eventually be different
|
25
|
+
title = desc = "send file: #{path}"
|
26
|
+
|
27
|
+
[ "app.controller.send_file", title, desc, annotations ]
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def normalize_type
|
32
|
+
type = @payload[:type] || "application/octet-stream"
|
33
|
+
type = Mime[type].to_s if type.is_a?(Symbol)
|
34
|
+
type
|
35
|
+
end
|
36
|
+
|
37
|
+
def normalize_status
|
38
|
+
status = @payload[:status] || 200
|
39
|
+
Rack::Utils.status_code(status)
|
40
|
+
end
|
41
|
+
|
42
|
+
def normalize_disposition
|
43
|
+
@payload[:disposition] || "attachment"
|
44
|
+
end
|
37
45
|
end
|
38
46
|
|
39
|
-
|
40
|
-
@payload[:disposition] || "attachment"
|
41
|
-
end
|
47
|
+
rescue LoadError
|
42
48
|
end
|
49
|
+
|
43
50
|
end
|
44
51
|
end
|
data/lib/skylight/railtie.rb
CHANGED
@@ -13,52 +13,61 @@ module Skylight
|
|
13
13
|
|
14
14
|
attr_accessor :instrumenter
|
15
15
|
|
16
|
-
initializer "skylight.
|
17
|
-
|
18
|
-
@problems = checker.smoke_test(config_path(app)) || checker.sanity_check(load_config(app))
|
19
|
-
next unless @problems
|
16
|
+
initializer "skylight.configure" do |app|
|
17
|
+
config = load_config(app)
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
puts "[SKYLIGHT] PROBLEM: #{group} #{problem}"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
19
|
+
if good_to_go?(app, config)
|
20
|
+
@instrumenter = Instrumenter.new(config)
|
27
21
|
|
28
|
-
initializer "skylight.configure" do |app|
|
29
|
-
if @problems
|
30
|
-
puts "[SKYLIGHT] Skipping Skylight boot"
|
31
|
-
else
|
32
22
|
Rails.logger.debug "[SKYLIGHT] Installing middleware"
|
33
|
-
app.middleware.insert 0, Middleware,
|
23
|
+
app.middleware.insert 0, Middleware, @instrumenter
|
24
|
+
else
|
25
|
+
puts "[SKYLIGHT] Skipping Skylight boot"
|
34
26
|
end
|
35
27
|
end
|
36
28
|
|
37
29
|
private
|
38
30
|
|
39
|
-
def
|
40
|
-
|
31
|
+
def good_to_go?(app, config)
|
32
|
+
unless problems = check_for_problems(app, config)
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
|
36
|
+
problems.each do |group, problem_list|
|
37
|
+
problem_list.each do |problem|
|
38
|
+
puts "[SKYLIGHT] PROBLEM: #{group} #{problem}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
false
|
41
43
|
end
|
42
44
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
45
|
+
def check_for_problems(app, config)
|
46
|
+
checker = SanityChecker.new
|
47
|
+
checker.smoke_test(config_path(app)) || checker.sanity_check(config)
|
46
48
|
end
|
47
49
|
|
48
50
|
def load_config(app)
|
49
|
-
@skylight_config ||= begin
|
50
51
|
config = Config.load_from_yaml(config_path(app), ENV).tap do |c|
|
51
52
|
c.logger = Rails.logger
|
52
53
|
end
|
53
54
|
|
54
55
|
config.normalizer.view_paths = app.config.paths["app/views"].existent
|
55
|
-
config.http = Util::HTTP.new(config)
|
56
56
|
config
|
57
|
-
end
|
58
57
|
rescue => e
|
59
58
|
raise
|
60
59
|
Rails.logger.error "[SKYLIGHT] #{e.message} (#{e.class}) - #{e.backtrace.first}"
|
61
60
|
end
|
62
61
|
|
62
|
+
def environments
|
63
|
+
Array(config.skylight.environments).map { |e| e && e.to_s }.compact
|
64
|
+
end
|
65
|
+
|
66
|
+
def config_path(app)
|
67
|
+
path = config.skylight.config_path
|
68
|
+
File.expand_path(path, app.root)
|
69
|
+
end
|
70
|
+
|
71
|
+
|
63
72
|
end
|
64
73
|
end
|
data/lib/skylight/subscriber.rb
CHANGED
data/lib/skylight/trace.rb
CHANGED
@@ -94,7 +94,14 @@ module Skylight
|
|
94
94
|
|
95
95
|
update_cumulative_gc
|
96
96
|
|
97
|
-
|
97
|
+
ended_at = now - @timestamp
|
98
|
+
|
99
|
+
# If it's not the root node
|
100
|
+
if span.parent
|
101
|
+
ended_at -= @cumulative_gc
|
102
|
+
end
|
103
|
+
|
104
|
+
span.ended_at = ended_at
|
98
105
|
|
99
106
|
# Update the parent
|
100
107
|
@parent = @spans[@parent].parent
|
data/lib/skylight/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skylight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Tilde, Inc.
|
@@ -13,29 +14,33 @@ dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: activesupport
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- - '>='
|
19
|
+
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: 3.0.0
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- - '>='
|
27
|
+
- - ! '>='
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: 3.0.0
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: actionpack
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
|
-
- - '>='
|
35
|
+
- - ! '>='
|
32
36
|
- !ruby/object:Gem::Version
|
33
37
|
version: 3.0.0
|
34
38
|
type: :development
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
|
-
- - '>='
|
43
|
+
- - ! '>='
|
39
44
|
- !ruby/object:Gem::Version
|
40
45
|
version: 3.0.0
|
41
46
|
description: Currently in pre-alpha.
|
@@ -124,25 +129,26 @@ files:
|
|
124
129
|
- bin/skylight
|
125
130
|
homepage: http://www.skylight.io
|
126
131
|
licenses: []
|
127
|
-
metadata: {}
|
128
132
|
post_install_message:
|
129
133
|
rdoc_options: []
|
130
134
|
require_paths:
|
131
135
|
- lib
|
132
136
|
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
133
138
|
requirements:
|
134
|
-
- - '>='
|
139
|
+
- - ! '>='
|
135
140
|
- !ruby/object:Gem::Version
|
136
141
|
version: 1.9.2
|
137
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
none: false
|
138
144
|
requirements:
|
139
|
-
- - '>='
|
145
|
+
- - ! '>='
|
140
146
|
- !ruby/object:Gem::Version
|
141
147
|
version: '0'
|
142
148
|
requirements: []
|
143
149
|
rubyforge_project:
|
144
|
-
rubygems_version:
|
150
|
+
rubygems_version: 1.8.25
|
145
151
|
signing_key:
|
146
|
-
specification_version:
|
152
|
+
specification_version: 3
|
147
153
|
summary: Skylight is a ruby application monitoring tool.
|
148
154
|
test_files: []
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: addb4eed3d6a9b0f22eb5163115018211c5da90c
|
4
|
-
data.tar.gz: 513eb7a8391b46447744f602127b2e0e4fe84edc
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: cd3900fdbb47bc3adf7a81dda75a69277b72484d056a1f86c66b83b36335d0a2e01568830c0bb412bdcd76c82eb7ceec11fc2a5b8f73c1c129d725ab342e27b4
|
7
|
-
data.tar.gz: e94a2b3bf08c8151b1a23e666402a4530eaa3310087de8f6b43f109f57792c7556e17314711babfeff7cfaca3a3f8d1df41f18b36587bf356c5c12d2533f668a
|