skylight-core 2.0.0.beta3 → 2.0.0

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