skylight-core 2.0.0.beta2 → 2.0.0.beta3
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 +27 -18
- data/lib/skylight/core/fanout.rb +4 -0
- data/lib/skylight/core/gc.rb +5 -0
- data/lib/skylight/core/instrumentable.rb +26 -15
- data/lib/skylight/core/instrumenter.rb +7 -1
- data/lib/skylight/core/middleware.rb +10 -6
- data/lib/skylight/core/normalizers/sql.rb +9 -3
- data/lib/skylight/core/probes/action_view.rb +1 -3
- data/lib/skylight/core/probes/active_model_serializers.rb +1 -1
- data/lib/skylight/core/probes/excon.rb +1 -1
- data/lib/skylight/core/probes/grape.rb +1 -1
- data/lib/skylight/core/probes/middleware.rb +51 -27
- data/lib/skylight/core/probes/moped.rb +1 -1
- data/lib/skylight/core/probes/redis.rb +1 -1
- data/lib/skylight/core/probes/sinatra.rb +1 -1
- data/lib/skylight/core/railtie.rb +1 -1
- data/lib/skylight/core/test.rb +3 -0
- data/lib/skylight/core/trace.rb +35 -11
- data/lib/skylight/core/util/logging.rb +57 -41
- data/lib/skylight/core/version.rb +1 -1
- data/lib/skylight/core.rb +0 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 237d8a95eb9bd92d8ab981fda27862546cdccfccc4aa0ebb3f5c1bd32bc69494
|
4
|
+
data.tar.gz: 61cd69d8abe954e0033f1c9303a45cb11b7a58561f4c784d3b41c3e2c1896172
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2fecfbbf37b22227727a69d2cde96a585e75e06d3bdd2f272521bff757b6c507a2d144398558e956666b55d4bef0e7121c1f02beeac06142d2c303b08d21999
|
7
|
+
data.tar.gz: ff10cbe2195702b05506df19491ab229b6824daa58fae7cf56afe67d46abdcca1f16faf716ca871a5ab0c3bd0505d729f91b217fd9088f8245a760df55ec9f42
|
data/lib/skylight/core/config.rb
CHANGED
@@ -14,8 +14,9 @@ module Skylight::Core
|
|
14
14
|
# @api private
|
15
15
|
MUTEX = Mutex.new
|
16
16
|
|
17
|
+
def self.log_name; "Skylight" end
|
17
18
|
def self.env_matcher; /^(?:SK|SKYLIGHT)_(.+)$/ end
|
18
|
-
def self.
|
19
|
+
def self.env_prefix; "SKYLIGHT_" end
|
19
20
|
|
20
21
|
# Map environment variable keys with Skylight configuration keys
|
21
22
|
def self.env_to_key
|
@@ -47,7 +48,7 @@ module Skylight::Core
|
|
47
48
|
:log_file => '-'.freeze,
|
48
49
|
:log_level => 'INFO'.freeze,
|
49
50
|
:alert_log_file => '-'.freeze,
|
50
|
-
:log_sql_parse_errors =>
|
51
|
+
:log_sql_parse_errors => true,
|
51
52
|
:enable_segments => true,
|
52
53
|
:'heroku.dyno_info_path' => '/etc/heroku/dyno'
|
53
54
|
}
|
@@ -320,7 +321,7 @@ module Skylight::Core
|
|
320
321
|
value = send_or_get(key)
|
321
322
|
unless value.nil?
|
322
323
|
env_key = self.class.env_to_key.key(key) || key.upcase
|
323
|
-
ret << "#{self.class.
|
324
|
+
ret << "#{self.class.env_prefix}#{env_key}" << cast_for_env(value)
|
324
325
|
end
|
325
326
|
end
|
326
327
|
|
@@ -412,15 +413,19 @@ module Skylight::Core
|
|
412
413
|
private
|
413
414
|
|
414
415
|
def create_logger(out)
|
415
|
-
|
416
|
-
out
|
417
|
-
|
418
|
-
|
419
|
-
|
416
|
+
l = begin
|
417
|
+
if out.is_a?(String)
|
418
|
+
out = File.expand_path(out, root)
|
419
|
+
# May be redundant since we also do this in the permissions check
|
420
|
+
FileUtils.mkdir_p(File.dirname(out))
|
421
|
+
end
|
420
422
|
|
421
|
-
|
422
|
-
|
423
|
-
|
423
|
+
Logger.new(out)
|
424
|
+
rescue
|
425
|
+
Logger.new(STDOUT)
|
426
|
+
end
|
427
|
+
l.progname = self.class.log_name
|
428
|
+
l
|
424
429
|
end
|
425
430
|
|
426
431
|
def load_logger
|
@@ -429,13 +434,17 @@ module Skylight::Core
|
|
429
434
|
out = STDOUT if out == '-'
|
430
435
|
|
431
436
|
l = create_logger(out)
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
437
|
+
if trace?
|
438
|
+
l.level = Logger::DEBUG
|
439
|
+
else
|
440
|
+
l.level =
|
441
|
+
case get(:log_level)
|
442
|
+
when /^debug$/i then Logger::DEBUG
|
443
|
+
when /^info$/i then Logger::INFO
|
444
|
+
when /^warn$/i then Logger::WARN
|
445
|
+
when /^error$/i then Logger::ERROR
|
446
|
+
end
|
447
|
+
end
|
439
448
|
end
|
440
449
|
|
441
450
|
l
|
data/lib/skylight/core/fanout.rb
CHANGED
data/lib/skylight/core/gc.rb
CHANGED
@@ -30,6 +30,11 @@ module Skylight::Core
|
|
30
30
|
@profiler.enable if @profiler
|
31
31
|
end
|
32
32
|
|
33
|
+
# Total time in microseconds for GC over entire process lifetime
|
34
|
+
def total_time
|
35
|
+
@profiler ? @profiler.total_time : nil
|
36
|
+
end
|
37
|
+
|
33
38
|
def track
|
34
39
|
unless @profiler
|
35
40
|
win = Window.new(nil)
|
@@ -3,22 +3,13 @@ module Skylight
|
|
3
3
|
module Instrumentable
|
4
4
|
|
5
5
|
def self.included(base)
|
6
|
+
base.extend(Util::Logging)
|
6
7
|
base.extend(ClassMethods)
|
7
8
|
|
8
9
|
base.const_set(:LOCK, Mutex.new)
|
9
10
|
|
10
11
|
base.class_eval do
|
11
|
-
at_exit
|
12
|
-
if RUBY_VERSION == '1.9.2'
|
13
|
-
# workaround for MRI bug losing exit status in at_exit block
|
14
|
-
# http://bugs.ruby-lang.org/issues/5218
|
15
|
-
exit_status = $!.status if $!.is_a?(SystemExit)
|
16
|
-
stop!
|
17
|
-
exit exit_status if exit_status
|
18
|
-
else
|
19
|
-
stop!
|
20
|
-
end
|
21
|
-
end
|
12
|
+
at_exit { stop! }
|
22
13
|
end
|
23
14
|
|
24
15
|
Skylight::Core::Fanout.register(base)
|
@@ -38,6 +29,10 @@ module Skylight
|
|
38
29
|
nil
|
39
30
|
end
|
40
31
|
|
32
|
+
def probe(*args)
|
33
|
+
Skylight::Core::Probes.probe(*args)
|
34
|
+
end
|
35
|
+
|
41
36
|
# Start instrumenting
|
42
37
|
def start!(config=nil)
|
43
38
|
return @instrumenter if @instrumenter
|
@@ -51,11 +46,17 @@ module Skylight
|
|
51
46
|
@instrumenter = instrumenter_class.new(config).start!
|
52
47
|
end
|
53
48
|
rescue => e
|
54
|
-
message =
|
55
|
-
|
56
|
-
|
49
|
+
level, message = if e.is_a? ConfigError
|
50
|
+
[:warn, sprintf("Unable to start Instrumenter due to a configuration error: %s", e.message)]
|
51
|
+
else
|
52
|
+
[:error, sprintf("Unable to start Instrumenter; msg=%s; class=%s", e.message, e.class)]
|
53
|
+
end
|
54
|
+
|
55
|
+
if config && config.respond_to?("log_#{level}") && config.respond_to?(:log_trace)
|
56
|
+
config.send("log_#{level}", message)
|
57
|
+
config.log_trace e.backtrace.join("\n")
|
57
58
|
else
|
58
|
-
warn message
|
59
|
+
warn "[#{name.upcase}] #{message}"
|
59
60
|
end
|
60
61
|
false
|
61
62
|
end
|
@@ -127,6 +128,11 @@ module Skylight
|
|
127
128
|
instrumenter.done(span, meta)
|
128
129
|
end
|
129
130
|
|
131
|
+
def broken!
|
132
|
+
return unless instrumenter
|
133
|
+
instrumenter.broken!
|
134
|
+
end
|
135
|
+
|
130
136
|
# Temporarily disable
|
131
137
|
def disable
|
132
138
|
unless instrumenter
|
@@ -137,6 +143,11 @@ module Skylight
|
|
137
143
|
instrumenter.disable { yield }
|
138
144
|
end
|
139
145
|
|
146
|
+
def config
|
147
|
+
return unless instrumenter
|
148
|
+
instrumenter.config
|
149
|
+
end
|
150
|
+
|
140
151
|
end
|
141
152
|
|
142
153
|
end
|
@@ -135,7 +135,7 @@ module Skylight::Core
|
|
135
135
|
|
136
136
|
ensure
|
137
137
|
@trace_info.current = nil
|
138
|
-
t { "submitting trace" }
|
138
|
+
t { "instrumenter submitting trace" }
|
139
139
|
trace.submit
|
140
140
|
end
|
141
141
|
end
|
@@ -202,6 +202,11 @@ module Skylight::Core
|
|
202
202
|
trace.span_correlation_header(span)
|
203
203
|
end
|
204
204
|
|
205
|
+
def broken!
|
206
|
+
return unless trace = @trace_info.current
|
207
|
+
trace.broken!
|
208
|
+
end
|
209
|
+
|
205
210
|
def done(span, meta=nil)
|
206
211
|
return unless trace = @trace_info.current
|
207
212
|
trace.done(span, meta)
|
@@ -232,6 +237,7 @@ module Skylight::Core
|
|
232
237
|
true
|
233
238
|
rescue => e
|
234
239
|
warn "failed to submit trace to worker; err=%s", e
|
240
|
+
t { "BACKTRACE:\n#{e.backtrace.join("\n")}" }
|
235
241
|
false
|
236
242
|
end
|
237
243
|
end
|
@@ -42,14 +42,14 @@ module Skylight::Core
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def self.with_after_close(resp, &block)
|
45
|
-
# Responses should be
|
45
|
+
# Responses should be arrays but in some situations they aren't
|
46
46
|
# e.g. https://github.com/ruby-grape/grape/issues/1041
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
# The safest approach seems to be to rely on implicit destructuring
|
48
|
+
# since that is currently what Rack::Lint does.
|
49
|
+
# See also https://github.com/rack/rack/issues/1239
|
50
|
+
status, headers, body = resp
|
50
51
|
|
51
|
-
|
52
|
-
resp
|
52
|
+
[status, headers, BodyProxy.new(body, &block)]
|
53
53
|
end
|
54
54
|
|
55
55
|
include Util::Logging
|
@@ -76,6 +76,10 @@ module Skylight::Core
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def call(env)
|
79
|
+
if instrumentable.tracing?
|
80
|
+
error "Already instrumenting. Make sure the Middleware hasn't been added more than once."
|
81
|
+
end
|
82
|
+
|
79
83
|
if env["REQUEST_METHOD"] == "HEAD"
|
80
84
|
t { "middleware skipping HEAD" }
|
81
85
|
@app.call(env)
|
@@ -31,10 +31,16 @@ module Skylight::Core
|
|
31
31
|
extracted_title, sql = extract_binds(trace.instrumenter, payload, binds)
|
32
32
|
[ name, extracted_title || title, sql ]
|
33
33
|
rescue => e
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
if e.is_a?(Skylight::SqlLexError)
|
35
|
+
if config[:log_sql_parse_errors]
|
36
|
+
config.logger.error "[#{e.formatted_code}] Failed to extract binds from SQL query. " \
|
37
|
+
"It's likely that this query uses more advanced syntax than we currently support. " \
|
38
|
+
"sql=#{payload[:sql].inspect}"
|
39
|
+
end
|
40
|
+
else
|
41
|
+
config.logger.error "Failed to extract binds in SQL; sql=#{payload[:sql].inspect}; exception=#{e.inspect}"
|
37
42
|
end
|
43
|
+
|
38
44
|
[ name, title, nil ]
|
39
45
|
end
|
40
46
|
end
|
@@ -10,11 +10,9 @@ module Skylight::Core
|
|
10
10
|
layout = nil
|
11
11
|
|
12
12
|
if path
|
13
|
-
if
|
14
|
-
# Rails 5
|
13
|
+
if ::ActionView.gem_version >= Gem::Version.new('5.x')
|
15
14
|
layout = find_layout(path, locals.keys, [formats.first])
|
16
15
|
else
|
17
|
-
# Rails 4
|
18
16
|
layout = find_layout(path, locals.keys)
|
19
17
|
end
|
20
18
|
end
|
@@ -19,7 +19,7 @@ module Skylight::Core
|
|
19
19
|
|
20
20
|
if !version || version < Gem::Version.new("0.5.0")
|
21
21
|
# Using $stderr here isn't great, but we don't have a logger accessible
|
22
|
-
$stderr.puts "[SKYLIGHT] [#{Skylight::Core::VERSION}] Instrumention is only available for " \
|
22
|
+
$stderr.puts "[SKYLIGHT::CORE] [#{Skylight::Core::VERSION}] Instrumention is only available for " \
|
23
23
|
"ActiveModelSerializers version 0.5.0 and greater."
|
24
24
|
return
|
25
25
|
end
|
@@ -14,7 +14,7 @@ module Skylight::Core
|
|
14
14
|
::Excon.defaults[:middlewares].insert(idx, Probes::Excon::Middleware)
|
15
15
|
else
|
16
16
|
# Using $stderr here isn't great, but we don't have a logger accessible
|
17
|
-
$stderr.puts "[SKYLIGHT] [#{Skylight::Core::VERSION}] The installed version of Excon doesn't " \
|
17
|
+
$stderr.puts "[SKYLIGHT::CORE] [#{Skylight::Core::VERSION}] The installed version of Excon doesn't " \
|
18
18
|
"support Middlewares. The Excon probe will be disabled."
|
19
19
|
end
|
20
20
|
end
|
@@ -12,7 +12,7 @@ module Skylight::Core
|
|
12
12
|
|
13
13
|
if version < Gem::Version.new("0.10.0")
|
14
14
|
# Using $stderr here isn't great, but we don't have a logger accessible
|
15
|
-
$stderr.puts "[SKYLIGHT] [#{Skylight::Core::VERSION}] The Grape probe only works with version 0.10.0+ " \
|
15
|
+
$stderr.puts "[SKYLIGHT::CORE] [#{Skylight::Core::VERSION}] The Grape probe only works with version 0.10.0+ " \
|
16
16
|
"and will be disabled."
|
17
17
|
|
18
18
|
return
|
@@ -2,7 +2,57 @@ module Skylight::Core
|
|
2
2
|
module Probes
|
3
3
|
module Middleware
|
4
4
|
class Probe
|
5
|
+
def self.add_instrumentation(middleware, default_name: "Anonymous Middleware", category: "rack.middleware")
|
6
|
+
middleware.instance_eval <<-RUBY, __FILE__, __LINE__ + 1
|
7
|
+
alias call_without_sk call
|
8
|
+
def call(*args, &block)
|
9
|
+
traces = Skylight::Core::Fanout.registered.map do |r|
|
10
|
+
r.instrumenter ? r.instrumenter.current_trace : nil
|
11
|
+
end.compact
|
12
|
+
|
13
|
+
return call_without_sk(*args, &block) if traces.empty?
|
14
|
+
|
15
|
+
begin
|
16
|
+
name = self.class.name || "#{default_name}"
|
17
|
+
|
18
|
+
traces.each{|t| t.endpoint = name }
|
19
|
+
|
20
|
+
spans = Skylight::Core::Fanout.instrument(title: name, category: "#{category}")
|
21
|
+
resp = call_without_sk(*args, &block)
|
22
|
+
|
23
|
+
Skylight::Core::Middleware.with_after_close(resp) do
|
24
|
+
Skylight::Core::Fanout.done(spans)
|
25
|
+
end
|
26
|
+
rescue Exception => e
|
27
|
+
# FIXME: Log this?
|
28
|
+
Skylight::Core::Fanout.done(spans, exception_object: e)
|
29
|
+
raise
|
30
|
+
end
|
31
|
+
end
|
32
|
+
RUBY
|
33
|
+
end
|
34
|
+
|
5
35
|
def install
|
36
|
+
ActionDispatch::MiddlewareStack.class_eval do
|
37
|
+
alias build_without_sk build
|
38
|
+
|
39
|
+
if ::ActionPack.gem_version >= Gem::Version.new('5.x')
|
40
|
+
# Rails 5
|
41
|
+
def build(app = Proc.new)
|
42
|
+
Skylight::Core::Probes::Middleware::Probe.add_instrumentation(app, default_name: "Rack App", category: "rack.app")
|
43
|
+
build_without_sk(app)
|
44
|
+
end
|
45
|
+
else
|
46
|
+
# Rails 3 and 4
|
47
|
+
def build(app, &block)
|
48
|
+
app ||= block
|
49
|
+
raise "MiddlewareStack#build requires an app" unless app
|
50
|
+
Skylight::Core::Probes::Middleware::Probe.add_instrumentation(app, default_name: "Rack App", category: "rack.app")
|
51
|
+
build_without_sk(app)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
6
56
|
ActionDispatch::MiddlewareStack::Middleware.class_eval do
|
7
57
|
alias build_without_sk build
|
8
58
|
def build(*args)
|
@@ -18,33 +68,7 @@ module Skylight::Core
|
|
18
68
|
# On Rails 3, ActionDispatch::Session::CookieStore is frozen, for one
|
19
69
|
return middleware if middleware.frozen?
|
20
70
|
|
21
|
-
middleware
|
22
|
-
alias call_without_sk call
|
23
|
-
def call(*args, &block)
|
24
|
-
traces = Skylight::Core::Fanout.registered.map do |r|
|
25
|
-
r.instrumenter ? r.instrumenter.current_trace : nil
|
26
|
-
end.compact
|
27
|
-
|
28
|
-
return call_without_sk(*args, &block) if traces.empty?
|
29
|
-
|
30
|
-
begin
|
31
|
-
name = self.class.name || "Anonymous Middleware"
|
32
|
-
|
33
|
-
traces.each{|t| t.endpoint = name }
|
34
|
-
|
35
|
-
spans = Skylight::Core::Fanout.instrument(title: name, category: "rack.middleware")
|
36
|
-
resp = call_without_sk(*args, &block)
|
37
|
-
|
38
|
-
Skylight::Core::Middleware.with_after_close(resp) do
|
39
|
-
Skylight::Core::Fanout.done(spans)
|
40
|
-
end
|
41
|
-
rescue Exception => e
|
42
|
-
# FIXME: Log this?
|
43
|
-
Skylight::Core::Fanout.done(spans, exception_object: e)
|
44
|
-
raise
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
71
|
+
Skylight::Core::Probes::Middleware::Probe.add_instrumentation(middleware)
|
48
72
|
|
49
73
|
middleware
|
50
74
|
end
|
@@ -6,7 +6,7 @@ module Skylight::Core
|
|
6
6
|
def install
|
7
7
|
unless defined?(::Moped::Instrumentable)
|
8
8
|
# Using $stderr here isn't great, but we don't have a logger accessible
|
9
|
-
$stderr.puts "[SKYLIGHT] [#{Skylight::Core::VERSION}] The installed version of Moped doesn't " \
|
9
|
+
$stderr.puts "[SKYLIGHT::CORE] [#{Skylight::Core::VERSION}] The installed version of Moped doesn't " \
|
10
10
|
"support instrumentation. The Moped probe will be disabled."
|
11
11
|
|
12
12
|
return
|
@@ -7,7 +7,7 @@ module Skylight::Core
|
|
7
7
|
|
8
8
|
if !version || version < Gem::Version.new("3.0.0")
|
9
9
|
# Using $stderr here isn't great, but we don't have a logger accessible
|
10
|
-
$stderr.puts "[SKYLIGHT] [#{Skylight::Core::VERSION}] The installed version of Redis doesn't " \
|
10
|
+
$stderr.puts "[SKYLIGHT::CORE] [#{Skylight::Core::VERSION}] The installed version of Redis doesn't " \
|
11
11
|
"support Middlewares. At least version 3.0.0 is required."
|
12
12
|
return
|
13
13
|
end
|
@@ -5,7 +5,7 @@ module Skylight::Core
|
|
5
5
|
def install
|
6
6
|
if ::Sinatra::VERSION < '1.4.0'
|
7
7
|
# Using $stderr here isn't great, but we don't have a logger accessible
|
8
|
-
$stderr.puts "[SKYLIGHT] [#{Skylight::VERSION}] Sinatra must be version 1.4.0 or greater."
|
8
|
+
$stderr.puts "[SKYLIGHT::CORE] [#{Skylight::VERSION}] Sinatra must be version 1.4.0 or greater."
|
9
9
|
return
|
10
10
|
end
|
11
11
|
|
data/lib/skylight/core/test.rb
CHANGED
@@ -56,6 +56,9 @@ module Skylight
|
|
56
56
|
mock_spans[sp][:meta] = meta
|
57
57
|
end
|
58
58
|
|
59
|
+
def native_span_started(sp)
|
60
|
+
end
|
61
|
+
|
59
62
|
def native_span_set_exception(sp, exception_object, exception)
|
60
63
|
mock_spans[sp][:exception_object] = exception_object
|
61
64
|
mock_spans[sp][:exception] = exception
|
data/lib/skylight/core/trace.rb
CHANGED
@@ -50,8 +50,12 @@ module Skylight::Core
|
|
50
50
|
@instrumenter.config
|
51
51
|
end
|
52
52
|
|
53
|
+
def broken?
|
54
|
+
!!@broken
|
55
|
+
end
|
56
|
+
|
53
57
|
def record(cat, title=nil, desc=nil)
|
54
|
-
return if
|
58
|
+
return if broken?
|
55
59
|
|
56
60
|
title.freeze if title.is_a?(String)
|
57
61
|
desc.freeze if desc.is_a?(String)
|
@@ -65,12 +69,12 @@ module Skylight::Core
|
|
65
69
|
nil
|
66
70
|
rescue => e
|
67
71
|
error "failed to record span; msg=%s", e.message
|
68
|
-
|
72
|
+
broken!
|
69
73
|
nil
|
70
74
|
end
|
71
75
|
|
72
76
|
def instrument(cat, title=nil, desc=nil, meta=nil)
|
73
|
-
return if
|
77
|
+
return if broken?
|
74
78
|
t { "instrument: #{cat}, #{title}" }
|
75
79
|
|
76
80
|
title.freeze if title.is_a?(String)
|
@@ -81,7 +85,8 @@ module Skylight::Core
|
|
81
85
|
desc = @instrumenter.limited_description(desc)
|
82
86
|
|
83
87
|
if desc == Instrumenter::TOO_MANY_UNIQUES
|
84
|
-
|
88
|
+
error "[E0002] The number of unique span descriptions allowed per-request has been exceeded " \
|
89
|
+
"for endpoint: #{endpoint}."
|
85
90
|
debug "original desc=%s", original_desc
|
86
91
|
debug "cat=%s, title=%s, desc=%s", cat, title, desc
|
87
92
|
end
|
@@ -89,17 +94,18 @@ module Skylight::Core
|
|
89
94
|
start(now - gc_time, cat, title, desc, meta)
|
90
95
|
rescue => e
|
91
96
|
error "failed to instrument span; msg=%s", e.message
|
92
|
-
|
97
|
+
broken!
|
93
98
|
nil
|
94
99
|
end
|
95
100
|
|
96
101
|
def span_correlation_header(span)
|
102
|
+
return unless span
|
97
103
|
native_span_get_correlation_header(span)
|
98
104
|
end
|
99
105
|
|
100
106
|
def done(span, meta=nil)
|
101
107
|
return unless span
|
102
|
-
return if
|
108
|
+
return if broken?
|
103
109
|
|
104
110
|
if meta && (meta[:exception_object] || meta[:exception])
|
105
111
|
native_span_set_exception(span, meta[:exception_object], meta[:exception])
|
@@ -108,7 +114,7 @@ module Skylight::Core
|
|
108
114
|
stop(span, Util::Clock.nanos - gc_time)
|
109
115
|
rescue => e
|
110
116
|
error "failed to close span; msg=%s", e.message
|
111
|
-
|
117
|
+
broken!
|
112
118
|
nil
|
113
119
|
end
|
114
120
|
|
@@ -117,6 +123,11 @@ module Skylight::Core
|
|
117
123
|
@instrumenter.current_trace = nil
|
118
124
|
end
|
119
125
|
|
126
|
+
def broken!
|
127
|
+
debug "trace is broken"
|
128
|
+
@broken = true
|
129
|
+
end
|
130
|
+
|
120
131
|
def traced
|
121
132
|
time = gc_time
|
122
133
|
now = Util::Clock.nanos
|
@@ -130,9 +141,9 @@ module Skylight::Core
|
|
130
141
|
end
|
131
142
|
|
132
143
|
def submit
|
133
|
-
|
144
|
+
t { "submitting trace; broken=#{broken?}" }
|
134
145
|
|
135
|
-
|
146
|
+
return if broken?
|
136
147
|
|
137
148
|
if @submitted
|
138
149
|
t { "already submitted" }
|
@@ -159,6 +170,7 @@ module Skylight::Core
|
|
159
170
|
native_span_set_title(sp, title.to_s) if title
|
160
171
|
native_span_set_description(sp, desc.to_s) if desc
|
161
172
|
native_span_set_meta(sp, meta) if meta
|
173
|
+
native_span_started(sp)
|
162
174
|
|
163
175
|
@spans << sp
|
164
176
|
t { "started span: #{sp} - #{cat}, #{title}" }
|
@@ -171,9 +183,21 @@ module Skylight::Core
|
|
171
183
|
|
172
184
|
expected = @spans.pop
|
173
185
|
unless span == expected
|
174
|
-
|
175
|
-
|
186
|
+
message = "[E0001] Spans were closed out of order. Expected to see '#{native_span_get_title(expected)}', " \
|
187
|
+
"but got '#{native_span_get_title(span)}' instead."
|
188
|
+
|
189
|
+
if native_span_get_category(span) == "rack.middleware"
|
190
|
+
message << "\n#{native_span_get_title(span)} may be a Middleware that doesn't fully conform " \
|
191
|
+
"to the Rack SPEC."
|
192
|
+
end
|
193
|
+
|
194
|
+
message << "\nThis request will not be tracked. Please contact support@skylight.io for more information."
|
195
|
+
|
196
|
+
error message
|
197
|
+
|
176
198
|
t { "expected=#{expected}, actual=#{span}" }
|
199
|
+
|
200
|
+
broken!
|
177
201
|
end
|
178
202
|
|
179
203
|
time = self.class.normalize_time(time)
|
@@ -25,36 +25,41 @@ module Skylight::Core
|
|
25
25
|
|
26
26
|
module Logging
|
27
27
|
|
28
|
-
def
|
29
|
-
|
28
|
+
def log_env_prefix
|
29
|
+
if c = config_for_logging
|
30
|
+
c.class.env_prefix
|
31
|
+
else
|
32
|
+
"SKYLIGHT_"
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
|
-
|
33
|
-
#
|
34
|
-
|
35
|
-
log :debug, msg, *args
|
36
|
-
end
|
36
|
+
def trace?
|
37
|
+
!!ENV["#{log_env_prefix}ENABLE_TRACE_LOGS"]
|
38
|
+
end
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
else
|
42
|
-
# Logs if `ENV[TRACE_ENV_KEY]` is set.
|
43
|
-
#
|
44
|
-
# @param (see #debug)
|
45
|
-
#
|
46
|
-
# See {TRACE_ENV_KEY}.
|
47
|
-
def trace(msg, *args)
|
48
|
-
end
|
40
|
+
def raise_on_error?
|
41
|
+
!!ENV["#{log_env_prefix}RAISE_ON_ERROR"]
|
42
|
+
end
|
49
43
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
44
|
+
# Logs if tracing
|
45
|
+
#
|
46
|
+
# @param (see #debug)
|
47
|
+
#
|
48
|
+
# See {trace?}.
|
49
|
+
def trace(msg, *args)
|
50
|
+
return unless trace?
|
51
|
+
log :debug, msg, *args
|
52
|
+
end
|
53
|
+
|
54
|
+
# Evaluates and logs the result of the block if tracing
|
55
|
+
#
|
56
|
+
# @yield block to be evaluted
|
57
|
+
# @yieldreturn arguments for {#debug}
|
58
|
+
#
|
59
|
+
# See {trace?}.
|
60
|
+
def t
|
61
|
+
return unless trace?
|
62
|
+
log :debug, yield
|
58
63
|
end
|
59
64
|
|
60
65
|
# @param msg (see #log)
|
@@ -79,7 +84,7 @@ module Skylight::Core
|
|
79
84
|
# @param args (see #log)
|
80
85
|
def error(msg, *args)
|
81
86
|
log :error, msg, *args
|
82
|
-
raise sprintf(msg, *args) if
|
87
|
+
raise sprintf(msg, *args) if raise_on_error?
|
83
88
|
end
|
84
89
|
|
85
90
|
alias log_trace trace
|
@@ -94,29 +99,40 @@ module Skylight::Core
|
|
94
99
|
sprintf(*args)
|
95
100
|
end
|
96
101
|
|
97
|
-
|
98
|
-
|
99
|
-
# @param args [Array] values for `Kernel#sprintf` on `msg`
|
100
|
-
def log(level, msg, *args)
|
101
|
-
c = if respond_to?(:config)
|
102
|
+
def config_for_logging
|
103
|
+
if respond_to?(:config)
|
102
104
|
config
|
103
105
|
elsif self.is_a?(Config)
|
104
106
|
self
|
105
107
|
end
|
108
|
+
end
|
106
109
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
110
|
+
# @param level [String,Symbol] the method on `logger` to use for logging
|
111
|
+
# @param msg [String] the message to log
|
112
|
+
# @param args [Array] values for `Kernel#sprintf` on `msg`
|
113
|
+
def log(level, msg, *args)
|
114
|
+
c = config_for_logging
|
115
|
+
logger = c ? c.logger : nil
|
116
|
+
|
117
|
+
if logger
|
118
|
+
if logger.respond_to?(level)
|
119
|
+
if args.length > 0
|
120
|
+
logger.send level, sprintf(msg, *args)
|
121
|
+
else
|
122
|
+
logger.send level, msg
|
123
|
+
end
|
124
|
+
return
|
114
125
|
else
|
115
|
-
|
126
|
+
Kernel.warn "Invalid logger"
|
116
127
|
end
|
117
128
|
end
|
129
|
+
|
130
|
+
# Fallback
|
131
|
+
module_name = self.is_a?(Module) ? name : self.class.name
|
132
|
+
root_name = module_name.split('::').first.upcase
|
133
|
+
puts sprintf("[#{root_name}] #{msg}", *args)
|
118
134
|
rescue Exception => e
|
119
|
-
if
|
135
|
+
if trace?
|
120
136
|
puts "[ERROR] #{e.message}"
|
121
137
|
puts e.backtrace
|
122
138
|
end
|
data/lib/skylight/core.rb
CHANGED
@@ -6,9 +6,6 @@ module Skylight
|
|
6
6
|
autoload :Normalizers, 'skylight/core/normalizers'
|
7
7
|
end
|
8
8
|
|
9
|
-
# @api private
|
10
|
-
TRACE_ENV_KEY = 'SKYLIGHT_ENABLE_TRACE_LOGS'.freeze
|
11
|
-
|
12
9
|
# Some methods exepected to be defined by the native code (OUTDATED)
|
13
10
|
#
|
14
11
|
# * Skylight::Core::Util::Clock#native_hrtime
|
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.0.
|
4
|
+
version: 2.0.0.beta3
|
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-
|
11
|
+
date: 2018-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|