skylight-core 2.0.0.beta3 → 2.0.0

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/skylight/core.rb +1 -0
  3. data/lib/skylight/core/config.rb +2 -0
  4. data/lib/skylight/core/deprecation.rb +15 -0
  5. data/lib/skylight/core/instrumentable.rb +8 -0
  6. data/lib/skylight/core/instrumenter.rb +20 -12
  7. data/lib/skylight/core/middleware.rb +46 -14
  8. data/lib/skylight/core/normalizers.rb +34 -86
  9. data/lib/skylight/core/normalizers/action_view/render_collection.rb +2 -0
  10. data/lib/skylight/core/normalizers/action_view/render_partial.rb +2 -0
  11. data/lib/skylight/core/normalizers/action_view/render_template.rb +2 -0
  12. data/lib/skylight/core/normalizers/render.rb +77 -0
  13. data/lib/skylight/core/probes.rb +73 -73
  14. data/lib/skylight/core/probes/action_controller.rb +1 -1
  15. data/lib/skylight/core/probes/action_dispatch.rb +1 -0
  16. data/lib/skylight/core/probes/action_dispatch/request_id.rb +31 -0
  17. data/lib/skylight/core/probes/action_view.rb +1 -1
  18. data/lib/skylight/core/probes/active_model_serializers.rb +1 -1
  19. data/lib/skylight/core/probes/elasticsearch.rb +1 -1
  20. data/lib/skylight/core/probes/excon.rb +1 -1
  21. data/lib/skylight/core/probes/faraday.rb +1 -1
  22. data/lib/skylight/core/probes/httpclient.rb +1 -1
  23. data/lib/skylight/core/probes/middleware.rb +19 -3
  24. data/lib/skylight/core/probes/mongo.rb +1 -1
  25. data/lib/skylight/core/probes/mongoid.rb +3 -3
  26. data/lib/skylight/core/probes/moped.rb +1 -1
  27. data/lib/skylight/core/probes/net_http.rb +1 -1
  28. data/lib/skylight/core/probes/redis.rb +1 -1
  29. data/lib/skylight/core/probes/sequel.rb +1 -1
  30. data/lib/skylight/core/probes/sinatra.rb +1 -1
  31. data/lib/skylight/core/probes/tilt.rb +1 -1
  32. data/lib/skylight/core/test.rb +95 -82
  33. data/lib/skylight/core/trace.rb +48 -19
  34. data/lib/skylight/core/user_config.rb +1 -0
  35. data/lib/skylight/core/util.rb +0 -1
  36. data/lib/skylight/core/util/logging.rb +12 -4
  37. data/lib/skylight/core/version.rb +1 -1
  38. metadata +9 -8
  39. data/lib/skylight/core/normalizers/couch_potato/query.rb +0 -20
  40. data/lib/skylight/core/probes/grape.rb +0 -80
  41. data/lib/skylight/core/util/deploy.rb +0 -132
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 237d8a95eb9bd92d8ab981fda27862546cdccfccc4aa0ebb3f5c1bd32bc69494
4
- data.tar.gz: 61cd69d8abe954e0033f1c9303a45cb11b7a58561f4c784d3b41c3e2c1896172
3
+ metadata.gz: 0d65618c6d6e9fcecd44bca37e8d7e3fbade73ce213712ab8af7ca71c6707e8c
4
+ data.tar.gz: '01867c672012d9400da14b148f856745d611695f4a85677eca624de60c9f87dc'
5
5
  SHA512:
