skylight 0.0.7 → 0.0.10

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 (61) hide show
  1. checksums.yaml +7 -0
  2. data/bin/skylight +5 -0
  3. data/lib/skylight.rb +2 -0
  4. data/lib/skylight/cli.rb +84 -0
  5. data/lib/skylight/config.rb +53 -6
  6. data/lib/skylight/instrumenter.rb +4 -1
  7. data/lib/skylight/json_proto.rb +0 -3
  8. data/lib/skylight/middleware.rb +1 -0
  9. data/lib/skylight/normalize.rb +30 -5
  10. data/lib/skylight/normalize/process_action.rb +1 -1
  11. data/lib/skylight/normalize/render_collection.rb +2 -6
  12. data/lib/skylight/normalize/render_partial.rb +2 -5
  13. data/lib/skylight/normalize/render_template.rb +2 -5
  14. data/lib/skylight/normalize/sql.rb +2 -4
  15. data/lib/skylight/railtie.rb +30 -33
  16. data/lib/skylight/sanity_checker.rb +73 -0
  17. data/lib/skylight/subscriber.rb +1 -15
  18. data/lib/skylight/trace.rb +30 -5
  19. data/lib/skylight/util/http.rb +97 -0
  20. data/lib/skylight/vendor/highline.rb +1012 -0
  21. data/lib/skylight/vendor/highline/color_scheme.rb +134 -0
  22. data/lib/skylight/vendor/highline/compatibility.rb +16 -0
  23. data/lib/skylight/vendor/highline/import.rb +41 -0
  24. data/lib/skylight/vendor/highline/menu.rb +398 -0
  25. data/lib/skylight/vendor/highline/question.rb +475 -0
  26. data/lib/skylight/vendor/highline/simulate.rb +48 -0
  27. data/lib/skylight/vendor/highline/string_extensions.rb +131 -0
  28. data/lib/skylight/vendor/highline/style.rb +181 -0
  29. data/lib/skylight/vendor/highline/system_extensions.rb +218 -0
  30. data/lib/skylight/vendor/thor.rb +473 -0
  31. data/lib/skylight/vendor/thor/actions.rb +318 -0
  32. data/lib/skylight/vendor/thor/actions/create_file.rb +105 -0
  33. data/lib/skylight/vendor/thor/actions/create_link.rb +60 -0
  34. data/lib/skylight/vendor/thor/actions/directory.rb +119 -0
  35. data/lib/skylight/vendor/thor/actions/empty_directory.rb +137 -0
  36. data/lib/skylight/vendor/thor/actions/file_manipulation.rb +314 -0
  37. data/lib/skylight/vendor/thor/actions/inject_into_file.rb +109 -0
  38. data/lib/skylight/vendor/thor/base.rb +652 -0
  39. data/lib/skylight/vendor/thor/command.rb +136 -0
  40. data/lib/skylight/vendor/thor/core_ext/hash_with_indifferent_access.rb +80 -0
  41. data/lib/skylight/vendor/thor/core_ext/io_binary_read.rb +12 -0
  42. data/lib/skylight/vendor/thor/core_ext/ordered_hash.rb +100 -0
  43. data/lib/skylight/vendor/thor/error.rb +28 -0
  44. data/lib/skylight/vendor/thor/group.rb +282 -0
  45. data/lib/skylight/vendor/thor/invocation.rb +172 -0
  46. data/lib/skylight/vendor/thor/parser.rb +4 -0
  47. data/lib/skylight/vendor/thor/parser/argument.rb +74 -0
  48. data/lib/skylight/vendor/thor/parser/arguments.rb +171 -0
  49. data/lib/skylight/vendor/thor/parser/option.rb +121 -0
  50. data/lib/skylight/vendor/thor/parser/options.rb +218 -0
  51. data/lib/skylight/vendor/thor/rake_compat.rb +72 -0
  52. data/lib/skylight/vendor/thor/runner.rb +322 -0
  53. data/lib/skylight/vendor/thor/shell.rb +88 -0
  54. data/lib/skylight/vendor/thor/shell/basic.rb +393 -0
  55. data/lib/skylight/vendor/thor/shell/color.rb +148 -0
  56. data/lib/skylight/vendor/thor/shell/html.rb +127 -0
  57. data/lib/skylight/vendor/thor/util.rb +270 -0
  58. data/lib/skylight/vendor/thor/version.rb +3 -0
  59. data/lib/skylight/version.rb +1 -1
  60. data/lib/skylight/worker.rb +3 -58
  61. metadata +56 -18
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: addb4eed3d6a9b0f22eb5163115018211c5da90c
4
+ data.tar.gz: 513eb7a8391b46447744f602127b2e0e4fe84edc
5
+ SHA512:
6
+ metadata.gz: cd3900fdbb47bc3adf7a81dda75a69277b72484d056a1f86c66b83b36335d0a2e01568830c0bb412bdcd76c82eb7ceec11fc2a5b8f73c1c129d725ab342e27b4
7
+ data.tar.gz: e94a2b3bf08c8151b1a23e666402a4530eaa3310087de8f6b43f109f57792c7556e17314711babfeff7cfaca3a3f8d1df41f18b36587bf356c5c12d2533f668a
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "skylight/cli"
4
+
5
+ Skylight::CLI.start(ARGV)
@@ -19,11 +19,13 @@ module Skylight
19
19
  require 'skylight/util/clock'
