skylight 5.1.1 → 5.3.3
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/CHANGELOG.md +30 -1
- data/ERRORS.md +3 -0
- data/ext/extconf.rb +24 -8
- data/ext/libskylight.yml +8 -10
- data/ext/skylight_native.c +2 -0
- data/lib/skylight/cli/doctor.rb +2 -2
- data/lib/skylight/config.rb +42 -38
- data/lib/skylight/data/cacert.pem +730 -1023
- data/lib/skylight/errors.rb +3 -0
- data/lib/skylight/extensions/source_location.rb +2 -2
- data/lib/skylight/instrumenter.rb +1 -1
- data/lib/skylight/middleware.rb +16 -3
- data/lib/skylight/native.rb +3 -3
- data/lib/skylight/normalizers/active_job/perform.rb +22 -25
- data/lib/skylight/normalizers/active_record/sql.rb +8 -0
- data/lib/skylight/normalizers/grape/endpoint.rb +1 -1
- data/lib/skylight/normalizers/sql.rb +5 -9
- data/lib/skylight/probes/active_record_async.rb +96 -0
- data/lib/skylight/probes/elasticsearch.rb +10 -1
- data/lib/skylight/probes/middleware.rb +2 -2
- data/lib/skylight/probes/mongo.rb +14 -1
- data/lib/skylight/probes/mongoid.rb +6 -13
- data/lib/skylight/probes/rack_builder.rb +37 -0
- data/lib/skylight/probes/sinatra_add_middleware.rb +2 -2
- data/lib/skylight/probes.rb +8 -9
- data/lib/skylight/railtie.rb +12 -4
- data/lib/skylight/sidekiq.rb +1 -1
- data/lib/skylight/sinatra.rb +1 -1
- data/lib/skylight/subscriber.rb +24 -2
- data/lib/skylight/test.rb +1 -5
- data/lib/skylight/user_config.rb +4 -2
- data/lib/skylight/util/clock.rb +1 -1
- data/lib/skylight/util/deploy.rb +4 -4
- data/lib/skylight/util/platform.rb +3 -3
- data/lib/skylight/version.rb +1 -1
- metadata +10 -7
data/lib/skylight/errors.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "skylight/util/lru_cache"
|
4
|
-
require "active_support/
|
4
|
+
require "active_support/inflector"
|
5
5
|
|
6
6
|
module Skylight
|
7
7
|
module Extensions
|
@@ -163,7 +163,7 @@ module Skylight
|
|
163
163
|
|
164
164
|
def instance_method_source_location(constant_name, method_name, source_name: :instance_method)
|
165
165
|
@instance_method_source_location_cache.fetch([constant_name, method_name, source_name]) do
|
166
|
-
if (constant = ::ActiveSupport::
|
166
|
+
if (constant = ::ActiveSupport::Inflector.safe_constantize(constant_name))
|
167
167
|
if constant.instance_methods.include?(:"before_instrument_#{method_name}")
|
168
168
|
method_name = :"before_instrument_#{method_name}"
|
169
169
|
end
|
data/lib/skylight/middleware.rb
CHANGED
@@ -3,6 +3,8 @@ require "securerandom"
|
|
3
3
|
module Skylight
|
4
4
|
# @api private
|
5
5
|
class Middleware
|
6
|
+
SKYLIGHT_REQUEST_ID = "skylight.request_id".freeze
|
7
|
+
|
6
8
|
class BodyProxy
|
7
9
|
def initialize(body, &block)
|
8
10
|
@body = body
|
@@ -81,7 +83,8 @@ module Skylight
|
|
81
83
|
set_request_id(env)
|
82
84
|
|
83
85
|
if Skylight.tracing?
|
84
|
-
|
86
|
+
debug "Already instrumenting. Make sure the Skylight Rack Middleware hasn't been added more than once."
|
87
|
+
return @app.call(env)
|
85
88
|
end
|
86
89
|
|
87
90
|
if env["REQUEST_METHOD"] == "HEAD"
|
@@ -108,7 +111,7 @@ module Skylight
|
|
108
111
|
|
109
112
|
def log_context
|
110
113
|
# Don't cache this, it will change
|
111
|
-
{ request_id:
|
114
|
+
{ request_id: current_request_id, inst: Skylight.instrumenter&.uuid }
|
112
115
|
end
|
113
116
|
|
114
117
|
# Allow for overwriting
|
@@ -122,8 +125,10 @@ module Skylight
|
|
122
125
|
|
123
126
|
# Request ID code based on ActionDispatch::RequestId
|
124
127
|
def set_request_id(env)
|
128
|
+
return if env[SKYLIGHT_REQUEST_ID]
|
129
|
+
|
125
130
|
existing_request_id = env["action_dispatch.request_id"] || env["HTTP_X_REQUEST_ID"]
|
126
|
-
|
131
|
+
self.current_request_id = env[SKYLIGHT_REQUEST_ID] = make_request_id(existing_request_id)
|
127
132
|
end
|
128
133
|
|
129
134
|
def make_request_id(request_id)
|
@@ -133,5 +138,13 @@ module Skylight
|
|
133
138
|
def internal_request_id
|
134
139
|
SecureRandom.uuid
|
135
140
|
end
|
141
|
+
|
142
|
+
def current_request_id
|
143
|
+
Thread.current[SKYLIGHT_REQUEST_ID]
|
144
|
+
end
|
145
|
+
|
146
|
+
def current_request_id=(request_id)
|
147
|
+
Thread.current[SKYLIGHT_REQUEST_ID] = request_id
|
148
|
+
end
|
136
149
|
end
|
137
150
|
end
|
data/lib/skylight/native.rb
CHANGED
@@ -59,13 +59,13 @@ module Skylight
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def self.libskylight_path
|
62
|
-
ENV
|
62
|
+
ENV.fetch("SKYLIGHT_LIB_PATH") { File.expand_path("../native/#{Util::Platform.tuple}", __FILE__) }
|
63
63
|
end
|
64
64
|
|
65
|
-
skylight_required = ENV.key?("SKYLIGHT_REQUIRED") && ENV
|
65
|
+
skylight_required = ENV.key?("SKYLIGHT_REQUIRED") && ENV.fetch("SKYLIGHT_REQUIRED", nil) !~ /^false$/i
|
66
66
|
|
67
67
|
begin
|
68
|
-
unless ENV.key?("SKYLIGHT_DISABLE_AGENT") && ENV
|
68
|
+
unless ENV.key?("SKYLIGHT_DISABLE_AGENT") && ENV.fetch("SKYLIGHT_DISABLE_AGENT", nil) !~ /^false$/i
|
69
69
|
lib = "#{libskylight_path}/libskylight.#{Util::Platform.libext}"
|
70
70
|
|
71
71
|
if File.exist?(lib)
|
@@ -15,7 +15,7 @@ module Skylight
|
|
15
15
|
.tap do |str|
|
16
16
|
if str.match(DELIVERY_JOB)
|
17
17
|
mailer_class, mailer_method, * = job_instance.arguments
|
18
|
-
return "#{mailer_class}##{mailer_method}", str
|
18
|
+
return "#{mailer_class}##{mailer_method}", str if mailer_class && mailer_method
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -33,9 +33,7 @@ module Skylight
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def normalize_after(trace, _span, _name, payload)
|
36
|
-
|
37
|
-
|
38
|
-
trace.segment = payload[:job].queue_name
|
36
|
+
maybe_set_endpoint(trace, payload)
|
39
37
|
end
|
40
38
|
|
41
39
|
private
|
@@ -53,31 +51,30 @@ module Skylight
|
|
53
51
|
end
|
54
52
|
|
55
53
|
def maybe_set_endpoint(trace, payload)
|
56
|
-
|
57
|
-
end
|
54
|
+
endpoint = normalize_title(payload[:job])
|
58
55
|
|
59
|
-
def assign_endpoint?(trace, payload)
|
60
56
|
# Always assign the endpoint if it has not yet been assigned by the ActiveJob probe.
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
57
|
+
if !trace.endpoint ||
|
58
|
+
(defined?(Skylight::Probes::ActiveJob::TITLE) && trace.endpoint == Skylight::Probes::ActiveJob::TITLE) ||
|
59
|
+
(
|
60
|
+
defined?(Skylight::Probes::DelayedJob::Probe::UNKNOWN) &&
|
61
|
+
trace.endpoint == Skylight::Probes::DelayedJob::Probe::UNKNOWN
|
62
|
+
) ||
|
63
|
+
# If a job is called using #perform_now inside a controller action
|
64
|
+
# or within another job's #perform method, we do not want this to
|
65
|
+
# overwrite the existing endpoint name (unless it is the default from ActiveJob).
|
66
|
+
#
|
67
|
+
# If the current endpoint name matches this payload, return true to allow the
|
68
|
+
# segment to be assigned by normalize_after.
|
69
|
+
trace.endpoint =~ DELIVERY_JOB ||
|
70
|
+
# This adapter wrapper needs to be handled specifically due to interactions with the
|
71
|
+
# standalone Delayed::Job probe, as there is no consistent way to get the wrapped
|
72
|
+
# job name among all Delayed::Job backends.
|
73
|
+
trace.endpoint == DELAYED_JOB_WRAPPER
|
74
|
+
trace.endpoint = endpoint
|
68
75
|
end
|
69
76
|
|
70
|
-
|
71
|
-
# or within another job's #perform method, we do not want this to
|
72
|
-
# overwrite the existing endpoint name (unless it is the default from ActiveJob).
|
73
|
-
#
|
74
|
-
# If the current endpoint name matches this payload, return true to allow the
|
75
|
-
# segment to be assigned by normalize_after.
|
76
|
-
trace.endpoint == DELIVERY_JOB || trace.endpoint == normalize_title(payload[:job]) ||
|
77
|
-
# This adapter wrapper needs to be handled specifically due to interactions with the
|
78
|
-
# standalone Delayed::Job probe, as there is no consistent way to get the wrapped
|
79
|
-
# job name among all Delayed::Job backends.
|
80
|
-
trace.endpoint == DELAYED_JOB_WRAPPER
|
77
|
+
trace.segment = payload[:job].queue_name if trace.endpoint == endpoint && config.enable_segments?
|
81
78
|
end
|
82
79
|
|
83
80
|
def normalize_title(job_instance)
|
@@ -7,6 +7,14 @@ module Skylight
|
|
7
7
|
class SQL < Skylight::Normalizers::SQL
|
8
8
|
register "sql.active_record"
|
9
9
|
end
|
10
|
+
|
11
|
+
class FutureResult < Normalizer
|
12
|
+
register "future_result.active_record"
|
13
|
+
|
14
|
+
def normalize(_trace, _name, payload)
|
15
|
+
["db.future_result", "Async #{payload[:args][1] || "Query"}"]
|
16
|
+
end
|
17
|
+
end
|
10
18
|
end
|
11
19
|
end
|
12
20
|
end
|
@@ -20,7 +20,7 @@ module Skylight
|
|
20
20
|
|
21
21
|
def get_namespace(endpoint)
|
22
22
|
# slice off preceding slash for data continuity
|
23
|
-
::Grape::Namespace.joined_space_path(endpoint.namespace_stackable(:namespace)).to_s[1
|
23
|
+
::Grape::Namespace.joined_space_path(endpoint.namespace_stackable(:namespace)).to_s[1..]
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -14,14 +14,10 @@ module Skylight
|
|
14
14
|
# @option payload [String] [:name] The SQL operation
|
15
15
|
# @option payload [Hash] [:binds] The bound parameters
|
16
16
|
# @return [Array]
|
17
|
-
def normalize(_trace,
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
name = CAT
|
23
|
-
title = payload[:name] || "SQL"
|
24
|
-
end
|
17
|
+
def normalize(_trace, _name, payload)
|
18
|
+
return :skip if payload[:name] == "SCHEMA" || payload[:name] == "CACHE"
|
19
|
+
|
20
|
+
title = payload[:name] || "SQL"
|
25
21
|
|
26
22
|
# We can only handle UTF-8 encoded strings.
|
27
23
|
# (Construction method here avoids extra allocations)
|
@@ -38,7 +34,7 @@ module Skylight
|
|
38
34
|
sql = nil
|
39
35
|
end
|
40
36
|
|
41
|
-
[
|
37
|
+
[CAT, title, sql]
|
42
38
|
end
|
43
39
|
end
|
44
40
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Skylight
|
2
|
+
module Probes
|
3
|
+
module ActiveRecord
|
4
|
+
module FutureResult
|
5
|
+
# Applied to ActiveSupport::Notifications::Event
|
6
|
+
module AsyncEventExtensions
|
7
|
+
# Notify Skylight that the event has started
|
8
|
+
def __sk_start!
|
9
|
+
subscriber = Skylight.instrumenter.subscriber
|
10
|
+
subscriber.start(name, nil, payload)
|
11
|
+
trace = Skylight.instrumenter.current_trace
|
12
|
+
|
13
|
+
# Set a finisher to end the event
|
14
|
+
@__sk_finisher = ->(name, payload) do
|
15
|
+
subscriber.with_trace(trace) { subscriber.finish(name, nil, payload) }
|
16
|
+
end
|
17
|
+
|
18
|
+
# End it immediately if we've actually already ended
|
19
|
+
__sk_finish! if @end
|
20
|
+
rescue StandardError => e
|
21
|
+
Skylight.error("Unable to start event for FutureResult: #{e}")
|
22
|
+
end
|
23
|
+
|
24
|
+
# Notify Skylight that the event has finished
|
25
|
+
def __sk_finish!
|
26
|
+
return unless @__sk_finisher
|
27
|
+
|
28
|
+
@__sk_finisher.call(name, payload)
|
29
|
+
@__sk_finisher = nil
|
30
|
+
rescue StandardError => e
|
31
|
+
Skylight.error("Unable to finish event for FutureResult: #{e}")
|
32
|
+
end
|
33
|
+
|
34
|
+
# When the event is marked as finish make sure we notify Skylight
|
35
|
+
def finish!
|
36
|
+
super
|
37
|
+
__sk_finish!
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Applied to FutureResult
|
42
|
+
module Instrumentation
|
43
|
+
def result(*, **)
|
44
|
+
# This instruments the whole FutureResult so that we know when we were executing (potenially) async.
|
45
|
+
ActiveSupport::Notifications.instrument("future_result.active_record", { args: @args, kwargs: @kwargs }) do
|
46
|
+
super
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def execute_or_wait(*, **)
|
53
|
+
# At this point we're actually waiting for the query to have finished executing.
|
54
|
+
|
55
|
+
begin
|
56
|
+
# If the query has already started async, the @event_buffer will be defined.
|
57
|
+
# We grab the events (currently only the SQL queries), extend them with our
|
58
|
+
# special methods and notify Skylight.
|
59
|
+
# We act as if the event has just stared, though the query may already have been
|
60
|
+
# running. This means we're essentially just logging blocking time right now.
|
61
|
+
|
62
|
+
# Dup here just in case more get added somehow during the super call
|
63
|
+
events = @event_buffer&.instance_variable_get(:@events).dup
|
64
|
+
|
65
|
+
events&.each do |event|
|
66
|
+
event.singleton_class.prepend(AsyncEventExtensions)
|
67
|
+
event.__sk_start!
|
68
|
+
end
|
69
|
+
rescue StandardError => e
|
70
|
+
Skylight.error("Unable to start events for FutureResult: #{e}")
|
71
|
+
end
|
72
|
+
|
73
|
+
super
|
74
|
+
ensure
|
75
|
+
# Once we've actually got a result, we mark each one as finished.
|
76
|
+
# Note that it may have already finished, but if it didn't we need to say so now.
|
77
|
+
events&.reverse_each(&:__sk_finish!)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Probe
|
82
|
+
def install
|
83
|
+
::ActiveRecord::FutureResult.prepend(Instrumentation)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
register(
|
90
|
+
:active_record_async,
|
91
|
+
"ActiveRecord::FutureResult",
|
92
|
+
"active_record/future_result",
|
93
|
+
ActiveRecord::FutureResult::Probe.new
|
94
|
+
)
|
95
|
+
end
|
96
|
+
end
|
@@ -3,8 +3,17 @@ module Skylight
|
|
3
3
|
module Elasticsearch
|
4
4
|
class Probe
|
5
5
|
def install
|
6
|
+
const =
|
7
|
+
if defined?(::Elasticsearch::Transport::Transport::Base)
|
8
|
+
::Elasticsearch::Transport::Transport::Base
|
9
|
+
elsif defined?(::Elastic::Transport::Transport::Base)
|
10
|
+
::Elastic::Transport::Transport::Base
|
11
|
+
else
|
12
|
+
return false
|
13
|
+
end
|
14
|
+
|
6
15
|
# Prepending doesn't work here since this a module that's already been included
|
7
|
-
|
16
|
+
const.class_eval do
|
8
17
|
alias_method :perform_request_without_sk, :perform_request
|
9
18
|
def perform_request(method, path, *args, &block)
|
10
19
|
ActiveSupport::Notifications.instrument(
|
@@ -25,10 +25,10 @@ module Skylight
|
|
25
25
|
# for Rails <= 5.2 ActionDispatch::MiddlewareStack::Middleware
|
26
26
|
module Instrumentation
|
27
27
|
def build(*)
|
28
|
-
sk_instrument_middleware(super)
|
28
|
+
Instrumentation.sk_instrument_middleware(super)
|
29
29
|
end
|
30
30
|
|
31
|
-
def sk_instrument_middleware(middleware)
|
31
|
+
def self.sk_instrument_middleware(middleware)
|
32
32
|
return middleware if middleware.is_a?(Skylight::Middleware)
|
33
33
|
|
34
34
|
# Not sure how this would actually happen
|
@@ -5,7 +5,20 @@ module Skylight
|
|
5
5
|
|
6
6
|
class Probe
|
7
7
|
def install
|
8
|
-
|
8
|
+
subscriber = Subscriber.new
|
9
|
+
|
10
|
+
# From the mongo driver:
|
11
|
+
#
|
12
|
+
# > Global subscriptions must be established prior to creating
|
13
|
+
# > clients. When a client is constructed it copies subscribers from
|
14
|
+
# > the Global module; subsequent subscriptions or unsubscriptions
|
15
|
+
# > on the Global module have no effect on already created clients.
|
16
|
+
#
|
17
|
+
# So, for existing clients created before the Skylight initializer
|
18
|
+
# runs, we'll have to subscribe to those individually.
|
19
|
+
::Mongoid::Clients.clients.each { |_name, client| client.subscribe(::Mongo::Monitoring::COMMAND, subscriber) }
|
20
|
+
|
21
|
+
::Mongo::Monitoring::Global.subscribe(::Mongo::Monitoring::COMMAND, subscriber)
|
9
22
|
end
|
10
23
|
end
|
11
24
|
|
@@ -1,13 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
register(:mongoid, "Mongoid", "mongoid", Mongoid::Probe.new)
|
12
|
-
end
|
13
|
-
end
|
1
|
+
# Older versions of the mongoid uses the moped under-the-hood, while newer
|
2
|
+
# verions uses the official driver. It used to be that the the mongoid probe
|
3
|
+
# exists to detect and enable either one of those underlying probes, but at
|
4
|
+
# this point we no longer support moped, so this is now just an alias for the
|
5
|
+
# mongo probe.
|
6
|
+
require_relative "mongo"
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Skylight
|
2
|
+
module Probes
|
3
|
+
module Rack
|
4
|
+
module Builder
|
5
|
+
module Instrumentation
|
6
|
+
def use(middleware, *args, &block)
|
7
|
+
if @map
|
8
|
+
mapping = @map
|
9
|
+
@map = nil
|
10
|
+
@use << proc { |app| generate_map(app, mapping) }
|
11
|
+
end
|
12
|
+
@use << proc do |app|
|
13
|
+
middleware
|
14
|
+
.new(app, *args, &block)
|
15
|
+
.tap do |middleware_instance|
|
16
|
+
Skylight::Probes::Middleware::Instrumentation.sk_instrument_middleware(middleware_instance)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
ruby2_keywords(:use) if respond_to?(:ruby2_keywords, true)
|
21
|
+
end
|
22
|
+
|
23
|
+
class Probe
|
24
|
+
def install
|
25
|
+
if defined?(::Rack.release) && Gem::Version.new(::Rack.release) >= ::Gem::Version.new("1.4") &&
|
26
|
+
defined?(::Rack::Builder)
|
27
|
+
require "skylight/probes/middleware"
|
28
|
+
::Rack::Builder.prepend(Instrumentation)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
register(:rack_builder, "Rack::Builder", "rack/builder", Skylight::Probes::Rack::Builder::Probe.new)
|
36
|
+
end
|
37
|
+
end
|
data/lib/skylight/probes.rb
CHANGED
@@ -78,15 +78,14 @@ module Skylight
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def add_path(path)
|
81
|
-
|
82
|
-
|
83
|
-
.
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
81
|
+
Dir.glob("**/*.rb", base: path) do |f|
|
82
|
+
name = Pathname.new(f).sub_ext("").to_s
|
83
|
+
full_path = File.expand_path(f, path)
|
84
|
+
|
85
|
+
raise "duplicate probe name: #{name}; original=#{available[name]}; new=#{full_path}" if available.key?(name)
|
86
|
+
|
87
|
+
available[name] = full_path
|
88
|
+
end
|
90
89
|
end
|
91
90
|
|
92
91
|
def available
|
data/lib/skylight/railtie.rb
CHANGED
@@ -16,7 +16,15 @@ module Skylight
|
|
16
16
|
# net_http, action_controller, action_dispatch, action_view, and middleware are on by default
|
17
17
|
# See https://www.skylight.io/support/getting-more-from-skylight#available-instrumentation-options
|
18
18
|
# for a full list.
|
19
|
-
config.skylight.probes = %w[
|
19
|
+
config.skylight.probes = %w[
|
20
|
+
net_http
|
21
|
+
action_controller
|
22
|
+
action_dispatch
|
23
|
+
action_view
|
24
|
+
middleware
|
25
|
+
active_job_enqueue
|
26
|
+
active_record_async
|
27
|
+
]
|
20
28
|
|
21
29
|
# The position in the middleware stack to place Skylight
|
22
30
|
# Default is first, but can be `{ after: Middleware::Name }` or `{ before: Middleware::Name }`
|
@@ -99,8 +107,8 @@ module Skylight
|
|
99
107
|
|
100
108
|
configure_logging(config, app)
|
101
109
|
|
102
|
-
config[:
|
103
|
-
config[:
|
110
|
+
config[:"daemon.sockdir_path"] ||= tmp
|
111
|
+
config[:"normalizers.render.view_paths"] = existent_paths(app.config.paths["app/views"]) + [Rails.root.to_s]
|
104
112
|
|
105
113
|
config[:env] ||= Rails.env.to_s if config[:report_rails_env]
|
106
114
|
|
@@ -145,7 +153,7 @@ module Skylight
|
|
145
153
|
return false unless sk_config
|
146
154
|
|
147
155
|
key = "SKYLIGHT_ENABLED"
|
148
|
-
activate = ENV.key?(key) ? ENV
|
156
|
+
activate = ENV.key?(key) ? ENV.fetch(key, nil) !~ /^false$/i : environments.include?(Rails.env.to_s)
|
149
157
|
|
150
158
|
show_worker_activation_warning(sk_config) if activate
|
151
159
|
|
data/lib/skylight/sidekiq.rb
CHANGED
@@ -21,7 +21,7 @@ module Skylight
|
|
21
21
|
|
22
22
|
def call(worker, job, queue)
|
23
23
|
t { "Sidekiq middleware beginning trace" }
|
24
|
-
title = job["wrapped"] || job["class"]
|
24
|
+
title = job["display_class"] || job["wrapped"] || job["class"]
|
25
25
|
|
26
26
|
# TODO: Using hints here would be ideal but requires further refactoring
|
27
27
|
meta =
|
data/lib/skylight/sinatra.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
require "skylight"
|
2
|
-
Skylight.probe(:sinatra_add_middleware, :sinatra, :tilt, :sequel)
|
2
|
+
Skylight.probe(:sinatra_add_middleware, :sinatra, :tilt, :sequel, :rack_builder)
|
data/lib/skylight/subscriber.rb
CHANGED
@@ -36,16 +36,30 @@ module Skylight
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
# cargo-culted from Rails's ConnectionAdapter
|
40
|
+
EXCEPTION_NEVER = { Exception => :never }.freeze # :nodoc:
|
41
|
+
EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze # :nodoc:
|
42
|
+
private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
|
43
|
+
def with_trace(trace, &block) # :nodoc:
|
44
|
+
Thread.handle_interrupt(EXCEPTION_NEVER) do
|
45
|
+
previous_trace = @trace
|
46
|
+
@trace = trace
|
47
|
+
Thread.handle_interrupt(EXCEPTION_IMMEDIATE, &block)
|
48
|
+
ensure
|
49
|
+
@trace = previous_trace
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
39
53
|
def start(name, _id, payload)
|
40
54
|
return if @instrumenter.disabled?
|
41
|
-
return unless (trace =
|
55
|
+
return unless (trace = current_trace)
|
42
56
|
|
43
57
|
_start(trace, name, payload)
|
44
58
|
end
|
45
59
|
|
46
60
|
def finish(name, _id, payload)
|
47
61
|
return if @instrumenter.disabled?
|
48
|
-
return unless (trace =
|
62
|
+
return unless (trace = current_trace)
|
49
63
|
|
50
64
|
while (curr = trace.notifications.pop)
|
51
65
|
next unless curr.name == name
|
@@ -70,8 +84,16 @@ module Skylight
|
|
70
84
|
# Ignored for now because nothing in rails uses it
|
71
85
|
end
|
72
86
|
|
87
|
+
def publish_event(event)
|
88
|
+
# Ignored for now because only ActiveRecord::FutureResult uses it and we handle that with probes
|
89
|
+
end
|
90
|
+
|
73
91
|
private
|
74
92
|
|
93
|
+
def current_trace
|
94
|
+
@trace || @instrumenter.current_trace
|
95
|
+
end
|
96
|
+
|
75
97
|
def normalize(*args)
|
76
98
|
@normalizers.normalize(*args)
|
77
99
|
end
|
data/lib/skylight/test.rb
CHANGED
@@ -25,10 +25,6 @@ module Skylight
|
|
25
25
|
"Mocked Instrumenter"
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.native_new(*)
|
29
|
-
allocate
|
30
|
-
end
|
31
|
-
|
32
28
|
def native_start
|
33
29
|
true
|
34
30
|
end
|
@@ -47,7 +43,7 @@ module Skylight
|
|
47
43
|
:Trace,
|
48
44
|
Class.new(OriginalTrace) do
|
49
45
|
def self.native_new(start, _uuid, endpoint, meta)
|
50
|
-
inst =
|
46
|
+
inst = super
|
51
47
|
inst.instance_variable_set(:@start, start)
|
52
48
|
inst.instance_variable_set(:@endpoint, endpoint)
|
53
49
|
inst.instance_variable_set(:@starting_endpoint, endpoint)
|
data/lib/skylight/user_config.rb
CHANGED
@@ -18,7 +18,9 @@ module Skylight
|
|
18
18
|
@config[:user_config_path] ||
|
19
19
|
begin
|
20
20
|
require "etc"
|
21
|
-
home_dir =
|
21
|
+
home_dir =
|
22
|
+
ENV.fetch("HOME", nil) || Etc.getpwuid.dir ||
|
23
|
+
(ENV.fetch("USER", nil) && File.expand_path("~#{ENV.fetch("USER", nil)}"))
|
22
24
|
if home_dir
|
23
25
|
File.join(home_dir, ".skylight")
|
24
26
|
else
|
@@ -31,7 +33,7 @@ module Skylight
|
|
31
33
|
end
|
32
34
|
|
33
35
|
def disable_dev_warning?
|
34
|
-
disable_dev_warning || ENV
|
36
|
+
disable_dev_warning || ENV.fetch("SKYLIGHT_DISABLE_DEV_WARNING", nil) =~ /^true$/i
|
35
37
|
end
|
36
38
|
|
37
39
|
def disable_env_warning?
|
data/lib/skylight/util/clock.rb
CHANGED