6
- metadata.gz: b2fecfbbf37b22227727a69d2cde96a585e75e06d3bdd2f272521bff757b6c507a2d144398558e956666b55d4bef0e7121c1f02beeac06142d2c303b08d21999
7
- data.tar.gz: ff10cbe2195702b05506df19491ab229b6824daa58fae7cf56afe67d46abdcca1f16faf716ca871a5ab0c3bd0505d729f91b217fd9088f8245a760df55ec9f42
6
+ metadata.gz: e610c23d07e5e8c02f4be9ef602689e9d1a1abfdd2ee58a72dbdd643b7e6d6d9abef8eb256951563d5296bfd8f0c18d0de76af69be8d4e3f403a67293cd95423
7
+ data.tar.gz: 6dff8d6a3e452b7657f8c011c0dbf54205d01795effe34826ab38da5700bc778be3b99bff952684bfbaf5c312093f69c38907f35211f111dbb9c5bee4361d37d
data/lib/skylight/core.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'skylight/core/version'
2
+ require 'skylight/core/deprecation'
2
3
 
3
4
  module Skylight
4
5
  module Core
@@ -98,6 +98,8 @@ module Skylight::Core
98
98
  @values = {}
99
99
  @priority = {}
100
100
  @regexp = nil
101
+ @alert_logger = nil
102
+ @logger = nil
101
103
 
102
104
  p = attrs.delete(:priority)
103
105
 
@@ -0,0 +1,15 @@
1
+ require 'active_support/deprecation'
2
+
3
+ module Skylight
4
+ SKYLIGHT_GEM_ROOT = File.expand_path("../../..", __FILE__) + "/"
5
+
6
+ class Deprecation < ActiveSupport::Deprecation
7
+ private
8
+
9
+ def ignored_callstack(path)
10
+ path.start_with?(SKYLIGHT_GEM_ROOT)
11
+ end
12
+ end
13
+
14
+ DEPRECATOR = Deprecation.new('3.0', 'skylight')
15
+ end
@@ -33,6 +33,10 @@ module Skylight
33
33
  Skylight::Core::Probes.probe(*args)
34
34
  end
35
35
 
36
+ def enable_normalizer(*names)
37
+ Skylight::Core::Normalizers.enable(*names)
38
+ end
39
+
36
40
  # Start instrumenting
37
41
  def start!(config=nil)
38
42
  return @instrumenter if @instrumenter
@@ -63,7 +67,10 @@ module Skylight
63
67
 
64
68
  # Stop instrumenting
65
69
  def stop!
70
+ t { "stop!" }
71
+
66
72
  const_get(:LOCK).synchronize do
73
+ t { "stop! synchronized" }
67
74
  return unless @instrumenter
68
75
  # This is only really helpful for getting specs to pass.
69
76
  @instrumenter.current_trace = nil
@@ -75,6 +82,7 @@ module Skylight
75
82
 
76
83
  # Check tracing
77
84
  def tracing?
85
+ t { "checking tracing?; thread=#{Thread.current.object_id}"}
78
86
  instrumenter && instrumenter.current_trace
79
87
  end
80
88
 
@@ -1,5 +1,6 @@
1
1
  require 'thread'
2
2
  require 'strscan'
3
+ require 'securerandom'
3
4
 
4
5
  module Skylight::Core
5
6
  # @api private
@@ -24,25 +25,27 @@ module Skylight::Core
24
25
  end
25
26
  end
26
27
 
27
- attr_reader :config, :gc, :trace_info
28
+ attr_reader :uuid, :config, :gc, :trace_info
28
29
 
29
30
  def self.trace_class
30
31
  Trace
31
32
  end
32
33
 
33
- def self.native_new
34
+ def self.native_new(_uuid, _config_env)
34
35
  raise "not implemented"
35
36
  end
36
37
 
37
38
  def self.new(config)
38
39
  config.validate!
39
40
 
40
- inst = native_new(config.to_native_env)
41
- inst.send(:initialize, config)
41
+ uuid = SecureRandom.uuid
42
+ inst = native_new(uuid, config.to_native_env)
43
+ inst.send(:initialize, uuid, config)
42
44
  inst
43
45
  end
44
46
 
45
- def initialize(config)
47
+ def initialize(uuid, config)
48
+ @uuid = uuid
46
49
  @gc = config.gc