20
20
  require 'skylight/util/ewma'
21
21
  require 'skylight/util/gzip'
22
+ require 'skylight/util/http'
22
23
  require 'skylight/util/queue'
23
24
  require 'skylight/util/uniform_sample'
24
25
  require 'skylight/util/uuid'
25
26
 
26
27
  # Then require the rest
28
+ require 'skylight/sanity_checker'
27
29
  require 'skylight/compat'
28
30
  require 'skylight/config'
29
31
  require 'skylight/instrumenter'
@@ -0,0 +1,84 @@
1
+ # Use vendored thor / highline
2
+ $:.unshift File.expand_path('../vendor', __FILE__)
3
+
4
+ require "skylight"
5
+ require "thor"
6
+ require "highline"
7
+
8
+ module Skylight
9
+ class CLI < Thor
10
+ desc "create", "Create a new app"
11
+ def create
12
+ if !SanityChecker.new.smoke_test(File.expand_path("config/skylight.yml"))
13
+ say "Your app is already on Skylight. http://www.skylight.io", :green
14
+ return
15
+ end
16
+
17
+ token = load_credentials
18
+ config = http_config
19
+
20
+ response = Util::HTTP.new(config).create_app(token, app_name)["app"]
21
+
22
+ config.app_id = response["id"]
23
+ config.authentication_token = response["token"]
24
+
25
+ config.yaml_file = File.expand_path("config/skylight.yml")
26
+
27
+ config.save
28
+
29
+ say "Congratulations. Your application is on Skylight! http://www.skylight.io", :green
30
+ end
31
+
32
+ private
33
+ def user_settings
34
+ File.expand_path("~/.skylight")
35
+ end
36
+
37
+ def http_config
38
+ @http_config ||= Config.new do |c|
39
+ c.host = "www.skylight.io"
40
+ c.port = 443
41
+ c.ssl = true
42
+ c.deflate = false
43
+ end
44
+ end
45
+
46
+ def load_credentials
47
+ if credentials?
48
+ return YAML.load_file(user_settings)["token"]
49
+ end
50
+
51
+ token = nil
52
+
53
+ loop do
54
+ h = HighLine.new
55
+ username = h.ask("Username: ")
56
+ password = h.ask("Password: ") { |q| q.echo = "*" }
57
+
58
+ response = Util::HTTP.new(http_config).auth(username, password)
59
+ if response["authenticated"] == false
60
+ say "Sorry. That username and password was invalid. Please try again", :red
61
+ puts
62
+ else
63
+ token = response["token"]
64
+ break
65
+ end
66
+ end
67
+
68
+ File.open(user_settings, "w") do |file|
69
+ file.puts YAML.dump("token" => token)
70
+ end
71
+
72
+ token
73
+ end
74
+
75
+ def credentials?
76
+ !SanityChecker.new.user_credentials(user_settings)
77
+ end
78
+
79
+ def app_name
80
+ require "./config/application"
81
+ Rails.application.class.name.split("::").first.underscore
82
+ end
83
+ end
84
+ end
@@ -1,17 +1,42 @@
1
1
  require 'yaml'
