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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc19196b2920db75b79fae6c65192174b3493387acf49ac77a6217b3790ba04e
4
- data.tar.gz: da0c089c1fbc0531e9a8f1753e64cfdd79792edb50c36778e4862d0b27598c21
3
+ metadata.gz: ab247cb921b7d63dec0fc2fd7c6987a862986953f06765ae3472f59fb3c5ccbd
4
+ data.tar.gz: da9348e64a843ee5547808ead23c14b904d61c18431eebbf60e8aa36f41db2ef
5
5
  SHA512:
6
- metadata.gz: 426d918a456c5c47442534b3c7f51d2f36d05425077930b167383954fcea702d3be0abdf67acada63a1272dbcfe31c7632ac24c1dc8ffb579a7ca431f43b6412
7
- data.tar.gz: 31c169c52f43217b53d361b18327311915ad70b09bdb35354816eec1ed3b341611cb02f0bd40566a9641122e8d75974d487ecb43eb8ee1086b1e132fda37fd14
6
+ metadata.gz: db622c8b9bcada4c1806d4891632587510e4ee06bee1ddc265d29bbf816aef404e403a8b5e1aa584342f1867089aba945de6de3dd3d8c13d38c97e3fce526be9
7
+ data.tar.gz: 79445c8d91cda531854c1e7ae9799be4b78e921fe7c4588a1bc4e1c5292546d34ac237c35d973759e9a6bc071bbe7fcd567079c71d8c462d76e93ba0becdf684
data/CHANGELOG.md CHANGED
@@ -1,11 +1,17 @@
1
- ## 5.2.0
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] fix native extension configuration for arm64 hosts
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)
@@ -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("../../ext/install.log", __dir__)
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
@@ -36,7 +36,7 @@ module Skylight
36
36
  end
37
37
  end
38
38
 
39
- attr_reader :uuid, :config, :gc, :extensions
39
+ attr_reader :uuid, :config, :gc, :extensions, :subscriber
40
40
 
41
41
  def self.native_new(_uuid, _config_env)
42
42
  raise "not implemented"
@@ -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, name, payload)
18
- case payload[:name]
19
- when "SCHEMA", "CACHE"
20
- return :skip
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
- [name, title, sql]
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
@@ -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[net_http action_controller action_dispatch action_view middleware active_job_enqueue]
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 }`
@@ -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 = @instrumenter.current_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 = @instrumenter.current_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
@@ -3,5 +3,5 @@ module Skylight
3
3
  # for compatibility with semver when it is parsed by the rust agent.
4
4
  # This string will be transformed in the gemspec to "5.0.0.alpha"
5
5
  # to conform with rubygems.
6
- VERSION = "5.2.0".freeze
6
+ VERSION = "5.3.0".freeze
7
7
  end
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.2.0
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-03 00:00:00.000000000 Z
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