skylight-core 2.0.1 → 2.0.2.beta
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.
- checksums.yaml +4 -4
- data/lib/skylight/core/config.rb +8 -1
- data/lib/skylight/core/fanout.rb +0 -1
- data/lib/skylight/core/instrumenter.rb +2 -0
- data/lib/skylight/core/middleware.rb +1 -1
- data/lib/skylight/core/normalizers/active_record/sql.rb +1 -1
- data/lib/skylight/core/normalizers/grape/endpoint.rb +3 -1
- data/lib/skylight/core/normalizers/grape/format_response.rb +21 -0
- data/lib/skylight/core/probes/middleware.rb +11 -3
- data/lib/skylight/core/probes/tilt.rb +1 -1
- data/lib/skylight/core/sidekiq.rb +41 -0
- data/lib/skylight/core/subscriber.rb +8 -20
- data/lib/skylight/core/trace.rb +49 -22
- data/lib/skylight/core/user_config.rb +1 -1
- data/lib/skylight/core/version.rb +1 -1
- data/lib/skylight/core.rb +1 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d9ef05dea2241e0a6ec4b0d5cef5803457a80b5e40ef5d8b166640528da91555
|
4
|
+
data.tar.gz: fea0b9a66551b26c8d0f0cc4daf6f59ac320e80fa4b860c5d299547ac243eb1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dff2bc263dbdf1335e7c84123fca8814f3f32ef883420730e7a08bf3e5e8449c11470ccaf61b691829178c49dffbcc62360a8f6153c93d53232dac2906e51c45
|
7
|
+
data.tar.gz: 9cae9daf7ddf1302125b68ea98eacb27d34b6444e2bd8a0ac92dfdc0c34b532562f95179ea17b5394f8b6457d21f3fd2c6b5cd3ab489d6c8f1f1b542e95616c8
|
data/lib/skylight/core/config.rb
CHANGED
@@ -32,12 +32,12 @@ module Skylight::Core
|
|
32
32
|
|
33
33
|
# == Instrumenter ==
|
34
34
|
"ENABLE_SEGMENTS" => :enable_segments,
|
35
|
+
"ENABLE_SIDEKIQ" => :enable_sidekiq,
|
35
36
|
|
36
37
|
# == User config settings ==
|
37
38
|
"USER_CONFIG_PATH" => :'user_config_path',
|
38
39
|
|
39
40
|
# == Heroku settings ==
|
40
|
-
#
|
41
41
|
"HEROKU_DYNO_INFO_PATH" => :'heroku.dyno_info_path'
|
42
42
|
}
|
43
43
|
end
|
@@ -50,6 +50,7 @@ module Skylight::Core
|
|
50
50
|
:alert_log_file => '-'.freeze,
|
51
51
|
:log_sql_parse_errors => true,
|
52
52
|
:enable_segments => true,
|
53
|
+
:enable_sidekiq => false,
|
53
54
|
:'heroku.dyno_info_path' => '/etc/heroku/dyno'
|
54
55
|
}
|
55
56
|
end
|
@@ -404,6 +405,10 @@ module Skylight::Core
|
|
404
405
|
!!get(:enable_segments)
|
405
406
|
end
|
406
407
|
|
408
|
+
def enable_sidekiq?
|
409
|
+
!!get(:enable_sidekiq)
|
410
|
+
end
|
411
|
+
|
407
412
|
def user_config
|
408
413
|
@user_config ||= UserConfig.new(self)
|
409
414
|
end
|
@@ -445,6 +450,8 @@ module Skylight::Core
|
|
445
450
|
when /^info$/i then Logger::INFO
|
446
451
|
when /^warn$/i then Logger::WARN
|
447
452
|
when /^error$/i then Logger::ERROR
|
453
|
+
when /^fatal$/i then Logger::FATAL
|
454
|
+
else Logger::ERROR
|
448
455
|
end
|
449
456
|
end
|
450
457
|
end
|
data/lib/skylight/core/fanout.rb
CHANGED
@@ -21,7 +21,7 @@ module Skylight::Core
|
|
21
21
|
meta[:adapter] = config[:adapter]
|
22
22
|
meta[:database] = config[:database]
|
23
23
|
rescue => e
|
24
|
-
warn "Unable to get ActiveRecord config; e=#{e}"
|
24
|
+
trace.instrumenter.warn "Unable to get ActiveRecord config; e=#{e}"
|
25
25
|
end
|
26
26
|
|
27
27
|
[name, title, description, meta]
|
@@ -8,6 +8,8 @@ module Skylight::Core
|
|
8
8
|
require "skylight/core/normalizers/grape/endpoint_#{type}"
|
9
9
|
end
|
10
10
|
|
11
|
+
require 'skylight/core/normalizers/grape/format_response'
|
12
|
+
|
11
13
|
private
|
12
14
|
|
13
15
|
def get_method(endpoint)
|
@@ -27,4 +29,4 @@ module Skylight::Core
|
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
30
|
-
end
|
32
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Skylight::Core
|
2
|
+
module Normalizers
|
3
|
+
module Grape
|
4
|
+
class FormatResponse < Normalizer
|
5
|
+
register "format_response.grape"
|
6
|
+
|
7
|
+
CAT = "view.grape.format_response".freeze
|
8
|
+
|
9
|
+
def normalize(_trace, _name, payload)
|
10
|
+
if (formatter = payload[:formatter])
|
11
|
+
title = formatter.is_a?(Module) ? formatter.to_s : formatter.class.to_s
|
12
|
+
[CAT, title, nil]
|
13
|
+
else
|
14
|
+
:skip
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -36,13 +36,21 @@ module Skylight::Core
|
|
36
36
|
spans = Skylight::Core::Fanout.instrument(title: name, category: "#{category}")
|
37
37
|
resp = call_without_sk(*args, &block)
|
38
38
|
|
39
|
-
Skylight::Core::Middleware.with_after_close(resp) do
|
39
|
+
proxied_response = Skylight::Core::Middleware.with_after_close(resp) do
|
40
40
|
Skylight::Core::Fanout.done(spans)
|
41
41
|
end
|
42
|
-
rescue Exception =>
|
42
|
+
rescue Exception => err
|
43
43
|
# FIXME: Log this?
|
44
|
-
Skylight::Core::Fanout.done(spans, exception_object:
|
44
|
+
Skylight::Core::Fanout.done(spans, exception_object: err)
|
45
45
|
raise
|
46
|
+
ensure
|
47
|
+
unless err || proxied_response
|
48
|
+
# If we've gotten to this point, the most likely scenario is that
|
49
|
+
# a throw/catch has bypassed a portion of the callstack. Since these spans would not otherwise
|
50
|
+
# be closed, mark them deferred to indicate that they should be implicitly closed.
|
51
|
+
# See Core::Trace#deferred_spans or Core::Trace#stop for more information.
|
52
|
+
Skylight::Core::Fanout.done(spans, defer: true)
|
53
|
+
end
|
46
54
|
end
|
47
55
|
end
|
48
56
|
RUBY
|
@@ -10,7 +10,7 @@ module Skylight::Core
|
|
10
10
|
def render(*args, &block)
|
11
11
|
opts = {
|
12
12
|
category: "view.render.template",
|
13
|
-
title: options[:sky_virtual_path] || "Unknown template name"
|
13
|
+
title: options[:sky_virtual_path] || basename || "Unknown template name"
|
14
14
|
}
|
15
15
|
|
16
16
|
Skylight::Core::Fanout.instrument(opts) do
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Skylight
|
2
|
+
module Core
|
3
|
+
module Sidekiq
|
4
|
+
def self.add_middleware(instrumentable)
|
5
|
+
::Sidekiq.configure_server do |sidekiq_config|
|
6
|
+
instrumentable.debug "Adding Sidekiq Middleware"
|
7
|
+
|
8
|
+
sidekiq_config.server_middleware do |chain|
|
9
|
+
# Put it at the front
|
10
|
+
chain.prepend ServerMiddleware, instrumentable
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ServerMiddleware
|
16
|
+
include Util::Logging
|
17
|
+
|
18
|
+
def initialize(instrumentable)
|
19
|
+
@instrumentable = instrumentable
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(_worker, job, queue)
|
23
|
+
t { "Sidekiq middleware beginning trace" }
|
24
|
+
job_class = job['wrapped'] || job['class']
|
25
|
+
title = "#{job_class}#perform"
|
26
|
+
segment = queue != 'default' ? "<sk-segment>#{queue}</sk-segment>" : ""
|
27
|
+
@instrumentable.trace("#{title}#{segment}", 'app.sidekiq.worker', title) do
|
28
|
+
yield
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
ActiveSupport::Notifications.subscribe("started_instrumenter.skylight") \
|
34
|
+
do |_name, _started, _finished, _unique_id, payload|
|
35
|
+
if payload[:instrumenter].config.enable_sidekiq?
|
36
|
+
add_middleware(payload[:instrumenter])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -7,32 +7,22 @@ module Skylight::Core
|
|
7
7
|
|
8
8
|
def initialize(config, instrumenter)
|
9
9
|
@config = config
|
10
|
-
@subscriber = nil
|
11
10
|
@normalizers = Normalizers.build(config)
|
12
11
|
@instrumenter = instrumenter
|
12
|
+
@subscribers = []
|
13
13
|
end
|
14
14
|
|
15
15
|
def register!
|
16
|
-
unregister!
|
17
|
-
|
18
|
-
|
16
|
+
unregister!
|
17
|
+
@normalizers.keys.each do |key|
|
18
|
+
@subscribers << ActiveSupport::Notifications.subscribe(key, self)
|
19
|
+
end
|
19
20
|
end
|
20
21
|
|
21
22
|
def unregister!
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
class ArrayPattern
|
27
|
-
|
28
|
-
def initialize(keys)
|
29
|
-
@keys = Set.new keys
|
23
|
+
until @subscribers.empty?
|
24
|
+
ActiveSupport::Notifications.unsubscribe @subscribers.shift
|
30
25
|
end
|
31
|
-
|
32
|
-
def ===(item)
|
33
|
-
@keys.include?(item)
|
34
|
-
end
|
35
|
-
|
36
26
|
end
|
37
27
|
|
38
28
|
#
|
@@ -57,10 +47,8 @@ module Skylight::Core
|
|
57
47
|
|
58
48
|
unless result == :skip
|
59
49
|
case result.size
|
60
|
-
when 4
|
50
|
+
when 3, 4
|
61
51
|
cat, title, desc, meta = result
|
62
|
-
when 3
|
63
|
-
cat, title, desc = result
|
64
52
|
else
|
65
53
|
raise "Invalid normalizer result: #{result.inspect}"
|
66
54
|
end
|
data/lib/skylight/core/trace.rb
CHANGED
@@ -122,6 +122,11 @@ module Skylight::Core
|
|
122
122
|
|
123
123
|
return if broken?
|
124
124
|
|
125
|
+
if meta && meta[:defer]
|
126
|
+
deferred_spans[span] ||= (Util::Clock.nanos - gc_time)
|
127
|
+
return
|
128
|
+
end
|
129
|
+
|
125
130
|
if meta && (meta[:exception_object] || meta[:exception])
|
126
131
|
native_span_set_exception(span, meta[:exception_object], meta[:exception])
|
127
132
|
end
|
@@ -201,37 +206,59 @@ module Skylight::Core
|
|
201
206
|
sp
|
202
207
|
end
|
203
208
|
|
209
|
+
# Middleware spans that were interrupted by a throw/catch should be cached here.
|
210
|
+
# keys: span ids
|
211
|
+
# values: nsec timestamp at which the span was cached here.
|
212
|
+
def deferred_spans
|
213
|
+
@deferred_spans ||= {}
|
214
|
+
end
|
215
|
+
|
204
216
|
def stop(span, time)
|
205
217
|
t { "stopping span: #{span}" }
|
206
218
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
Probes.installed.keys.include?("ActionDispatch::MiddlewareStack::Middleware")
|
214
|
-
if Probes::Middleware::Probe.disabled?
|
215
|
-
message << "\nWe disabled the Middleware probe but unfortunately, this didn't solve the issue."
|
216
|
-
else
|
217
|
-
Probes::Middleware::Probe.disable!
|
218
|
-
message << "\n#{native_span_get_title(span)} may be a Middleware that doesn't fully conform " \
|
219
|
-
"to the Rack SPEC. We've disabled the Middleware probe to see if that resolves the issue."
|
220
|
-
end
|
221
|
-
end
|
219
|
+
# If `stop` is called for a span that is not the last item in the stack,
|
220
|
+
# check to see if the last item has been marked as deferred. If so, close
|
221
|
+
# that span first, then try to close the original.
|
222
|
+
while deferred_spans[expected = @spans.pop]
|
223
|
+
normalized_stop(expected, deferred_spans.delete(expected))
|
224
|
+
end
|
222
225
|
|
223
|
-
|
226
|
+
handle_unexpected_stop(expected, span) unless span == expected
|
224
227
|
|
225
|
-
|
228
|
+
normalized_stop(span, time)
|
229
|
+
nil
|
230
|
+
end
|
226
231
|
|
227
|
-
|
232
|
+
def normalized_stop(span, time)
|
233
|
+
time = self.class.normalize_time(time)
|
234
|
+
native_stop_span(span, time)
|
235
|
+
end
|
228
236
|
|
229
|
-
|
237
|
+
# Originally extracted from `stop`.
|
238
|
+
# If we attempt to close spans out of order, and it appears to be a middleware issue,
|
239
|
+
# disable the middleware probe and mark trace as broken.
|
240
|
+
def handle_unexpected_stop(expected, span)
|
241
|
+
message = "[E0001] Spans were closed out of order. Expected to see '#{native_span_get_title(expected)}', " \
|
242
|
+
"but got '#{native_span_get_title(span)}' instead."
|
243
|
+
|
244
|
+
if native_span_get_category(span) == "rack.middleware" &&
|
245
|
+
Probes.installed.keys.include?("ActionDispatch::MiddlewareStack::Middleware")
|
246
|
+
if Probes::Middleware::Probe.disabled?
|
247
|
+
message << "\nWe disabled the Middleware probe but unfortunately, this didn't solve the issue."
|
248
|
+
else
|
249
|
+
Probes::Middleware::Probe.disable!
|
250
|
+
message << "\n#{native_span_get_title(span)} may be a Middleware that doesn't fully conform " \
|
251
|
+
"to the Rack SPEC. We've disabled the Middleware probe to see if that resolves the issue."
|
252
|
+
end
|
230
253
|
end
|
231
254
|
|
232
|
-
|
233
|
-
|
234
|
-
|
255
|
+
message << "\nThis request will not be tracked. Please contact support@skylight.io for more information."
|
256
|
+
|
257
|
+
error message
|
258
|
+
|
259
|
+
t { "expected=#{expected}, actual=#{span}" }
|
260
|
+
|
261
|
+
broken!
|
235
262
|
end
|
236
263
|
|
237
264
|
def gc_time
|
data/lib/skylight/core.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skylight-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2.beta
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tilde, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- lib/skylight/core/normalizers/grape/endpoint_render.rb
|
185
185
|
- lib/skylight/core/normalizers/grape/endpoint_run.rb
|
186
186
|
- lib/skylight/core/normalizers/grape/endpoint_run_filters.rb
|
187
|
+
- lib/skylight/core/normalizers/grape/format_response.rb
|
187
188
|
- lib/skylight/core/normalizers/moped/query.rb
|
188
189
|
- lib/skylight/core/normalizers/render.rb
|
189
190
|
- lib/skylight/core/normalizers/sequel/sql.rb
|
@@ -210,6 +211,7 @@ files:
|
|
210
211
|
- lib/skylight/core/probes/sinatra.rb
|
211
212
|
- lib/skylight/core/probes/tilt.rb
|
212
213
|
- lib/skylight/core/railtie.rb
|
214
|
+
- lib/skylight/core/sidekiq.rb
|
213
215
|
- lib/skylight/core/subscriber.rb
|
214
216
|
- lib/skylight/core/test.rb
|
215
217
|
- lib/skylight/core/trace.rb
|
@@ -244,9 +246,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
244
246
|
version: 2.2.7
|
245
247
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
246
248
|
requirements:
|
247
|
-
- - "
|
249
|
+
- - ">"
|
248
250
|
- !ruby/object:Gem::Version
|
249
|
-
version:
|
251
|
+
version: 1.3.1
|
250
252
|
requirements: []
|
251
253
|
rubyforge_project:
|
252
254
|
rubygems_version: 2.7.6
|