47
50
  @config = config
48
51
  @subscriber = Subscriber.new(config, self)
@@ -51,6 +54,10 @@ module Skylight::Core
51
54
  @trace_info = @config[:trace_info] || TraceInfo.new(key)
52
55
  end
53
56
 
57
+ def log_context
58
+ @log_context ||= { inst: uuid }
59
+ end
60
+
54
61
  def native_start
55
62
  raise "not implemented"
56
63
  end
@@ -59,11 +66,11 @@ module Skylight::Core
59
66
  raise "not implemented"
60
67
  end
61
68
 
62
- def native_track_desc
69
+ def native_track_desc(_endpoint, _description)
63
70
  raise "not implemented"
64
71
  end
65
72
 
66
- def native_submit_trace
73
+ def native_submit_trace(_trace)
67
74
  raise "not implemented"
68
75
  end
69
76
 
@@ -72,6 +79,7 @@ module Skylight::Core
72
79
  end
73
80
 
74
81
  def current_trace=(trace)
82
+ t { "setting current_trace=#{trace ? trace.uuid : "nil"}; thread=#{Thread.current.object_id}" }
75
83
  @trace_info.current = trace
76
84
  end
77
85
 
@@ -135,7 +143,7 @@ module Skylight::Core
135
143
 
136
144
  ensure
137
145
  @trace_info.current = nil
138
- t { "instrumenter submitting trace" }
146
+ t { "instrumenter submitting trace; trace=#{trace.uuid}" }
139
147
  trace.submit
140
148
  end
141
149
  end
@@ -172,7 +180,7 @@ module Skylight::Core
172
180
  cat = cat.to_s
173
181
 
174
182
  unless match?(cat, Skylight::CATEGORY_REGEX)
175
- warn "invalid skylight instrumentation category; value=%s", cat
183
+ warn "invalid skylight instrumentation category; trace=%s; value=%s", trace.uuid, cat
176
184
  return yield if block_given?
177
185
  return
178
186
  end
@@ -225,10 +233,10 @@ module Skylight::Core
225
233
  end
226
234
 
227
235
  def process(trace)
228
- t { fmt "processing trace" }
236
+ t { fmt "processing trace=#{trace.uuid}" }
229
237
 
230
238
  if ignore?(trace)
231
- t { fmt "ignoring trace" }
239
+ t { fmt "ignoring trace=#{trace.uuid}" }
232
240
  return false
233
241
  end
234
242
 
@@ -236,7 +244,7 @@ module Skylight::Core
236
244
  native_submit_trace(trace)
237
245
  true
238
246
  rescue => e
239
- warn "failed to submit trace to worker; err=%s", e
247
+ warn "failed to submit trace to worker; trace=%s, err=%s", trace.uuid, e
240
248
  t { "BACKTRACE:\n#{e.backtrace.join("\n")}" }
241
249
  false
242
250
  end
@@ -1,3 +1,5 @@
1
+ require 'securerandom'
2
+
1
3
  module Skylight::Core
2
4
  # @api private
3
5
  class Middleware
@@ -62,22 +64,11 @@ module Skylight::Core
62
64
  @config = opts[:config]
63
65
  end
64
66
 
65
- def instrumentable
66
- Skylight
67
- end
68
-
69
- # Allow for overwriting
70
- def endpoint_name(_env)
71
- "Rack"
72
- end
73
-
74
- def endpoint_meta(_env)
75
- nil
76
- end
77
-
78
67
  def call(env)
68
+ set_request_id(env)
69
+
79
70
  if instrumentable.tracing?
80
- error "Already instrumenting. Make sure the Middleware hasn't been added more than once."
71
+ error "Already instrumenting. Make sure the Skylight Rack Middleware hasn't been added more than once."
81
72
  end
82
73
 
83
74
  if env["REQUEST_METHOD"] == "HEAD"
@@ -87,6 +78,8 @@ module Skylight::Core
87
78
  begin