2
+ require 'logger'
2
3
 
3
4
  module Skylight
4
5
  class Config
6
+ class Normalizer < Struct.new(:view_paths)
7
+ end
8
+
9
+ class << self
10
+ def load_from_yaml(path, env=ENV)
11
+ new do |config|
12
+ data = YAML.load_file(path)
5
13
 
6
- def self.load_from_yaml(path)
7
- new do |config|
8
- data = YAML.load_file(path)
9
- data.each do |key, value|
10
- if config.respond_to?("#{key}=")
11
- config.send("#{key}=", value)
14
+ data.each do |key, value|
15
+ apply_config(config, key, value)
12
16
  end
17
+
18
+ config.yaml_file = path
19
+
20
+ apply_env(config, env)
21
+ end
22
+ end
23
+
24
+ private
25
+ def apply_env(config, env)
26
+ env.each do |key, value|
27
+ name = normalize_env(key)
28
+ apply_config(config, name, value) if name
13
29
  end
14
30
  end
31
+
32
+ def normalize_env(key)
33
+ match = key.match(/^SKYLIGHT_(\w+)$/)
34
+ match && match[1].downcase
35
+ end
36
+
37
+ def apply_config(config, key, value)
38
+ config.send("#{key}=", value) if config.respond_to?("#{key}=")
39
+ end
15
40
  end
16
41
 
17
42
  def initialize(attrs = {})
@@ -27,6 +52,8 @@ module Skylight
27
52
  @logger = Logger.new(STDOUT)
28
53
  @logger.level = Logger::INFO
29
54
 
55
+ @normalizer = Normalizer.new
56
+
30
57
  attrs.each do |k, v|
31
58
  if respond_to?("#{k}=")
32
59
  send("#{k}=", v)
@@ -36,7 +63,9 @@ module Skylight
36
63
  yield self if block_given?
37
64
  end
38
65
 
66
+ attr_accessor :yaml_file
39
67
  attr_accessor :authentication_token
68
+ attr_accessor :app_id
40
69
 
41
70
  attr_accessor :ssl
42
71
  alias_method :ssl?, :ssl
@@ -48,12 +77,16 @@ module Skylight
48
77
 
49
78
  attr_accessor :port
50
79
 
80
+ attr_accessor :http
81
+
51
82
  attr_accessor :samples_per_interval
52
83
 
53
84
  attr_accessor :interval
54
85
 
55
86
  attr_accessor :max_pending_traces
56
87
 
88
+ attr_reader :normalizer
89
+
57
90
  attr_reader :protocol
58
91
  def protocol=(val)
59
92
  if val.is_a?(String) || val.is_a?(Symbol)
@@ -78,5 +111,19 @@ module Skylight
78
111
  end
79
112
  end
80
113
 
114
+ attr_writer :gc_profiler
115
+
116
+ def gc_profiler
117
+ @gc_profiler ||= Struct.new(:enable, :disable, :clear, :total_time).new(nil, nil, nil, 0)
118
+ end
119
+
120
+ def save(filename=yaml_file)
121
+ File.open(filename, "w") do |file|
122
+ config = {}
123
+ config["authentication_token"] = authentication_token if authentication_token
124
+ config["app_id"] = app_id if app_id
125
+ file.puts YAML.dump(config)
126
+ end
127
+ end
81
128
  end
82
129
  end
@@ -20,6 +20,7 @@ module Skylight
20
20
 
21
21
  def initialize(config)
22
22
  @config = config
23
+
23
24
  @worker = Worker.new(self)
24
25
  end
25
26
 
@@ -39,6 +40,8 @@ module Skylight
39
40
  return
40
41
  end
41
42
 
43
+ config.gc_profiler.enable
44
+
42
45
  self
