skylight-core 2.0.0.beta2 → 2.0.0.beta3
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 +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
|