88
79
  t { "middleware beginning trace" }
89
80
  trace = instrumentable.trace(endpoint_name(env), 'app.rack.request', nil, endpoint_meta(env))
81
+ t { "middleware began trace=#{trace.uuid}" }
82
+
90
83
  resp = @app.call(env)
91
84
 
92
85
  if trace
@@ -101,5 +94,44 @@ module Skylight::Core
101
94
  end
102
95
  end
103
96
  end
97
+
98
+ private
99
+
100
+ def log_context
101
+ # Don't cache this, it will change
102
+ inst_id = instrumentable.instrumenter ? instrumentable.instrumenter.uuid : nil
103
+ { request_id: @current_request_id, inst: inst_id }
104
+ end
105
+
106
+ def instrumentable
107
+ Skylight
108
+ end
109
+
110
+ # Allow for overwriting
111
+ def endpoint_name(_env)
112
+ "Rack"
113
+ end
114
+
115
+ def endpoint_meta(_env)
116
+ nil
117
+ end
118
+
119
+ # Request ID code based on ActionDispatch::RequestId
120
+ def set_request_id(env)
121
+ existing_request_id = env["action_dispatch.request_id"] || env['HTTP_X_REQUEST_ID'];
122
+ @current_request_id = env["skylight.request_id"] = make_request_id(existing_request_id)
123
+ end
124
+
125
+ def make_request_id(request_id)
126
+ if request_id && !request_id.empty?
127
+ request_id.gsub(/[^\w\-]/, "".freeze).first(255)
128
+ else
129
+ internal_request_id
130
+ end
131
+ end
132
+
133
+ def internal_request_id
134
+ SecureRandom.uuid
135
+ end
104
136
  end
105
137
  end
@@ -7,29 +7,51 @@ module Skylight::Core
7
7
 
8
8
  DEFAULT = Default.new
9
9
 
