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