43
46
  end
44
47
 
@@ -72,7 +75,7 @@ module Skylight
72
75
  private
73
76
 
74
77
  def create_trace(endpoint)
75
- Trace.new(endpoint)
78
+ Trace.new(config, endpoint)
76
79
  # Paranoia
77
80
  rescue => e
78
81
  error e
@@ -82,9 +82,6 @@ module Skylight
82
82
  ehash
83
83
  end
84
84
 
85
- require "pp"
86
- @config.logger.debug PP.pp(hash, "")
87
-
88
85
  out << hash.to_json
89
86
  end
90
87
  end
@@ -8,6 +8,7 @@ module Skylight
8
8
  def initialize(app, config, instrumenter_class=Instrumenter)
9
9
  @app = app
10
10
  @config = config
11
+ @config.gc_profiler = GC::Profiler
11
12
  @instrumenter_class = instrumenter_class
12
13
  end
13
14
 
@@ -2,13 +2,13 @@ module Skylight
2
2
  module Normalize
3
3
  @registry = {}
4
4
 
5
- def self.normalize(trace, name, payload)
5
+ def self.normalize(trace, name, payload, config={})
6
6
  klass = @registry[name]
7
7
 
8
8
  if klass
9
- klass.new(trace, name, payload).normalize
9
+ klass.new(trace, name, payload, config).normalize
10
10
  else
11
- Default.new(trace, name, payload).normalize
11
+ Default.new(trace, name, payload, config).normalize
12
12
  end
13
13
  end
14
14
 
@@ -22,8 +22,33 @@ module Skylight
22
22
  Normalize.register(name, self)
23
23
  end
24
24
 
25
- def initialize(trace, name, payload)
26
- @trace, @name, @payload = trace, name, payload
25
+ def initialize(trace, name, payload, config={})
26
+ @trace, @name, @payload, @config = trace, name, payload, config
27
+ end
28
+ end
29
+
30
+ class RenderNormalizer < Normalizer
31
+ private
32
+ def normalize_render(category, payload)
33
+ path = @payload[:identifier]
34
+
35
+ title = relative_path(path)
36
+ path = nil if path == title
37
+ [ category, title, path, payload ]
38
+ end
39
+
40
+ def relative_path(path)
41
+ root_path = @config.view_paths.find do |p|
42
+ path.start_with?(p)
43
+ end
44
+
45
+ if root_path
46
+ relative = path[root_path.size..-1]
47
+ relative = relative[1..-1] if relative.start_with?("/")
48
+ relative
49
+ else
50
+ path
51
+ end
27
52
  end
28
53
  end
29
54
  end
@@ -5,7 +5,7 @@ module Skylight
5
5
 
6
6
  def normalize
7
7
  @trace.endpoint = controller_action
8
- [ "app.controller.request", controller_action, controller_action, @payload ]
8
+ [ "app.controller.request", controller_action, nil, @payload ]
9
9
  end
10
10
 
11
11
  private
@@ -1,15 +1,11 @@
1
1
  module Skylight
2
2
  module Normalize
3
- class RenderCollection < Normalizer
3
+ class RenderCollection < RenderNormalizer
4
4
  register "render_collection.action_view"
5
5
 
6
6
  def normalize
7
- path = @payload[:identifier]
8
- annotations = { count: @payload[:count] }
9
-
10
- [ "view.render.collection", path, path, annotations ]
7
+ normalize_render "view.render.collection", count: @payload[:count]
11
8
  end
12
9
  end
13
10
  end
14
11
  end
15
-
@@ -1,13 +1,10 @@
1
1
  module Skylight
2
2
  module Normalize
3
- class RenderPartial < Normalizer
3
+ class RenderPartial < RenderNormalizer
4
4
  register "render_partial.action_view"
5
5
 
6
6
  def normalize
7
- path = @payload[:identifier]
8
- annotations = { partial: true }
9
-
10
- [ "view.render.template", path, path, annotations ]
7
+ normalize_render "view.render.template", partial: true
11
8
  end
12
9
  end
13
10
  end