10
- def self.register(name, klass)
11
- (@registry ||= {})[name] = klass
12
- klass
10
+ def self.registry
11
+ @registry ||= {}
12
+ end
13
+
14
+ def self.register(name, klass, opts={})
15
+ enabled = opts[:enabled] != false
16
+ registry[name] = [klass, enabled]
17
+ end
18
+
19
+ def self.unregister(name)
20
+ @registry.delete(name)
21
+ end
22
+
23
+ def self.enable(*names, enabled: true)
24
+ names.each do |name|
25
+ matches = registry.select{|n,_| n =~ /(^|\.)#{name}$/ }
26
+ raise ArgumentError, "no normalizers match #{name}" if matches.empty?
27
+ matches.values.each{|v| v[1] = enabled }
28
+ end
29
+ end
30
+
31
+ def self.disable(*names)
32
+ enable(*names, enabled: false)
13
33
  end
14
34
 
15
35
  def self.build(config)
16
36
  normalizers = {}
17
37
 
18
- (@registry || {}).each do |k, klass|
38
+ registry.each do |key, (klass, enabled)|
39
+ next if !enabled
40
+
19
41
  unless klass.method_defined?(:normalize)
20
42
  # TODO: Warn
21
43
  next
22
44
  end
23
45
 
24
- normalizers[k] = klass.new(config)
46
+ normalizers[key] = klass.new(config)
25
47
  end
26
48
 
27
49
  Container.new(normalizers)
28
50
  end
29
51
 
30
52
  class Normalizer
31
- def self.register(name)
32
- Normalizers.register(name, self)
53
+ def self.register(name, opts={})
54
+ Normalizers.register(name, self, opts)
33
55
  end
34
56
 
35
57
  attr_reader :config
@@ -47,80 +69,6 @@ module Skylight::Core
47
69
  end
48
70
  end
49
71
 
50
- # Base Normalizer for Rails rendering
51
- class RenderNormalizer < Normalizer
52
- include Util::AllocationFree
53
-
54
- def setup
55
- @paths = config['normalizers.render.view_paths'] || []
56
- end
57
-
58
- # Generic normalizer for renders
59
- # @param category [String]
60
- # @param payload [Hash]
61
- # @option payload [String] :identifier
62
- # @return [Array]
63
- def normalize_render(category, payload)
64
- if path = payload[:identifier]
65
- title = relative_path(path)
66
- path = nil if path == title
67
- end
68
-
69
- [ category, title, nil ]
70
- end
71
-
72
- def relative_path(path)
73
- return path if relative_path?(path)
74
-
75
- root = array_find(@paths) { |p| path.start_with?(p) }
76
- type = :project
77
-
78
- unless root
79
- root = array_find(Gem.path) { |p| path.start_with?(p) }
80
- type = :gem
81
- end
82
-
83
- if root
84
- start = root.size
85
- start += 1 if path.getbyte(start) == SEPARATOR_BYTE
86
- if type == :gem
87
- "$GEM_PATH/#{path[start, path.size]}"
88
- else
89
- path[start, path.size]
90
- end
91
- else
92
- "Absolute Path"
93
- end
94
- end
95
-
96
- private
97
- def relative_path?(path)
98
- !absolute_path?(path)
99
- end
100
-
101
- SEPARATOR_BYTE = File::SEPARATOR.ord
102
-
103
- if File.const_defined?(:NULL) ? File::NULL == "NUL" : RbConfig::CONFIG['host_os'] =~ /mingw|mswin32/
104
- # This is a DOSish environment
105
- ALT_SEPARATOR_BYTE = File::ALT_SEPARATOR && File::ALT_SEPARATOR.ord
106
- COLON_BYTE = ":".ord
107
- def absolute_path?(path)
108
- if alpha?(path.getbyte(0)) && path.getbyte(1) == COLON_BYTE
109
- byte2 = path.getbyte(2)
110
- byte2 == SEPARATOR_BYTE || byte2 == ALT_SEPARATOR_BYTE
111
- end
112
- end
113
-
114
- def alpha?(byte)
115
- byte >= 65 and byte <= 90 || byte >= 97 and byte <= 122
116
- end
117
- else
118
- def absolute_path?(path)
119
- path.getbyte(0) == SEPARATOR_BYTE
120
- end
121
- end
122
- end
123
-
124
72
  class Container
125
73
  def initialize(normalizers)
126
74
  @normalizers = normalizers
@@ -139,7 +87,10 @@ module Skylight::Core
139
87
  end
140
88
 
141
89
  def normalizer_for(name)
142
- @normalizers[name] || DEFAULT
90
+ # We never expect to hit the default case since we only register listeners
91
+ # for items that we know have normalizers. For now, though, we'll play it
92
+ # safe and provide a fallback.
93
+ @normalizers.fetch(name, DEFAULT)
143
94
  end
144
95
  end
145
96
 
@@ -148,13 +99,13 @@ module Skylight::Core
148
99
  action_view/render_collection
149
100
  action_view/render_partial
150
101
  action_view/render_template
102
+ active_job/enqueue_at
151
103
  active_model_serializers/render
152
104
  active_record/instantiation
153
105
  active_record/sql
154
106
  active_support/cache
155
107
  coach/handler_finish
156
108
  coach/middleware_finish
157
- couch_potato/query
158
109
  data_mapper/sql
159
110
  elasticsearch/request
160
111
  faraday/request
@@ -163,8 +114,5 @@ module Skylight::Core
163
114
  sequel/sql).each do |file|
164
115
  require "skylight/core/normalizers/#{file}"
165
116
  end
166
-
167
- # The following are not required by default as they are of dubious usefulness:
168
- # - active_job/enqueue_at
169
117
  end
170
118
  end
@@ -1,3 +1,5 @@
1
+ require 'skylight/core/normalizers/render'
2
+
1
3
  module Skylight::Core
2
4
  module Normalizers
3
5
  module ActionView