skylight 5.2.0 → 5.3.0

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