skylight 5.2.0 → 5.3.0
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 +8 -2
- data/ext/extconf.rb +16 -0
- data/lib/skylight/cli/doctor.rb +1 -1
- data/lib/skylight/instrumenter.rb +1 -1
- data/lib/skylight/normalizers/active_record/sql.rb +8 -0
- data/lib/skylight/normalizers/sql.rb +5 -9
- data/lib/skylight/probes/active_record_async.rb +96 -0
- data/lib/skylight/railtie.rb +9 -1
- data/lib/skylight/subscriber.rb +24 -2
- data/lib/skylight/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab247cb921b7d63dec0fc2fd7c6987a862986953f06765ae3472f59fb3c5ccbd
|
4
|
+
data.tar.gz: da9348e64a843ee5547808ead23c14b904d61c18431eebbf60e8aa36f41db2ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db622c8b9bcada4c1806d4891632587510e4ee06bee1ddc265d29bbf816aef404e403a8b5e1aa584342f1867089aba945de6de3dd3d8c13d38c97e3fce526be9
|
7
|
+
data.tar.gz: 79445c8d91cda531854c1e7ae9799be4b78e921fe7c4588a1bc4e1c5292546d34ac237c35d973759e9a6bc071bbe7fcd567079c71d8c462d76e93ba0becdf684
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,17 @@
|
|
1
|
-
## 5.
|
1
|
+
## 5.3.0 (February, 9, 2022)
|
2
|
+
|
3
|
+
- [FEATURE] Support for Rails 7's `load_async`.
|
4
|
+
- [IMPROVEMENT] `skylight doctor` now checks glibc compatibility.
|
5
|
+
- [BUGFIX] Fix an issue where `skylight doctor` wouldn't correctly log installation errors.
|
6
|
+
|
7
|
+
## 5.2.0 (February 3, 2022)
|
2
8
|
|
3
9
|
- [FEATURE] Experimental gRPC transport
|
4
10
|
- [IMPROVEMENT] Internal native client refactors
|
5
11
|
- [IMPROVEMENT] Add Rack::Builder probe to better instrument middlewares in Sinatra and other Builder-based apps
|
6
12
|
- [BUGFIX] Fix some internal errors related to Rails 7
|
7
13
|
- [BUGFIX] Fix an issue in which trace logging could output the incorrect request ID.
|
8
|
-
- [BUGFIX]
|
14
|
+
- [BUGFIX] Fix native extension configuration for arm64 hosts
|
9
15
|
|
10
16
|
## 5.1.1 (May 27, 2021)
|
11
17
|
|
data/ext/extconf.rb
CHANGED
@@ -9,6 +9,22 @@ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
|
9
9
|
require "skylight/native_ext_fetcher"
|
10
10
|
require "skylight/util/platform"
|
11
11
|
|
12
|
+
GLIBC_MIN = 2.23
|
13
|
+
GLIBC_V4_MIN = 2.15
|
14
|
+
|
15
|
+
ldd_output =
|
16
|
+
begin
|
17
|
+
`ldd --version`
|
18
|
+
rescue Errno::ENOENT
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
if ldd_output =~ /GLIBC (\d+(\.\d+)+)/ && ($1.to_f < GLIBC_MIN)
|
23
|
+
message = "glibc #{GLIBC_MIN}+ is required but you have #{$1} installed."
|
24
|
+
message << "\nYou may be able to use Skylight v4 instead." if $1.to_f >= GLIBC_V4_MIN
|
25
|
+
fail message
|
26
|
+
end
|
27
|
+
|
12
28
|
# Util allowing proxying writes to multiple location
|
13
29
|
class MultiIO
|
14
30
|
def initialize(*targets)
|
data/lib/skylight/cli/doctor.rb
CHANGED
@@ -65,7 +65,7 @@ module Skylight
|
|
65
65
|
say "Unable to load native extension", :yellow
|
66
66
|
|
67
67
|
indent do
|
68
|
-
install_log = File.expand_path("
|
68
|
+
install_log = File.expand_path("../../../ext/install.log", __dir__)
|
69
69
|
if File.exist?(install_log)
|
70
70
|
File.readlines(install_log).each { |line| say line, :red }
|
71
71
|
else
|
@@ -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
|
@@ -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
|
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 }`
|
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/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.
|
4
|
+
version: 5.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tilde, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -285,6 +285,7 @@ files:
|
|
285
285
|
- lib/skylight/probes/active_job.rb
|
286
286
|
- lib/skylight/probes/active_job_enqueue.rb
|
287
287
|
- lib/skylight/probes/active_model_serializers.rb
|
288
|
+
- lib/skylight/probes/active_record_async.rb
|
288
289
|
- lib/skylight/probes/delayed_job.rb
|
289
290
|
- lib/skylight/probes/elasticsearch.rb
|
290
291
|
- lib/skylight/probes/excon.rb
|