active_record_query_counter 2.2.1 → 2.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 +6 -0
- data/README.md +56 -32
- data/VERSION +1 -1
- data/active_record_query_counter.gemspec +7 -1
- data/lib/active_record_query_counter/counter.rb +2 -1
- data/lib/active_record_query_counter/transaction_manager_extension.rb +1 -0
- data/lib/active_record_query_counter.rb +22 -1
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b460515835154824cb80fec7db1e62dc4f4f983f8779fc1b80bec3c728646a4
|
4
|
+
data.tar.gz: 3d26302dd73d2ae010f4732ca4711a7dd1daa4ca0cca55e5ccd50349e89b282c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1af45ed8c0659df4fcbf665621576b07380565a1289458e868b7cb33825c2d055e7b489eb1e490c31a566157a01f328eedd2771f9f3f5bffdece2b357445a01
|
7
|
+
data.tar.gz: ba21e07f668e1c3f97c61ce6f48fd10ef2d019afdd7d9d579e3487c710d58e8b44a9b1c5042572bc74be55a907c506d6385947dbe85a10b14b57e2b7b94037b7
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,12 @@ 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.3.0
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- Added count of rollbacks from transactions
|
12
|
+
|
7
13
|
## 2.2.1
|
8
14
|
|
9
15
|
### Changed
|
data/README.md
CHANGED
@@ -1,39 +1,47 @@
|
|
1
1
|
# ActiveRecordQueryCounter
|
2
2
|
|
3
3
|
[](https://github.com/bdurand/active_record_query_counter/actions/workflows/continuous_integration.yml)
|
4
|
-
[](https://github.com/bdurand/active_record_query_counter/actions/workflows/regression_test.yml)
|
5
4
|
[](https://github.com/testdouble/standard)
|
6
5
|
[](https://badge.fury.io/rb/active_record_query_counter)
|
7
6
|
|
8
|
-
|
7
|
+
**ActiveRecordQueryCounter** is a ruby gem that provides detailed insights into how your code interacts with the database by hooking into ActiveRecord.
|
9
8
|
|
10
|
-
|
9
|
+
It measures database usage within a block of code, including:
|
11
10
|
|
12
|
-
-
|
13
|
-
-
|
14
|
-
-
|
15
|
-
-
|
16
|
-
-
|
11
|
+
- The number of queries executed
|
12
|
+
- The number of rows returned
|
13
|
+
- The total time spent on queries
|
14
|
+
- The number of transactions used
|
15
|
+
- The total time spent inside transactions
|
16
|
+
- The number of transactions that were rolled back
|
17
17
|
|
18
|
-
|
18
|
+
This gem is designed to help you:
|
19
|
+
|
20
|
+
- Identify "hot spots" in your code that generate excessive or slow queries.
|
21
|
+
- Spot queries returning unexpectedly large result sets.
|
22
|
+
- Detect areas where transactions are underutilized, especially when performing multiple database updates.
|
19
23
|
|
20
24
|
## Usage
|
21
25
|
|
22
|
-
|
26
|
+
### Enabling The Gem
|
27
|
+
|
28
|
+
To use **ActiveRecordQueryCounter**, you first need to enable it on your database connection adapter. Add the following to an initializer:
|
23
29
|
|
24
|
-
|
30
|
+
For **PostgreSQL**:
|
25
31
|
|
26
32
|
```ruby
|
27
33
|
ActiveRecordQueryCounter.enable!(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
28
34
|
```
|
29
35
|
|
30
|
-
MySQL
|
36
|
+
For **MySQL**:
|
31
37
|
|
32
38
|
```ruby
|
33
39
|
ActiveRecordQueryCounter.enable!(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
|
34
40
|
```
|
35
41
|
|
36
|
-
|
42
|
+
### Counting Queries
|
43
|
+
|
44
|
+
To measure database activity, wrap the code you want to monitor inside a `count_queries` block:
|
37
45
|
|
38
46
|
```ruby
|
39
47
|
ActiveRecordQueryCounter.count_queries do
|
@@ -43,18 +51,25 @@ ActiveRecordQueryCounter.count_queries do
|
|
43
51
|
puts "Query Time: #{ActiveRecordQueryCounter.query_time}"
|
44
52
|
puts "Transactions: #{ActiveRecordQueryCounter.transaction_count}"
|
45
53
|
puts "Transaction Time: #{ActiveRecordQueryCounter.transaction_time}"
|
54
|
+
puts "Rollbacks: #{ActiveRecordQueryCounter.rollback_count}"
|
46
55
|
end
|
47
56
|
```
|
48
57
|
|
49
|
-
|
58
|
+
### Middleware Integration
|
59
|
+
|
60
|
+
For **Rails** and **Sidekiq**, middleware is included to enable query counting in web requests and workers.
|
61
|
+
|
62
|
+
Add the following to an initializer:
|
50
63
|
|
51
64
|
```ruby
|
52
65
|
ActiveSupport.on_load(:active_record) do
|
53
66
|
ActiveRecordQueryCounter.enable!(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
54
67
|
end
|
55
68
|
|
69
|
+
# Enable Rack Middleware
|
56
70
|
Rails.application.config.middleware.use(ActiveRecordQueryCounter::RackMiddleware)
|
57
71
|
|
72
|
+
# Enable Sidekiq Middleware
|
58
73
|
Sidekiq.configure_server do |config|
|
59
74
|
config.server_middleware do |chain|
|
60
75
|
chain.add ActiveRecordQueryCounter::SidekiqMiddleware
|
@@ -62,13 +77,15 @@ Sidekiq.configure_server do |config|
|
|
62
77
|
end
|
63
78
|
```
|
64
79
|
|
65
|
-
|
80
|
+
### Disabling Query Counting
|
81
|
+
|
82
|
+
You can temporarily disable query counting within a block using `disable`:
|
66
83
|
|
67
84
|
```ruby
|
68
85
|
ActiveRecordQueryCounter.count_queries do
|
69
86
|
do_something
|
70
87
|
ActiveRecordQueryCounter.disable do
|
71
|
-
# Queries will not be counted
|
88
|
+
# Queries in this block will not be counted.
|
72
89
|
do_something_else
|
73
90
|
end
|
74
91
|
end
|
@@ -76,43 +93,46 @@ end
|
|
76
93
|
|
77
94
|
### Notifications
|
78
95
|
|
79
|
-
|
96
|
+
**ActiveRecordQueryCounter** supports ActiveSupport notifications when certain query thresholds are exceeded.
|
97
|
+
|
98
|
+
#### Available Notifications
|
99
|
+
|
100
|
+
##### 1. active_record_query_counter.query_time notification
|
80
101
|
|
81
|
-
|
102
|
+
Triggered when a query exceeds the query_time threshold with the payload:
|
82
103
|
|
83
|
-
This notification is triggered when a query takes longer than the `query_time` threshold. The payload contains the following keys:
|
84
104
|
|
85
105
|
- `:sql` - The SQL statement that was executed.
|
86
106
|
- `:binds` - The bind parameters that were used.
|
87
107
|
- `:row_count` - The number of rows returned.
|
88
108
|
- `:trace` - The stack trace of where the query was executed.
|
89
109
|
|
90
|
-
|
110
|
+
##### 2. active_record_query_counter.row_count notification
|
91
111
|
|
92
|
-
|
112
|
+
Triggered when a query exceeds the row_count threshold with the payload:
|
93
113
|
|
94
114
|
- `:sql` - The SQL statement that was executed.
|
95
115
|
- `:binds` - The bind parameters that were used.
|
96
116
|
- `:row_count` - The number of rows returned.
|
97
117
|
- `:trace` - The stack trace of where the query was executed.
|
98
118
|
|
99
|
-
|
119
|
+
##### 3. active_record_query_counter.transaction_time notification
|
100
120
|
|
101
|
-
|
121
|
+
Triggered when a transaction exceeds the transaction_time threshold with the payload:
|
102
122
|
|
103
123
|
- `:trace` - The stack trace of where the transaction was completed.
|
104
124
|
|
105
|
-
|
125
|
+
##### 4. active_record_query_counter.transaction_count notification
|
106
126
|
|
107
|
-
|
127
|
+
Triggered when transactions exceed the transaction_count threshold with the payload:
|
108
128
|
|
109
129
|
- `:transactions` - An array of `ActiveRecordQueryCounter::TransactionInfo` objects.
|
110
130
|
|
111
131
|
The duration of the notification event is the time between when the first transaction was started and the last transaction was completed.
|
112
132
|
|
113
|
-
#### Thresholds
|
133
|
+
#### Setting Thresholds
|
114
134
|
|
115
|
-
|
135
|
+
Thresholds can be configured **globally** in an initializer:
|
116
136
|
|
117
137
|
```ruby
|
118
138
|
ActiveRecordQueryCounter.default_thresholds.set(
|
@@ -123,7 +143,7 @@ ActiveRecordQueryCounter.default_thresholds.set(
|
|
123
143
|
)
|
124
144
|
```
|
125
145
|
|
126
|
-
|
146
|
+
Or locally within a block:
|
127
147
|
|
128
148
|
```ruby
|
129
149
|
ActiveRecordQueryCounter.count_queries do
|
@@ -136,7 +156,8 @@ ActiveRecordQueryCounter.count_queries do
|
|
136
156
|
end
|
137
157
|
```
|
138
158
|
|
139
|
-
|
159
|
+
#### Sidekiq Worker Thresholds
|
160
|
+
Thresholds for individual Sidekiq workers can be set using `sidekiq_options`:
|
140
161
|
|
141
162
|
```ruby
|
142
163
|
class MyWorker
|
@@ -152,7 +173,6 @@ class MyWorker
|
|
152
173
|
}
|
153
174
|
}
|
154
175
|
)
|
155
|
-
# You can disable thresholds for the worker by setting `thresholds: false`.
|
156
176
|
|
157
177
|
def perform
|
158
178
|
do_something
|
@@ -160,7 +180,11 @@ class MyWorker
|
|
160
180
|
end
|
161
181
|
```
|
162
182
|
|
163
|
-
|
183
|
+
To disable thresholds for a worker, set `thresholds: false`.
|
184
|
+
|
185
|
+
#### Rack Middleware Thresholds
|
186
|
+
|
187
|
+
You can configure separate thresholds for the Rack middleware:
|
164
188
|
|
165
189
|
```ruby
|
166
190
|
Rails.application.config.middleware.use(ActiveRecordQueryCounter::RackMiddleware, thresholds: {
|
@@ -171,7 +195,7 @@ Rails.application.config.middleware.use(ActiveRecordQueryCounter::RackMiddleware
|
|
171
195
|
})
|
172
196
|
```
|
173
197
|
|
174
|
-
#### Example
|
198
|
+
#### Example: Subscribing to Notifications
|
175
199
|
|
176
200
|
```ruby
|
177
201
|
ActiveRecordQueryCounter.default_thresholds.query_time = 1.0
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.3.0
|
@@ -4,10 +4,16 @@ Gem::Specification.new do |spec|
|
|
4
4
|
spec.authors = ["Brian Durand"]
|
5
5
|
spec.email = ["bbdurand@gmail.com"]
|
6
6
|
|
7
|
-
spec.summary = "
|
7
|
+
spec.summary = "Provides detailed insights into how your code interacts with the database by hooking into ActiveRecord."
|
8
8
|
spec.homepage = "https://github.com/bdurand/active_record_query_counter"
|
9
9
|
spec.license = "MIT"
|
10
10
|
|
11
|
+
spec.metadata = {
|
12
|
+
"homepage_uri" => spec.homepage,
|
13
|
+
"source_code_uri" => spec.homepage,
|
14
|
+
"changelog_uri" => "#{spec.homepage}/blob/main/CHANGELOG.md"
|
15
|
+
}
|
16
|
+
|
11
17
|
# Specify which files should be added to the gem when it is released.
|
12
18
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
13
19
|
ignore_files = %w[
|
@@ -3,7 +3,7 @@
|
|
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, :cached_query_count
|
6
|
+
attr_accessor :query_count, :row_count, :query_time, :cached_query_count, :rollback_count
|
7
7
|
attr_reader :thresholds
|
8
8
|
|
9
9
|
def initialize
|
@@ -13,6 +13,7 @@ module ActiveRecordQueryCounter
|
|
13
13
|
@cached_query_count = 0
|
14
14
|
@transactions_hash = {}
|
15
15
|
@thresholds = ActiveRecordQueryCounter.default_thresholds.dup
|
16
|
+
@rollback_count = 0
|
16
17
|
end
|
17
18
|
|
18
19
|
# Return the percentage of queries that used the query cache instead of going to the database.
|
@@ -31,6 +31,7 @@ module ActiveRecordQueryCounter
|
|
31
31
|
if @active_record_query_counter_transaction_start_time && open_transactions == 1
|
32
32
|
end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
33
33
|
ActiveRecordQueryCounter.add_transaction(@active_record_query_counter_transaction_start_time, end_time)
|
34
|
+
ActiveRecordQueryCounter.increment_rollbacks
|
34
35
|
@active_record_query_counter_transaction_start_time = nil
|
35
36
|
end
|
36
37
|
super
|
@@ -113,6 +113,17 @@ module ActiveRecordQueryCounter
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
+
# Return the number of rollbacks that have been counted within the current block.
|
117
|
+
# Returns nil if not inside a block where queries are being counted.
|
118
|
+
#
|
119
|
+
# @return [Integer, nil]
|
120
|
+
def increment_rollbacks
|
121
|
+
counter = current_counter
|
122
|
+
return unless counter.is_a?(Counter)
|
123
|
+
|
124
|
+
counter.rollback_count += 1
|
125
|
+
end
|
126
|
+
|
116
127
|
# Return the number of queries that have been counted within the current block.
|
117
128
|
# Returns nil if not inside a block where queries are being counted.
|
118
129
|
#
|
@@ -195,6 +206,15 @@ module ActiveRecordQueryCounter
|
|
195
206
|
counter.transactions if counter.is_a?(Counter)
|
196
207
|
end
|
197
208
|
|
209
|
+
# Return the number of transactions that have rolled back within the current block.
|
210
|
+
# Returns nil if not inside a block where queries are being counted.
|
211
|
+
#
|
212
|
+
# @return [Integer, nil]
|
213
|
+
def rollback_count
|
214
|
+
counter = current_counter
|
215
|
+
counter.rollback_count if counter.is_a?(Counter)
|
216
|
+
end
|
217
|
+
|
198
218
|
# Return the query info as a hash with keys :query_count, :row_count, :query_time
|
199
219
|
# :transaction_count, and :transaction_type or nil if not inside a block where queries
|
200
220
|
# are being counted.
|
@@ -210,7 +230,8 @@ module ActiveRecordQueryCounter
|
|
210
230
|
cached_query_count: counter.cached_query_count,
|
211
231
|
cache_hit_rate: counter.cache_hit_rate,
|
212
232
|
transaction_count: counter.transaction_count,
|
213
|
-
transaction_time: counter.transaction_time
|
233
|
+
transaction_time: counter.transaction_time,
|
234
|
+
rollback_count: counter.rollback_count
|
214
235
|
}
|
215
236
|
end
|
216
237
|
end
|
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.3.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: 2024-
|
11
|
+
date: 2024-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -62,7 +62,10 @@ files:
|
|
62
62
|
homepage: https://github.com/bdurand/active_record_query_counter
|
63
63
|
licenses:
|
64
64
|
- MIT
|
65
|
-
metadata:
|
65
|
+
metadata:
|
66
|
+
homepage_uri: https://github.com/bdurand/active_record_query_counter
|
67
|
+
source_code_uri: https://github.com/bdurand/active_record_query_counter
|
68
|
+
changelog_uri: https://github.com/bdurand/active_record_query_counter/blob/main/CHANGELOG.md
|
66
69
|
post_install_message:
|
67
70
|
rdoc_options: []
|
68
71
|
require_paths:
|
@@ -78,8 +81,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
81
|
- !ruby/object:Gem::Version
|
79
82
|
version: '0'
|
80
83
|
requirements: []
|
81
|
-
rubygems_version: 3.4.
|
84
|
+
rubygems_version: 3.4.10
|
82
85
|
signing_key:
|
83
86
|
specification_version: 4
|
84
|
-
summary:
|
87
|
+
summary: Provides detailed insights into how your code interacts with the database
|
88
|
+
by hooking into ActiveRecord.
|
85
89
|
test_files: []
|