@@ -1,13 +1,10 @@
1
1
  module Skylight
2
2
  module Normalize
3
- class RenderTemplate < Normalizer
3
+ class RenderTemplate < RenderNormalizer
4
4
  register "render_template.action_view"
5
5
 
6
6
  def normalize
7
- path = @payload[:identifier]
8
- annotations = { partial: false }
9
-
10
- [ "view.render.template", path, path, annotations ]
7
+ normalize_render "view.render.template", partial: false
11
8
  end
12
9
  end
13
10
  end
@@ -4,11 +4,9 @@ module Skylight
4
4
  register "sql.active_record"
5
5
 
6
6
  def normalize
7
- if @payload[:name] == "SCHEMA"
7
+ case @payload[:name]
8
+ when "SCHEMA", "CACHE"
8
9
  return :skip
9
- elsif @payload[:name] == "CACHE"
10
- name = "db.sql.cache"
11
- title = "Cached Load"
12
10
  else
13
11
  name = "db.sql.query"
14
12
  title = @payload[:name]
@@ -13,9 +13,25 @@ module Skylight
13
13
 
14
14
  attr_accessor :instrumenter
15
15
 
16
+ initializer "skylight.sanity_check" do |app|
17
+ checker = SanityChecker.new
18
+ @problems = checker.smoke_test(config_path(app)) || checker.sanity_check(load_config(app))
19
+ next unless @problems
20
+
21
+ @problems.each do |group, problem_list|
22
+ problem_list.each do |problem|
23
+ puts "[SKYLIGHT] PROBLEM: #{group} #{problem}"
24
+ end
25
+ end
26
+ end
27
+
16
28
  initializer "skylight.configure" do |app|
17
- Rails.logger.debug "[SKYLIGHT] Installing middleware"
18
- app.middleware.insert 0, Middleware, load_config
29
+ if @problems
30
+ puts "[SKYLIGHT] Skipping Skylight boot"
31
+ else
32
+ Rails.logger.debug "[SKYLIGHT] Installing middleware"
33
+ app.middleware.insert 0, Middleware, load_config(app)
34
+ end
19
35
  end
20
36
 
21
37
  private
@@ -24,42 +40,23 @@ module Skylight
24
40
  Array(config.skylight.environments).map { |e| e && e.to_s }.compact
25
41
  end
26
42
 
27
- def load_instrumenter
28
- if environments.include?(Rails.env.to_s)
29
- if c = load_config
30
- Rails.logger.debug "[SKYLIGHT] Starting instrumenter"
31
- Instrumenter.start!(c)
32
- end
33
- end
34
- # Paranoia
35
- rescue
36
- nil
43
+ def config_path(app)
44
+ path = config.skylight.config_path
45
+ File.expand_path(path, app.root)
37
46
  end
38
47
 
39
- def load_config
40
- unless path = config.skylight.config_path
41
- Rails.logger.warn "[SKYLIGHT] Path to config YAML file unset"
42
- return
43
- end
44
-
45
- path = File.expand_path(path, Rails.root)
46
-
47
- unless File.exist?(path)
48
- Rails.logger.warn "[SKYLIGHT] Config does not exist at `#{path}`"
49
- return
50
- end
51
-
52
- ret = Config.load_from_yaml(path)
48
+ def load_config(app)
49
+ @skylight_config ||= begin
50
+ config = Config.load_from_yaml(config_path(app), ENV).tap do |c|
51
+ c.logger = Rails.logger
52
+ end
53
53
 
54
- unless ret.authentication_token
55
- Rails.logger.warn "[SKYLIGHT] Config does not include an authentication token"
56
- return
54
+ config.normalizer.view_paths = app.config.paths["app/views"].existent
55
+ config.http = Util::HTTP.new(config)
56
+ config
57
57
  end
58
-
59
- ret.logger = Rails.logger
60
-
61
- ret
62
58
  rescue => e
59
+ raise
63
60
  Rails.logger.error "[SKYLIGHT] #{e.message} (#{e.class}) - #{e.backtrace.first}"
64
61
  end
65
62