skylight 5.0.0.beta → 5.0.0.beta2
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 +7 -1
- data/ext/extconf.rb +2 -2
- data/lib/skylight/cli/doctor.rb +11 -13
- data/lib/skylight/config.rb +18 -18
- data/lib/skylight/deprecation.rb +3 -1
- data/lib/skylight/extensions.rb +8 -0
- data/lib/skylight/extensions/source_location.rb +107 -76
- data/lib/skylight/instrumenter.rb +3 -2
- data/lib/skylight/middleware.rb +4 -4
- data/lib/skylight/native_ext_fetcher.rb +2 -2
- data/lib/skylight/normalizers.rb +2 -2
- data/lib/skylight/normalizers/action_controller/process_action.rb +1 -1
- data/lib/skylight/normalizers/action_dispatch/route_set.rb +1 -1
- data/lib/skylight/normalizers/active_job/perform.rb +5 -0
- data/lib/skylight/normalizers/graphql/base.rb +1 -0
- data/lib/skylight/normalizers/render.rb +1 -1
- data/lib/skylight/normalizers/sql.rb +3 -2
- data/lib/skylight/probes.rb +38 -10
- data/lib/skylight/probes/active_job.rb +4 -6
- data/lib/skylight/probes/active_job_enqueue.rb +12 -14
- data/lib/skylight/probes/active_model_serializers.rb +2 -6
- data/lib/skylight/probes/delayed_job.rb +111 -25
- data/lib/skylight/probes/middleware.rb +2 -1
- data/lib/skylight/probes/net_http.rb +0 -1
- data/lib/skylight/railtie.rb +1 -1
- data/lib/skylight/sidekiq.rb +12 -7
- data/lib/skylight/subscriber.rb +1 -1
- data/lib/skylight/trace.rb +5 -1
- data/lib/skylight/util/deploy.rb +3 -6
- data/lib/skylight/util/http.rb +1 -1
- data/lib/skylight/util/logging.rb +2 -2
- data/lib/skylight/util/lru_cache.rb +1 -3
- data/lib/skylight/version.rb +1 -1
- metadata +7 -8
- data/lib/skylight/fanout.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b77ca3f00aac3011421d279776acf31f9259debecb3319689250e49fbd3310f
|
4
|
+
data.tar.gz: 6cee4d4a09aa991c3e5d3cf65bc9534797f59fc8951a7d088025271068d9e9cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98649cab11fb628dcfdade4a7dc5507d7640f5f90b6aa9230305fc1c5261d5f73ff3014bc399595f4bc6c85fafb334668f1b81e9020ea5e1f644f3e60ad966d7
|
7
|
+
data.tar.gz: edfacb9d5322768a0dbdd9acbdd31ea5305a077dee1a24076078c448c73a9cd7b0b1889ead269db9e661ed49d11e02e2da38326bad90448b12db72718b949a81
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
+
## 5.0.0.beta2
|
2
|
+
* [FEATURE] Source Locations detection and reporting is now enabled by default (can be disabled with `SKYLIGHT_ENABLE_SOURCE_LOCATIONS=false`)
|
3
|
+
* [BREAKING] Rename `environment` keyword argument to `priority_key`. Note `env` has not changed.
|
4
|
+
* [BREAKING] Drop support for Ruby 2.4
|
5
|
+
* [IMPROVEMENT] Improved Delayed::Job probe
|
6
|
+
|
1
7
|
## 5.0.0.beta
|
2
8
|
* [BREAKING] Merge skylight-core into skylight. All classes previously namespaced under `Skylight::Core` have been moved to `Skylight`.
|
3
9
|
* [BREAKING] Remove `Skylight::Util::Inflector`
|
4
10
|
* [BREAKING] Drop support for Rails 4
|
5
|
-
* [BREAKING] Drop support for
|
11
|
+
* [BREAKING] Drop support for Ruby 2.3
|
6
12
|
* [IMPROVEMENT] Maintain method visibility when instrumenting with `instrument_method`
|
7
13
|
* [IMPROVEMENT] Update probes to use `Module#prepend` where possible
|
8
14
|
* [IMPROVEMENT] New tokio-based skylightd
|
data/ext/extconf.rb
CHANGED
@@ -42,7 +42,7 @@ SKYLIGHT_CHECKSUM = ENV["SKYLIGHT_CHECKSUM"]
|
|
42
42
|
SKYLIGHT_EXT_STRICT = ENV.key?("SKYLIGHT_EXT_STRICT") && ENV["SKYLIGHT_EXT_STRICT"] =~ /^true$/i
|
43
43
|
|
44
44
|
# Setup logger
|
45
|
-
LOG = Logger.new(MultiIO.new(
|
45
|
+
LOG = Logger.new(MultiIO.new($stdout, File.open(SKYLIGHT_INSTALL_LOG, "a")))
|
46
46
|
|
47
47
|
# Handles terminating in the case of a failure. If we have a bug, we do not
|
48
48
|
# want to break our customer's deploy, but extconf.rb requires a Makefile to be
|
@@ -69,7 +69,7 @@ end
|
|
69
69
|
if Platform::OS == "darwin"
|
70
70
|
# If the user installs Xcode-only, they have to approve the
|
71
71
|
# license or no "xc*" tool will work.
|
72
|
-
if `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$CHILD_STATUS.success?
|
72
|
+
if `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$CHILD_STATUS.success? # rubocop:disable Style/SoleNestedConditional
|
73
73
|
fail <<~MESSAGE
|
74
74
|
You have not agreed to the Xcode license and so we are unable to build the native agent.
|
75
75
|
To resolve this, you can agree to the license by opening Xcode.app or running:
|
data/lib/skylight/cli/doctor.rb
CHANGED
@@ -85,20 +85,18 @@ module Skylight
|
|
85
85
|
say "Checking for valid configuration"
|
86
86
|
|
87
87
|
indent do
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
say "This may occur if you are configuring with ENV variables and didn't set them in this shell."
|
98
|
-
end
|
99
|
-
|
100
|
-
done!
|
88
|
+
config.validate!
|
89
|
+
say "Configuration is valid", :green
|
90
|
+
rescue ConfigError => e
|
91
|
+
encountered_error!
|
92
|
+
|
93
|
+
say "Configuration is invalid", :red
|
94
|
+
indent do
|
95
|
+
say e.message, :red
|
96
|
+
say "This may occur if you are configuring with ENV variables and didn't set them in this shell."
|
101
97
|
end
|
98
|
+
|
99
|
+
done!
|
102
100
|
end
|
103
101
|
|
104
102
|
puts "\n"
|
data/lib/skylight/config.rb
CHANGED
@@ -119,9 +119,7 @@ module Skylight
|
|
119
119
|
native_log_level: "LOG_LEVEL"
|
120
120
|
}.freeze
|
121
121
|
|
122
|
-
SERVER_VALIDATE = %i[
|
123
|
-
enable_source_locations
|
124
|
-
].freeze
|
122
|
+
SERVER_VALIDATE = %i[].freeze
|
125
123
|
|
126
124
|
DEFAULT_IGNORED_SOURCE_LOCATION_GEMS = [
|
127
125
|
-"skylight",
|
@@ -150,7 +148,7 @@ module Skylight
|
|
150
148
|
enable_segments: true,
|
151
149
|
enable_sidekiq: false,
|
152
150
|
sinatra_route_prefixes: false,
|
153
|
-
enable_source_locations:
|
151
|
+
enable_source_locations: true,
|
154
152
|
|
155
153
|
# Deploys
|
156
154
|
'heroku.dyno_info_path': -"/etc/heroku/dyno",
|
@@ -243,7 +241,7 @@ module Skylight
|
|
243
241
|
end
|
244
242
|
|
245
243
|
# @api private
|
246
|
-
attr_reader :
|
244
|
+
attr_reader :priority_key
|
247
245
|
|
248
246
|
# @api private
|
249
247
|
def initialize(*args)
|
@@ -253,16 +251,16 @@ module Skylight
|
|
253
251
|
attrs = args.pop.dup
|
254
252
|
end
|
255
253
|
|
256
|
-
@values
|
254
|
+
@values = {}
|
257
255
|
@priority = {}
|
258
|
-
@
|
256
|
+
@priority_regexp = nil
|
259
257
|
@alert_logger = nil
|
260
258
|
@logger = nil
|
261
259
|
|
262
260
|
p = attrs.delete(:priority)
|
263
261
|
|
264
|
-
if (@
|
265
|
-
@
|
262
|
+
if (@priority_key = args[0])
|
263
|
+
@priority_regexp = /^#{Regexp.escape(priority_key)}\.(.+)$/
|
266
264
|
end
|
267
265
|
|
268
266
|
attrs.each do |k, v|
|
@@ -277,7 +275,8 @@ module Skylight
|
|
277
275
|
def self.load(opts = {}, env = ENV)
|
278
276
|
attrs = {}
|
279
277
|
path = opts.delete(:file)
|
280
|
-
|
278
|
+
priority_key = opts.delete(:priority_key)
|
279
|
+
priority_key ||= opts[:env] # if a priority_key is not given, use env if available
|
281
280
|
|
282
281
|
if path
|
283
282
|
error = nil
|
@@ -295,11 +294,14 @@ module Skylight
|
|
295
294
|
raise ConfigError, "could not load config file; msg=#{error}" if error
|
296
295
|
end
|
297
296
|
|
297
|
+
# The key-value pairs in this `priority` option are inserted into the
|
298
|
+
# config's @priority hash *after* anything listed under priority_key;
|
299
|
+
# i.e., ENV takes precendence over priority_key
|
298
300
|
if env
|
299
301
|
attrs[:priority] = remap_env(env)
|
300
302
|
end
|
301
303
|
|
302
|
-
config = new(
|
304
|
+
config = new(priority_key, attrs)
|
303
305
|
|
304
306
|
opts.each do |k, v|
|
305
307
|
config[k] = v
|
@@ -439,7 +441,7 @@ module Skylight
|
|
439
441
|
end
|
440
442
|
end
|
441
443
|
|
442
|
-
if @
|
444
|
+
if @priority_regexp && k =~ @priority_regexp
|
443
445
|
@priority[$1.to_sym] = val
|
444
446
|
end
|
445
447
|
|
@@ -586,7 +588,7 @@ module Skylight
|
|
586
588
|
end
|
587
589
|
end
|
588
590
|
|
589
|
-
attr_writer :logger
|
591
|
+
attr_writer :logger, :alert_logger
|
590
592
|
|
591
593
|
def alert_logger
|
592
594
|
@alert_logger ||= MUTEX.synchronize do
|
@@ -601,8 +603,6 @@ module Skylight
|
|
601
603
|
end
|
602
604
|
end
|
603
605
|
|
604
|
-
attr_writer :alert_logger
|
605
|
-
|
606
606
|
def enable_segments?
|
607
607
|
!!get(:enable_segments)
|
608
608
|
end
|
@@ -638,13 +638,13 @@ module Skylight
|
|
638
638
|
|
639
639
|
Logger.new(out, progname: "Skylight", level: level)
|
640
640
|
rescue
|
641
|
-
Logger.new(
|
641
|
+
Logger.new($stdout, progname: "Skylight", level: level)
|
642
642
|
end
|
643
643
|
|
644
644
|
def load_logger
|
645
645
|
unless (l = @logger)
|
646
646
|
out = get(:log_file)
|
647
|
-
out =
|
647
|
+
out = $stdout if out == "-"
|
648
648
|
l = create_logger(out, level: log_level)
|
649
649
|
end
|
650
650
|
|
@@ -700,7 +700,7 @@ module Skylight
|
|
700
700
|
|
701
701
|
# This is a weird way to handle priorities
|
702
702
|
# See https://github.com/tildeio/direwolf-agent/issues/275
|
703
|
-
k = "#{
|
703
|
+
k = "#{priority_key}.#{k}" if priority_key
|
704
704
|
|
705
705
|
set(k, v)
|
706
706
|
end
|
data/lib/skylight/deprecation.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/deprecation"
|
2
4
|
|
3
5
|
module Skylight
|
4
|
-
SKYLIGHT_GEM_ROOT = File.expand_path(
|
6
|
+
SKYLIGHT_GEM_ROOT = "#{File.expand_path('../..', __dir__)}/"
|
5
7
|
|
6
8
|
class Deprecation < ActiveSupport::Deprecation
|
7
9
|
private
|
data/lib/skylight/extensions.rb
CHANGED
@@ -32,6 +32,12 @@ module Skylight
|
|
32
32
|
!!extensions.detect { |x| x.is_a?(ext_class) }
|
33
33
|
end
|
34
34
|
|
35
|
+
def process_trace_meta(meta)
|
36
|
+
extensions.each do |ext|
|
37
|
+
ext.process_trace_meta(meta)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
35
41
|
# meta is a mutable hash that will be passed to the instrumenter.
|
36
42
|
# This method bridges Skylight.instrument and instrumenter.instrument.
|
37
43
|
def process_instrument_options(opts, meta)
|
@@ -83,6 +89,8 @@ module Skylight
|
|
83
89
|
@config = config
|
84
90
|
end
|
85
91
|
|
92
|
+
def process_trace_meta(_meta); end
|
93
|
+
|
86
94
|
def process_instrument_options(_opts, _meta); end
|
87
95
|
|
88
96
|
def process_normalizer_meta(_payload, _meta, **opts); end
|
@@ -19,13 +19,29 @@ module Skylight
|
|
19
19
|
gem_require_trie # memoize this at startup
|
20
20
|
end
|
21
21
|
|
22
|
+
def process_trace_meta(meta)
|
23
|
+
unless meta[:source_location] || meta[:source_file]
|
24
|
+
warn "Ignoring source_line without source_file" if meta[:source_line]
|
25
|
+
if (location = find_caller)
|
26
|
+
meta[:source_file] = location.absolute_path
|
27
|
+
meta[:source_line] = location.lineno
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
22
32
|
def process_instrument_options(opts, meta)
|
23
33
|
source_location = opts[:source_location] || opts[:meta]&.[](:source_location)
|
24
34
|
source_file = opts[:source_file] || opts[:meta]&.[](:source_file)
|
25
35
|
source_line = opts[:source_line] || opts[:meta]&.[](:source_line)
|
36
|
+
source_name_hint, const_name, method_name = opts[:source_location_hint] ||
|
37
|
+
opts[:meta]&.[](:source_location_hint)
|
26
38
|
|
27
39
|
if source_location
|
28
40
|
meta[:source_location] = source_location
|
41
|
+
elsif source_name_hint
|
42
|
+
source_location = dispatch_hinted_source_location(source_name_hint, const_name, method_name)
|
43
|
+
meta[:source_file], meta[:source_line] = source_location
|
44
|
+
meta.delete(:source_location_hint) if source_location
|
29
45
|
elsif source_file
|
30
46
|
meta[:source_file] = source_file
|
31
47
|
meta[:source_line] = source_line
|
@@ -41,14 +57,21 @@ module Skylight
|
|
41
57
|
end
|
42
58
|
|
43
59
|
def process_normalizer_meta(payload, meta, **opts)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
60
|
+
if opts[:source_location] && (opts[:source_file] || opts[:source_line])
|
61
|
+
warn "Found both source_location and source_file or source_line in normalizer\n" \
|
62
|
+
" location=#{opts[:source_location]}; file=#{opts[:source_file]}; line=#{opts[:source_line]}"
|
63
|
+
end
|
64
|
+
|
65
|
+
sl =
|
66
|
+
if (source_name, constant_name, method_name = opts[:source_location_hint])
|
67
|
+
dispatch_hinted_source_location(
|
68
|
+
source_name,
|
69
|
+
constant_name,
|
70
|
+
method_name
|
71
|
+
)
|
72
|
+
elsif opts[:source_file]
|
73
|
+
[opts[:source_file], opts[:source_line]]
|
74
|
+
end
|
52
75
|
|
53
76
|
sl ||= source_location(payload, meta, cache_key: opts[:cache_key])
|
54
77
|
|
@@ -91,86 +114,88 @@ module Skylight
|
|
91
114
|
|
92
115
|
protected
|
93
116
|
|
94
|
-
|
95
|
-
|
96
|
-
return unless const_name && method_name
|
117
|
+
def dispatch_hinted_source_location(source_name, const_name, method_name)
|
118
|
+
return unless const_name && method_name
|
97
119
|
|
98
|
-
|
99
|
-
|
120
|
+
instance_method_source_location(const_name, method_name, source_name: source_name)
|
121
|
+
end
|
100
122
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
123
|
+
# from normalizers.rb
|
124
|
+
# Returns an array of file and line
|
125
|
+
def source_location(payload, meta, cache_key: nil)
|
126
|
+
# FIXME: what should precedence be?
|
127
|
+
if meta.is_a?(Hash) && meta[:source_location]
|
128
|
+
meta.delete(:source_location)
|
129
|
+
elsif payload.is_a?(Hash) && payload[:sk_source_location]
|
130
|
+
payload[:sk_source_location]
|
131
|
+
elsif (location = find_caller(cache_key: cache_key))
|
132
|
+
[location.absolute_path, location.lineno]
|
133
|
+
end
|
111
134
|
end
|
112
|
-
end
|
113
135
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
136
|
+
def find_caller(cache_key: nil)
|
137
|
+
if cache_key
|
138
|
+
@caller_cache.fetch(cache_key) { find_caller_inner }
|
139
|
+
else
|
140
|
+
find_caller_inner
|
141
|
+
end
|
119
142
|
end
|
120
|
-
end
|
121
143
|
|
122
|
-
|
123
|
-
|
124
|
-
return false unless path.start_with?(config.root.to_s)
|
125
|
-
# Must not be Bundler's vendor location
|
126
|
-
return false if defined?(Bundler) && path.start_with?(Bundler.bundle_path.to_s)
|
127
|
-
# Must not be Ruby files
|
128
|
-
return false if path.include?("/ruby-#{RUBY_VERSION}/lib/ruby/")
|
144
|
+
def project_path?(path)
|
145
|
+
return false unless path
|
129
146
|
|
130
|
-
|
131
|
-
|
132
|
-
|
147
|
+
# Must be in the project root
|
148
|
+
return false unless path.start_with?(config.root.to_s)
|
149
|
+
# Must not be Bundler's vendor location
|
150
|
+
return false if defined?(Bundler) && path.start_with?(Bundler.bundle_path.to_s)
|
151
|
+
# Must not be Ruby files
|
152
|
+
return false if path.include?("/ruby-#{RUBY_VERSION}/lib/ruby/")
|
133
153
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
154
|
+
# So it must be a project file
|
155
|
+
true
|
156
|
+
end
|
157
|
+
|
158
|
+
def instance_method_source_location(constant_name, method_name, source_name: :instance_method)
|
159
|
+
@instance_method_source_location_cache.fetch([constant_name, method_name, source_name]) do
|
160
|
+
if (constant = ::ActiveSupport::Dependencies.safe_constantize(constant_name))
|
161
|
+
if constant.instance_methods.include?(:"before_instrument_#{method_name}")
|
162
|
+
method_name = :"before_instrument_#{method_name}"
|
163
|
+
end
|
164
|
+
begin
|
165
|
+
unbound_method = case source_name
|
166
|
+
when :instance_method
|
167
|
+
find_instance_method(constant, method_name)
|
168
|
+
when :own_instance_method
|
169
|
+
find_own_instance_method(constant, method_name)
|
170
|
+
when :instance_method_super
|
171
|
+
find_instance_method_super(constant, method_name)
|
172
|
+
when :class_method
|
173
|
+
find_class_method(constant, method_name)
|
174
|
+
end
|
175
|
+
|
176
|
+
unbound_method&.source_location
|
177
|
+
rescue NameError
|
178
|
+
nil
|
179
|
+
end
|
153
180
|
end
|
154
181
|
end
|
155
182
|
end
|
156
|
-
end
|
157
183
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
end
|
184
|
+
def sanitize_source_location(path, line)
|
185
|
+
# Do this first since gems may be vendored in the app repo. However, it might be slower.
|
186
|
+
# Should we cache matches?
|
187
|
+
if (gem_name = find_source_gem(path))
|
188
|
+
path = gem_name
|
189
|
+
line = nil
|
190
|
+
elsif project_path?(path)
|
191
|
+
# Get relative path to root
|
192
|
+
path = Pathname.new(path).relative_path_from(config.root).to_s
|
193
|
+
else
|
194
|
+
return
|
195
|
+
end
|
171
196
|
|
172
|
-
|
173
|
-
|
197
|
+
line ? "#{path}:#{line}" : path
|
198
|
+
end
|
174
199
|
|
175
200
|
private
|
176
201
|
|
@@ -198,11 +223,13 @@ module Skylight
|
|
198
223
|
end
|
199
224
|
|
200
225
|
def find_source_gem(path)
|
226
|
+
return nil unless path
|
227
|
+
|
201
228
|
trie = gem_require_trie
|
202
229
|
|
203
230
|
path.split(File::SEPARATOR).each do |segment|
|
204
231
|
trie = trie[segment]
|
205
|
-
|
232
|
+
break unless trie
|
206
233
|
return trie[:name] if trie[:name]
|
207
234
|
end
|
208
235
|
|
@@ -211,6 +238,7 @@ module Skylight
|
|
211
238
|
|
212
239
|
def find_caller_inner
|
213
240
|
# Start at file before this one
|
241
|
+
# NOTE: We could start farther back now to avoid more Skylight files
|
214
242
|
caller_locations(1).find do |l|
|
215
243
|
find_source_gem(l.absolute_path) || project_path?(l.absolute_path)
|
216
244
|
end
|
@@ -244,6 +272,9 @@ module Skylight
|
|
244
272
|
constant.instance_method(method_name)
|
245
273
|
end
|
246
274
|
|
275
|
+
def find_class_method(constant, method_name)
|
276
|
+
constant.method(method_name)
|
277
|
+
end
|
247
278
|
end
|
248
279
|
end
|
249
280
|
end
|
@@ -60,8 +60,6 @@ module Skylight
|
|
60
60
|
@trace_info = @config[:trace_info] || TraceInfo.new(KEY)
|
61
61
|
@mutex = Mutex.new
|
62
62
|
@extensions = Skylight::Extensions::Collection.new(@config)
|
63
|
-
|
64
|
-
enable_extension!(:source_location) if @config.enable_source_locations?
|
65
63
|
end
|
66
64
|
|
67
65
|
def enable_extension!(name)
|
@@ -176,6 +174,7 @@ module Skylight
|
|
176
174
|
return
|
177
175
|
end
|
178
176
|
|
177
|
+
enable_extension!(:source_location) if @config.enable_source_locations?
|
179
178
|
config.gc.enable
|
180
179
|
@subscriber.register!
|
181
180
|
|
@@ -202,6 +201,8 @@ module Skylight
|
|
202
201
|
end
|
203
202
|
|
204
203
|
begin
|
204
|
+
meta ||= {}
|
205
|
+
extensions.process_trace_meta(meta)
|
205
206
|
trace = Trace.new(self, endpoint, Skylight::Util::Clock.nanos, cat, title, desc,
|
206
207
|
meta: meta, segment: segment, component: component)
|
207
208
|
rescue Exception => e
|
data/lib/skylight/middleware.rb
CHANGED
@@ -10,10 +10,10 @@ module Skylight
|
|
10
10
|
@closed = false
|
11
11
|
end
|
12
12
|
|
13
|
-
def respond_to_missing?(
|
14
|
-
return false if
|
13
|
+
def respond_to_missing?(name, include_all = false) # rubocop:disable Lint/MissingSuper, Style/OptionalBooleanParameter
|
14
|
+
return false if name.to_s !~ /^to_ary$/
|
15
15
|
|
16
|
-
@body.respond_to?(
|
16
|
+
@body.respond_to?(name, include_all)
|
17
17
|
end
|
18
18
|
|
19
19
|
def close
|
@@ -117,7 +117,7 @@ module Skylight
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def endpoint_meta(_env)
|
120
|
-
|
120
|
+
{ source_location: Trace::SYNTHETIC }
|
121
121
|
end
|
122
122
|
|
123
123
|
# Request ID code based on ActionDispatch::RequestId
|
@@ -23,7 +23,7 @@ module Skylight
|
|
23
23
|
# @param opts [Hash]
|
24
24
|
def self.fetch(**args)
|
25
25
|
args[:source] ||= BASE_URL
|
26
|
-
args[:logger] ||= Logger.new(
|
26
|
+
args[:logger] ||= Logger.new($stdout)
|
27
27
|
new(**args).fetch
|
28
28
|
end
|
29
29
|
|
@@ -35,7 +35,7 @@ module Skylight
|
|
35
35
|
# @param required [Boolean] whether the download is required to be successful
|
36
36
|
# @param platform
|
37
37
|
# @param log [Logger]
|
38
|
-
def initialize(source:, target:, version:, checksum:, arch:, required: false, platform: nil
|
38
|
+
def initialize(source:, target:, version:, checksum:, arch:, logger:, required: false, platform: nil)
|
39
39
|
raise "source required" unless source
|
40
40
|
raise "target required" unless target
|
41
41
|
raise "checksum required" unless checksum
|
data/lib/skylight/normalizers.rb
CHANGED
@@ -20,7 +20,7 @@ module Skylight
|
|
20
20
|
matches = registry.select { |n, _| n =~ /(^|\.)#{name}$/ }
|
21
21
|
raise ArgumentError, "no normalizers match #{name}" if matches.empty?
|
22
22
|
|
23
|
-
matches.
|
23
|
+
matches.each_value { |v| v[1] = enabled }
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -78,7 +78,7 @@ module Skylight
|
|
78
78
|
|
79
79
|
private
|
80
80
|
|
81
|
-
def process_meta(trace,
|
81
|
+
def process_meta(trace, _name, payload, meta, cache_key: nil)
|
82
82
|
trace.instrumenter.extensions.process_normalizer_meta(
|
83
83
|
payload,
|
84
84
|
meta,
|
@@ -38,7 +38,7 @@ module Skylight
|
|
38
38
|
|
39
39
|
def process_meta_options(payload)
|
40
40
|
# provide hints to override default source_location behavior
|
41
|
-
super.merge(
|
41
|
+
super.merge(source_location_hint: [:instance_method, payload[:controller], payload[:action]])
|
42
42
|
end
|
43
43
|
|
44
44
|
def segment_from_payload(payload)
|
@@ -19,7 +19,7 @@ module Skylight
|
|
19
19
|
|
20
20
|
def process_meta_options(_payload)
|
21
21
|
# provide hints to override default source_location behavior
|
22
|
-
super.merge(
|
22
|
+
super.merge(source_location_hint: [:own_instance_method, router_class_name, "call"])
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -36,6 +36,11 @@ module Skylight
|
|
36
36
|
|
37
37
|
private
|
38
38
|
|
39
|
+
def process_meta_options(payload)
|
40
|
+
# provide hints to override default source_location behavior
|
41
|
+
super.merge(source_location_hint: [:instance_method, payload[:job].class.to_s, "perform"])
|
42
|
+
end
|
43
|
+
|
39
44
|
def normalize_adapter_name(adapter)
|
40
45
|
adapter_string = adapter.is_a?(Class) ? adapter.to_s : adapter.class.to_s
|
41
46
|
adapter_string[/ActiveJob::QueueAdapters::(\w+)Adapter/, 1].underscore
|
@@ -40,7 +40,7 @@ module Skylight
|
|
40
40
|
# Matches a Gem Version or 12-digit hex (sha)
|
41
41
|
# that is preceeded by a `-` and followed by `/`
|
42
42
|
# Also matches 'app/views/' if it exists
|
43
|
-
%r{-(?:#{Gem::Version::VERSION_PATTERN}|[0-9a-f]{12})
|
43
|
+
%r{-(?:#{Gem::Version::VERSION_PATTERN}|[0-9a-f]{12})/(?:app/views/)*},
|
44
44
|
": ".freeze
|
45
45
|
)
|
46
46
|
else
|
@@ -14,7 +14,7 @@ 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(
|
17
|
+
def normalize(_trace, name, payload)
|
18
18
|
case payload[:name]
|
19
19
|
when "SCHEMA", "CACHE"
|
20
20
|
return :skip
|
@@ -29,7 +29,8 @@ module Skylight
|
|
29
29
|
|
30
30
|
unless sql.valid_encoding?
|
31
31
|
if config[:log_sql_parse_errors]
|
32
|
-
config.logger.error "[#{Skylight::SqlLexError.formatted_code}] Unable to extract binds from non-UTF-8
|
32
|
+
config.logger.error "[#{Skylight::SqlLexError.formatted_code}] Unable to extract binds from non-UTF-8 " \
|
33
|
+
"query. " \
|
33
34
|
"encoding=#{payload[:sql].encoding.name} " \
|
34
35
|
"sql=#{payload[:sql].inspect} "
|
35
36
|
end
|
data/lib/skylight/probes.rb
CHANGED
@@ -16,11 +16,41 @@ module Skylight
|
|
16
16
|
|
17
17
|
def install
|
18
18
|
probe.install
|
19
|
+
rescue StandardError, LoadError => e
|
20
|
+
log_install_exception(e)
|
19
21
|
end
|
20
22
|
|
21
23
|
def constant_available?
|
22
24
|
Skylight::Probes.constant_available?(const_name)
|
23
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def log_install_exception(err)
|
30
|
+
description = err.class.to_s
|
31
|
+
description << ": #{err.message}" unless err.message.empty?
|
32
|
+
|
33
|
+
backtrace = err.backtrace.map { |l| " #{l}" }.join("\n")
|
34
|
+
|
35
|
+
gems =
|
36
|
+
begin
|
37
|
+
Bundler.locked_gems.dependencies.map { |d| [d.name, d.requirement.to_s] }
|
38
|
+
rescue # rubocop:disable Lint/SuppressedException
|
39
|
+
end
|
40
|
+
|
41
|
+
error = "[SKYLIGHT] [#{Skylight::VERSION}] Encountered an error while installing the " \
|
42
|
+
"probe for #{const_name}. Please notify support@skylight.io with the debugging " \
|
43
|
+
"information below. It's recommended that you disable this probe until the " \
|
44
|
+
"issue is resolved." \
|
45
|
+
"\n\nERROR: #{description}\n\n#{backtrace}\n\n"
|
46
|
+
|
47
|
+
if gems
|
48
|
+
gems_string = gems.map { |g| " #{g[0]} #{g[1]}" }.join("\n")
|
49
|
+
error << "GEMS:\n\n#{gems_string}\n\n"
|
50
|
+
end
|
51
|
+
|
52
|
+
$stderr.puts(error)
|
53
|
+
end
|
24
54
|
end
|
25
55
|
|
26
56
|
class << self
|
@@ -99,12 +129,12 @@ module Skylight
|
|
99
129
|
def require_hook(require_path)
|
100
130
|
each_by_require_path(require_path) do |registration|
|
101
131
|
# Double check constant is available
|
102
|
-
|
103
|
-
install_probe(registration)
|
132
|
+
next unless registration.constant_available?
|
104
133
|
|
105
|
-
|
106
|
-
|
107
|
-
|
134
|
+
install_probe(registration)
|
135
|
+
|
136
|
+
# Don't need this to be called again
|
137
|
+
unregister_require_hook(registration)
|
108
138
|
end
|
109
139
|
end
|
110
140
|
|
@@ -143,11 +173,9 @@ module Kernel
|
|
143
173
|
|
144
174
|
def require(name)
|
145
175
|
require_without_sk(name).tap do
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
warn("[SKYLIGHT] Rescued exception in require hook", e)
|
150
|
-
end
|
176
|
+
Skylight::Probes.require_hook(name)
|
177
|
+
rescue Exception => e
|
178
|
+
warn("[SKYLIGHT] Rescued exception in require hook", e)
|
151
179
|
end
|
152
180
|
end
|
153
181
|
end
|
@@ -7,12 +7,10 @@ module Skylight
|
|
7
7
|
def execute(*)
|
8
8
|
Skylight.trace(TITLE, "app.job.execute", component: :worker) do |trace|
|
9
9
|
# See normalizers/active_job/perform for endpoint/segment assignment
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
raise
|
15
|
-
end
|
10
|
+
super
|
11
|
+
rescue Exception
|
12
|
+
trace.segment = "error" if trace
|
13
|
+
raise
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -6,21 +6,19 @@ module Skylight
|
|
6
6
|
|
7
7
|
def install
|
8
8
|
::ActiveJob::Base.around_enqueue do |job, block|
|
9
|
-
|
10
|
-
|
11
|
-
adapter_name = EnqueueProbe.normalize_adapter_name(job_class)
|
9
|
+
job_class = job.class
|
10
|
+
adapter_name = EnqueueProbe.normalize_adapter_name(job_class)
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
12
|
+
# If this is an ActionMailer::DeliveryJob, we'll report this as the mailer title
|
13
|
+
# and include ActionMailer::DeliveryJob in the description.
|
14
|
+
name, job_class_name = Normalizers::ActiveJob::Perform.normalize_title(job)
|
15
|
+
descriptors = ["adapter: '#{adapter_name}'", "queue: '#{job.queue_name}'"]
|
16
|
+
descriptors << "job: '#{job_class_name}'" if job_class_name
|
17
|
+
desc = "{ #{descriptors.join(', ')} }"
|
18
|
+
rescue
|
19
|
+
block.call
|
20
|
+
else
|
21
|
+
Skylight.instrument(title: "Enqueue #{name}", category: CAT, description: desc, &block)
|
24
22
|
end
|
25
23
|
|
26
24
|
self.class.instance_eval do
|
@@ -14,12 +14,8 @@ module Skylight
|
|
14
14
|
|
15
15
|
# File moved location between version
|
16
16
|
%w[serializer serializers].each do |dir|
|
17
|
-
|
18
|
-
|
19
|
-
require "active_model/#{dir}/version"
|
20
|
-
rescue LoadError
|
21
|
-
end
|
22
|
-
# rubocop:enable Lint/SuppressedException
|
17
|
+
require "active_model/#{dir}/version"
|
18
|
+
rescue LoadError # rubocop:disable Lint/SuppressedException
|
23
19
|
end
|
24
20
|
|
25
21
|
if Gem.loaded_specs["active_model_serializers"]
|
@@ -1,46 +1,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "delegate"
|
4
|
+
|
1
5
|
module Skylight
|
2
6
|
module Probes
|
3
7
|
module DelayedJob
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
begin
|
12
|
-
if defined?(::Delayed::PerformableMethod) && job.payload_object.is_a?(::Delayed::PerformableMethod)
|
13
|
-
job.name
|
14
|
-
else
|
15
|
-
job.payload_object.class.name
|
16
|
-
end
|
17
|
-
rescue
|
18
|
-
UNKNOWN
|
8
|
+
begin
|
9
|
+
require "delayed/plugin"
|
10
|
+
|
11
|
+
class Plugin < ::Delayed::Plugin
|
12
|
+
callbacks do |lifecycle|
|
13
|
+
lifecycle.around(:perform) do |worker, job, &block|
|
14
|
+
sk_instrument(worker, job, &block)
|
19
15
|
end
|
20
16
|
|
21
|
-
|
22
|
-
|
17
|
+
lifecycle.after(:error) do |_worker, _job|
|
18
|
+
Skylight.trace&.segment = "error"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
include Skylight::Util::Logging
|
24
|
+
|
25
|
+
def sk_instrument(_worker, job)
|
26
|
+
endpoint = Skylight::Probes::DelayedJob.handler_name(job)
|
27
|
+
|
28
|
+
Skylight.trace(endpoint,
|
29
|
+
"app.delayed_job.worker",
|
30
|
+
"Delayed::Worker#run",
|
31
|
+
component: :worker,
|
32
|
+
segment: job.queue,
|
33
|
+
meta: { source_location: "delayed_job" }) do
|
34
|
+
t { "Delayed::Job beginning trace" }
|
35
|
+
yield
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
23
39
|
end
|
40
|
+
rescue LoadError
|
41
|
+
$stderr.puts "[SKYLIGHT] The delayed_job probe was requested, but Delayed::Plugin was not defined."
|
42
|
+
end
|
43
|
+
|
44
|
+
UNKNOWN = "<Delayed::Job Unknown>"
|
24
45
|
|
25
|
-
|
26
|
-
|
27
|
-
|
46
|
+
def self.handler_name(job)
|
47
|
+
payload_object = if job.respond_to?(:payload_object_without_sk)
|
48
|
+
job.payload_object_without_sk
|
49
|
+
else
|
50
|
+
job.payload_object
|
51
|
+
end
|
52
|
+
|
53
|
+
payload_object_name(payload_object)
|
54
|
+
end
|
28
55
|
|
29
|
-
|
56
|
+
def self.payload_object_name(payload_object)
|
57
|
+
if payload_object.is_a?(::Delayed::PerformableMethod)
|
58
|
+
payload_object.display_name
|
59
|
+
else
|
60
|
+
# In the case of ActiveJob-wrapped jobs, there is quite a bit of job-specific metadata
|
61
|
+
# in `job.name`, which would break aggregation and potentially leak private data in job args.
|
62
|
+
# Use class name instead to avoid this.
|
63
|
+
payload_object.class.name
|
30
64
|
end
|
65
|
+
rescue
|
66
|
+
UNKNOWN
|
31
67
|
end
|
32
68
|
|
33
|
-
|
34
|
-
|
69
|
+
def self.payload_object_source_meta(payload_object)
|
70
|
+
if payload_object.is_a?(::Delayed::PerformableMethod)
|
71
|
+
if payload_object.object.is_a?(Module)
|
72
|
+
[:class_method, payload_object.object.name, payload_object.method_name.to_s]
|
73
|
+
else
|
74
|
+
[:instance_method, payload_object.object.class.name, payload_object.method_name.to_s]
|
75
|
+
end
|
76
|
+
else
|
77
|
+
[:instance_method, payload_object.class.name, "perform"]
|
78
|
+
end
|
79
|
+
end
|
35
80
|
|
81
|
+
class InstrumentationProxy < SimpleDelegator
|
82
|
+
def perform
|
83
|
+
source_meta = Skylight::Probes::DelayedJob.payload_object_source_meta(__getobj__)
|
84
|
+
|
85
|
+
opts = {
|
86
|
+
category: "app.delayed_job.job",
|
87
|
+
title: format_source(*source_meta),
|
88
|
+
meta: { source_location_hint: source_meta }
|
89
|
+
}
|
90
|
+
|
91
|
+
Skylight.instrument(opts) { __getobj__.perform }
|
92
|
+
end
|
93
|
+
|
94
|
+
# Used by Delayed::Backend::Base to determine Job#name
|
95
|
+
def display_name
|
96
|
+
__getobj__.respond_to?(:display_name) ? __getobj__.display_name : __getobj__.class.name
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def format_source(method_type, constant_name, method_name)
|
102
|
+
if method_type == :instance_method
|
103
|
+
"#{constant_name}##{method_name}"
|
104
|
+
else
|
105
|
+
"#{constant_name}.#{method_name}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Probe
|
36
111
|
def install
|
37
|
-
return unless validate_version
|
112
|
+
return unless validate_version && plugin_defined?
|
113
|
+
|
114
|
+
::Delayed::Worker.plugins = [Skylight::Probes::DelayedJob::Plugin] | ::Delayed::Worker.plugins
|
115
|
+
::Delayed::Backend::Base.class_eval do
|
116
|
+
alias_method :payload_object_without_sk, :payload_object
|
38
117
|
|
39
|
-
|
118
|
+
def payload_object
|
119
|
+
Skylight::Probes::DelayedJob::InstrumentationProxy.new(payload_object_without_sk)
|
120
|
+
end
|
121
|
+
end
|
40
122
|
end
|
41
123
|
|
42
124
|
private
|
43
125
|
|
126
|
+
def plugin_defined?
|
127
|
+
defined?(::Skylight::Probes::DelayedJob::Plugin)
|
128
|
+
end
|
129
|
+
|
44
130
|
def validate_version
|
45
131
|
spec = Gem.loaded_specs["delayed_job"]
|
46
132
|
version = spec&.version
|
@@ -72,7 +72,8 @@ module Skylight
|
|
72
72
|
|
73
73
|
source_file, source_line = method(__method__).super_method.source_location
|
74
74
|
|
75
|
-
spans = Skylight.instrument(title: name, category: __sk_category,
|
75
|
+
spans = Skylight.instrument(title: name, category: __sk_category,
|
76
|
+
source_file: source_file, source_line: source_line)
|
76
77
|
|
77
78
|
proxied_response =
|
78
79
|
Skylight::Middleware.with_after_close(super(*args), debug_identifier: "Middleware: #{name}") do
|
data/lib/skylight/railtie.rb
CHANGED
data/lib/skylight/sidekiq.rb
CHANGED
@@ -19,16 +19,21 @@ module Skylight
|
|
19
19
|
class ServerMiddleware
|
20
20
|
include Util::Logging
|
21
21
|
|
22
|
-
def call(
|
22
|
+
def call(worker, job, queue)
|
23
23
|
t { "Sidekiq middleware beginning trace" }
|
24
24
|
title = job["wrapped"] || job["class"]
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
raise
|
25
|
+
|
26
|
+
# TODO: Using hints here would be ideal but requires further refactoring
|
27
|
+
meta =
|
28
|
+
if (source_location = worker.method(:perform).source_location)
|
29
|
+
{ source_file: source_location[0], source_line: source_location[1] }
|
31
30
|
end
|
31
|
+
|
32
|
+
Skylight.trace(title, "app.sidekiq.worker", title, meta: meta, segment: queue, component: :worker) do |trace|
|
33
|
+
yield
|
34
|
+
rescue Exception # includes Sidekiq::Shutdown
|
35
|
+
trace.segment = "error" if trace
|
36
|
+
raise
|
32
37
|
end
|
33
38
|
end
|
34
39
|
end
|
data/lib/skylight/subscriber.rb
CHANGED
data/lib/skylight/trace.rb
CHANGED
@@ -4,6 +4,7 @@ require "skylight/util/logging"
|
|
4
4
|
module Skylight
|
5
5
|
class Trace
|
6
6
|
GC_CAT = "noise.gc".freeze
|
7
|
+
SYNTHETIC = "<synthetic>".freeze
|
7
8
|
|
8
9
|
META_KEYS = %i[mute_children].freeze
|
9
10
|
|
@@ -39,6 +40,8 @@ module Skylight
|
|
39
40
|
|
40
41
|
@spans = []
|
41
42
|
|
43
|
+
preprocess_meta(meta) if meta
|
44
|
+
|
42
45
|
# create the root node
|
43
46
|
@root = start(native_get_started_at, cat, title, desc, meta, normalize: false)
|
44
47
|
|
@@ -217,7 +220,8 @@ module Skylight
|
|
217
220
|
|
218
221
|
if time > 0
|
219
222
|
t { fmt "tracking GC time; duration=%d", time }
|
220
|
-
|
223
|
+
meta = { source_location: SYNTHETIC }
|
224
|
+
stop(start(now - time, GC_CAT, nil, nil, meta), now)
|
221
225
|
end
|
222
226
|
end
|
223
227
|
|
data/lib/skylight/util/deploy.rb
CHANGED
@@ -13,8 +13,7 @@ module Skylight
|
|
13
13
|
end
|
14
14
|
|
15
15
|
class EmptyDeploy
|
16
|
-
attr_reader :config
|
17
|
-
attr_reader :timestamp
|
16
|
+
attr_reader :config, :timestamp
|
18
17
|
|
19
18
|
def initialize(config)
|
20
19
|
@config = config
|
@@ -90,10 +89,8 @@ module Skylight
|
|
90
89
|
def get_info
|
91
90
|
info_path = config[:'heroku.dyno_info_path']
|
92
91
|
|
93
|
-
if File.exist?(info_path)
|
94
|
-
|
95
|
-
info["release"]
|
96
|
-
end
|
92
|
+
if File.exist?(info_path) && (info = JSON.parse(File.read(info_path)))
|
93
|
+
info["release"]
|
97
94
|
end
|
98
95
|
end
|
99
96
|
end
|
data/lib/skylight/util/http.rb
CHANGED
@@ -192,7 +192,7 @@ module Skylight
|
|
192
192
|
body.dig(*key.split(".")) if body.is_a?(Hash)
|
193
193
|
end
|
194
194
|
|
195
|
-
def respond_to_missing?(name, include_all = false)
|
195
|
+
def respond_to_missing?(name, include_all = false) # rubocop:disable Style/OptionalBooleanParameter
|
196
196
|
super || body.respond_to?(name, include_all)
|
197
197
|
end
|
198
198
|
|
@@ -9,12 +9,12 @@ module Skylight
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def write(*args)
|
12
|
-
|
12
|
+
$stderr.write(*args)
|
13
13
|
|
14
14
|
# Try to avoid writing to STDOUT/STDERR twice
|
15
15
|
logger_logdev = @logger.instance_variable_get(:@logdev)
|
16
16
|
logger_out = logger_logdev&.respond_to?(:dev) ? logger_logdev.dev : nil
|
17
|
-
if logger_out !=
|
17
|
+
if logger_out != $stdout && logger_out != $stderr
|
18
18
|
@logger.<<(*args)
|
19
19
|
end
|
20
20
|
end
|
data/lib/skylight/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skylight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.0.
|
4
|
+
version: 5.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tilde, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -86,28 +86,28 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: 13.0.1
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 13.0.1
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rake-compiler
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 1.
|
103
|
+
version: 1.1.1
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: 1.
|
110
|
+
version: 1.1.1
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: rspec
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -211,7 +211,6 @@ files:
|
|
211
211
|
- lib/skylight/errors.rb
|
212
212
|
- lib/skylight/extensions.rb
|
213
213
|
- lib/skylight/extensions/source_location.rb
|
214
|
-
- lib/skylight/fanout.rb
|
215
214
|
- lib/skylight/formatters/http.rb
|
216
215
|
- lib/skylight/gc.rb
|
217
216
|
- lib/skylight/helpers.rb
|
@@ -361,7 +360,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
361
360
|
requirements:
|
362
361
|
- - ">="
|
363
362
|
- !ruby/object:Gem::Version
|
364
|
-
version: '2.
|
363
|
+
version: '2.5'
|
365
364
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
366
365
|
requirements:
|
367
366
|
- - ">"
|
data/lib/skylight/fanout.rb
DELETED
File without changes
|