skylight-core 2.0.1 → 2.0.2.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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
|