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.
@@ -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
- require "./config/application"
81
- Rails.application.class.name.split("::").first.underscore
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
@@ -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 = 500
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
- @config = config
20
+ # Convert a hash to a config object
21
+ if Hash === config
22
+ config = Config.new(config)
23
+ end
23
24
 
24
- @worker = Worker.new(self)
25
+ @config = config
26
+ @started = false
27
+ @worker = Worker.new(self)
25
28
  end
26
29
 
27
30
  def start!
28
- @worker.start!
29
- Subscriber.register!(config)
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
- # Ensure properly configured
32
- return unless config
42
+ # Ensure properly configured
43
+ return unless config
33
44
 
34
- # Ensure that there is an API token
35
- unless config.authentication_token
36
- if logger = config.logger
37
- logger.warn "[SKYLIGHT] No authentication token provided; cannot start agent."
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
- return
41
- end
54
+ config.gc_profiler.enable
42
55
 
43
- config.gc_profiler.enable
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
@@ -1,46 +1,24 @@
1
1
  module Skylight
2
2
  class Middleware
3
- def self.new(app, config, *)
4
- return app unless config
3
+
4
+ def self.new(app, instrumenter, *)
5
+ return app unless instrumenter
5
6
  super
6
7
  end
7
8
 
8
- def initialize(app, config, instrumenter_class=Instrumenter)
9
+ def initialize(app, instrumenter)
9
10
  @app = app
10
- @config = config
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.trace("Rack") do
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
- def normalize_status
35
- status = @payload[:status] || 200
36
- Rack::Utils.status_code(status)
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
- def normalize_disposition
40
- @payload[:disposition] || "attachment"
41
- end
47
+ rescue LoadError
42
48
  end
49
+
43
50
  end
44
51
  end
@@ -13,52 +13,61 @@ 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
16
+ initializer "skylight.configure" do |app|
17
+ config = load_config(app)
20
18
 
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
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, load_config(app)
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 environments
40
- Array(config.skylight.environments).map { |e| e && e.to_s }.compact
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 config_path(app)
44
- path = config.skylight.config_path
45
- File.expand_path(path, app.root)
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
@@ -19,8 +19,6 @@ module Skylight
19
19
 
20
20
  def finish(name, id, payload)
21
21
  return unless trace = Trace.current
22
-
23
- logger.debug("[SKYLIGHT] END")
24
22
  trace.stop
25
23
  end
26
24
 
@@ -94,7 +94,14 @@ module Skylight
94
94
 
95
95
  update_cumulative_gc
96
96
 
97
- span.ended_at = now - @timestamp - @cumulative_gc
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
@@ -1,3 +1,3 @@
1
1
  module Skylight
2
- VERSION = '0.0.10'
2
+ VERSION = '0.0.11'
3
3
  end
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.10
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: 2.0.3
150
+ rubygems_version: 1.8.25
145
151
  signing_key:
146
- specification_version: 4
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