active_record_query_counter 2.0.0 → 2.2.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 +17 -0
- data/README.md +12 -0
- data/VERSION +1 -1
- data/active_record_query_counter.gemspec +1 -1
- data/lib/active_record_query_counter/connection_adapter_extension.rb +31 -7
- data/lib/active_record_query_counter/counter.rb +14 -1
- data/lib/active_record_query_counter/thresholds.rb +4 -0
- data/lib/active_record_query_counter/transaction_manager_extension.rb +8 -0
- data/lib/active_record_query_counter.rb +35 -6
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00cf8b2bba420e0b37944a53f4be128aeac846d6e387b15b03c3393f3a0030c2
|
4
|
+
data.tar.gz: 10c05613e25513f1afab756f9cdd1133a19f7b54e34ca811b7f3ba5ad982ff0e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4294aac8c3b0b55197ba1d069cc0a57f269ad772c23480b928fcf3f0a01b7c4f806f4969bf32f2d229b8dea65bc976d18cc864f923ec468dbbb43fc2fbe20bdd
|
7
|
+
data.tar.gz: ffddf3b2d87b74a2ad184d0ec55c4b371cda418c262aa2d0889cf40916579f5bff575ef0e631a39764edd58f7d321b71fa1b993dda6c3ff0c9f1ef060ca02769
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## 2.2.0
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- Added `ActiveRecordQueryCounter.disable` method to allow disabling query counting behavior within a block.
|
12
|
+
- Rails 7.1 compatibility.
|
13
|
+
|
14
|
+
## 2.1.0
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
- Added count of queries that hit the query cache instead of being sent to the database.
|
19
|
+
|
20
|
+
### Removed
|
21
|
+
|
22
|
+
- Dropped support for ActiveRecord 5.0.
|
23
|
+
|
7
24
|
## 2.0.0
|
8
25
|
|
9
26
|
### Added
|
data/README.md
CHANGED
@@ -60,6 +60,18 @@ Sidekiq.configure_server do |config|
|
|
60
60
|
end
|
61
61
|
```
|
62
62
|
|
63
|
+
If you want to disable query counting within a block of code, you can use the `disable` method.
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
ActiveRecordQueryCounter.count_queries do
|
67
|
+
do_something
|
68
|
+
ActiveRecordQueryCounter.disable do
|
69
|
+
# Queries will not be counted in this block.
|
70
|
+
do_something_else
|
71
|
+
end
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
63
75
|
### Notifications
|
64
76
|
|
65
77
|
You can also subscribe to ActiveSupport notifications to get notified when query thresholds are exceeded.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.2.0
|
@@ -3,14 +3,38 @@
|
|
3
3
|
module ActiveRecordQueryCounter
|
4
4
|
# Module to prepend to the connection adapter to inject the counting behavior.
|
5
5
|
module ConnectionAdapterExtension
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
class << self
|
7
|
+
def inject(connection_class)
|
8
|
+
# Rails 7.1+ uses internal_exec_query instead of exec_query.
|
9
|
+
mod = (connection_class.instance_methods.include?(:internal_exec_query) ? InternalExecQuery : ExecQuery)
|
10
|
+
unless connection_class.include?(mod)
|
11
|
+
connection_class.prepend(mod)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module ExecQuery
|
17
|
+
def exec_query(sql, name = nil, binds = [], *args, **kwargs)
|
18
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
19
|
+
result = super
|
20
|
+
if result.is_a?(ActiveRecord::Result)
|
21
|
+
end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
22
|
+
ActiveRecordQueryCounter.add_query(sql, name, binds, result.length, start_time, end_time)
|
23
|
+
end
|
24
|
+
result
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module InternalExecQuery
|
29
|
+
def internal_exec_query(sql, name = nil, binds = [], *args, **kwargs)
|
30
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
31
|
+
result = super
|
32
|
+
if result.is_a?(ActiveRecord::Result)
|
33
|
+
end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
34
|
+
ActiveRecordQueryCounter.add_query(sql, name, binds, result.length, start_time, end_time)
|
35
|
+
end
|
36
|
+
result
|
12
37
|
end
|
13
|
-
result
|
14
38
|
end
|
15
39
|
end
|
16
40
|
end
|
@@ -3,17 +3,30 @@
|
|
3
3
|
module ActiveRecordQueryCounter
|
4
4
|
# Data structure for storing query information encountered within a block.
|
5
5
|
class Counter
|
6
|
-
attr_accessor :query_count, :row_count, :query_time
|
6
|
+
attr_accessor :query_count, :row_count, :query_time, :cached_query_count
|
7
7
|
attr_reader :thresholds
|
8
8
|
|
9
9
|
def initialize
|
10
10
|
@query_count = 0
|
11
11
|
@row_count = 0
|
12
12
|
@query_time = 0.0
|
13
|
+
@cached_query_count = 0
|
13
14
|
@transactions_hash = {}
|
14
15
|
@thresholds = ActiveRecordQueryCounter.default_thresholds.dup
|
15
16
|
end
|
16
17
|
|
18
|
+
# Return the percentage of queries that used the query cache instead of going to the database.
|
19
|
+
#
|
20
|
+
# @return [Float]
|
21
|
+
def cache_hit_rate
|
22
|
+
total_queries = query_count + cached_query_count
|
23
|
+
if total_queries > 0
|
24
|
+
(cached_query_count.to_f / total_queries)
|
25
|
+
else
|
26
|
+
0.0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
17
30
|
# Return an array of transaction information for any transactions that have been tracked
|
18
31
|
# by the counter.
|
19
32
|
#
|
@@ -3,6 +3,14 @@
|
|
3
3
|
module ActiveRecordQueryCounter
|
4
4
|
# Extension to ActiveRecord::ConnectionAdapters::TransactionManager to count transactions.
|
5
5
|
module TransactionManagerExtension
|
6
|
+
class << self
|
7
|
+
def inject(transaction_manager_class)
|
8
|
+
unless transaction_manager_class.include?(self)
|
9
|
+
transaction_manager_class.prepend(self)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
6
14
|
def begin_transaction(*args, **kwargs)
|
7
15
|
if open_transactions == 0
|
8
16
|
@active_record_query_counter_transaction_start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
@@ -19,7 +19,7 @@ require_relative "active_record_query_counter/version"
|
|
19
19
|
# puts ActiveRecordQueryCounter.row_count
|
20
20
|
# end
|
21
21
|
module ActiveRecordQueryCounter
|
22
|
-
IGNORED_STATEMENTS = %w[
|
22
|
+
IGNORED_STATEMENTS = %w[SCHEMA EXPLAIN].freeze
|
23
23
|
private_constant :IGNORED_STATEMENTS
|
24
24
|
|
25
25
|
class << self
|
@@ -48,6 +48,20 @@ module ActiveRecordQueryCounter
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
# Disable query counting in a block. Any queries or transactions inside the block will not
|
52
|
+
# be counted.
|
53
|
+
#
|
54
|
+
# @return [Object] the return value of the block
|
55
|
+
def disable(&block)
|
56
|
+
counter = current_counter
|
57
|
+
begin
|
58
|
+
self.current_counter = nil
|
59
|
+
yield
|
60
|
+
ensure
|
61
|
+
self.current_counter = counter
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
51
65
|
# Increment the query counters.
|
52
66
|
#
|
53
67
|
# @param row_count [Integer] the number of rows returned by the query
|
@@ -107,6 +121,16 @@ module ActiveRecordQueryCounter
|
|
107
121
|
counter.query_count if counter.is_a?(Counter)
|
108
122
|
end
|
109
123
|
|
124
|
+
# Return the number of queries that hit the query cache and were not sent to the database
|
125
|
+
# that have been counted within the current block. Returns nil if not inside a block where
|
126
|
+
# queries are being counted.
|
127
|
+
#
|
128
|
+
# @return [Integer, nil]
|
129
|
+
def cached_query_count
|
130
|
+
counter = current_counter
|
131
|
+
counter.cached_query_count if counter.is_a?(Counter)
|
132
|
+
end
|
133
|
+
|
110
134
|
# Return the number of rows that have been counted within the current block.
|
111
135
|
# Returns nil if not inside a block where queries are being counted.
|
112
136
|
#
|
@@ -182,6 +206,8 @@ module ActiveRecordQueryCounter
|
|
182
206
|
query_count: counter.query_count,
|
183
207
|
row_count: counter.row_count,
|
184
208
|
query_time: counter.query_time,
|
209
|
+
cached_query_count: counter.cached_query_count,
|
210
|
+
cache_hit_rate: counter.cache_hit_rate,
|
185
211
|
transaction_count: counter.transaction_count,
|
186
212
|
transaction_time: counter.transaction_time
|
187
213
|
}
|
@@ -207,11 +233,14 @@ module ActiveRecordQueryCounter
|
|
207
233
|
# @param connection_class [Class] the connection adapter class to extend
|
208
234
|
# @return [void]
|
209
235
|
def enable!(connection_class)
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
236
|
+
ConnectionAdapterExtension.inject(connection_class)
|
237
|
+
TransactionManagerExtension.inject(ActiveRecord::ConnectionAdapters::TransactionManager)
|
238
|
+
|
239
|
+
@cache_subscription ||= ActiveSupport::Notifications.subscribe("sql.active_record") do |_name, _start_time, _end_time, _id, payload|
|
240
|
+
if payload[:cached]
|
241
|
+
counter = current_counter
|
242
|
+
counter.cached_query_count += 1 if counter
|
243
|
+
end
|
215
244
|
end
|
216
245
|
end
|
217
246
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_query_counter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Durand
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '5.
|
19
|
+
version: '5.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '5.
|
26
|
+
version: '5.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
78
|
- !ruby/object:Gem::Version
|
79
79
|
version: '0'
|
80
80
|
requirements: []
|
81
|
-
rubygems_version: 3.4.
|
81
|
+
rubygems_version: 3.4.20
|
82
82
|
signing_key:
|
83
83
|
specification_version: 4
|
84
84
|
summary: Count total number of ActiveRecord queries and row counts inside a block
|