active_record_query_counter 2.2.1 → 2.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: 752c1c799ab4ee023a24f4f8c3550da35831fdcebf39e71c9bb945bbf4ca7ff9
4
- data.tar.gz: ecd642c76f010996f40d0a6d791db96c06515137b2e1393d5655c1feae314b23
3
+ metadata.gz: 9b460515835154824cb80fec7db1e62dc4f4f983f8779fc1b80bec3c728646a4
4
+ data.tar.gz: 3d26302dd73d2ae010f4732ca4711a7dd1daa4ca0cca55e5ccd50349e89b282c
5
5
  SHA512:
6
- metadata.gz: b4a88b4283290565e8352d35f6c0b5483515dbcacbd17fb223fc90398b94d50ac2984519f84c6a188a576468cb1f9ea373edfcc6855301e78522676558511e9d
7
- data.tar.gz: ff360b2f495c953f79668a27520722c425c94d9cafe6607dcae40d25b65d10dd8f38f7b0d478771495927a5229ecf1e6948328b6adb87be5d6d186c77727d4f2
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
  [![Continuous Integration](https://github.com/bdurand/active_record_query_counter/actions/workflows/continuous_integration.yml/badge.svg)](https://github.com/bdurand/active_record_query_counter/actions/workflows/continuous_integration.yml)
4
- [![Regression Test](https://github.com/bdurand/active_record_query_counter/actions/workflows/regression_test.yml/badge.svg)](https://github.com/bdurand/active_record_query_counter/actions/workflows/regression_test.yml)
5
4
  [![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
6
5
  [![Gem Version](https://badge.fury.io/rb/active_record_query_counter.svg)](https://badge.fury.io/rb/active_record_query_counter)
7
6
 
8
- This gem injects itself into ActiveRecord to give you insight into how your code is using the database.
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
- Within a block of code, it will count:
9
+ It measures database usage within a block of code, including:
11
10
 
12
- - the number of queries
13
- - the number of rows returned
14
- - the amount of time spent on queries
15
- - the number of transactions used
16
- - the amount of time spent inside transactions
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
- The intended use is to gather instrumentation stats for finding hot spots in your code that produce a lot of queries or slow queries or queries that return a lot of rows. It can also be used to find code that is not using transactions when making multiple updates to the database.
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
- The behavior must be enabled on your database connection adapter from within an initializer.
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
- Postgres:
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
- Next you must specify the blocks where you want to count queries.
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
- This gem includes middleware for both Rack and Sidekiq that will enable query counting on web requests and in workers. If you are using Rails with Sidekiq, you can enable both with an initializer.
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
- If you want to disable query counting within a block of code, you can use the `disable` method.
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 in this block.
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
- You can also subscribe to ActiveSupport notifications to get notified when query thresholds are exceeded.
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
- #### active_record_query_counter.query_time notification
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
- #### active_record_query_counter.row_count notification
110
+ ##### 2. active_record_query_counter.row_count notification
91
111
 
92
- This notification is triggered when a query returns more rows than the `row_count` threshold. The payload contains the following keys:
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
- #### active_record_query_counter.transaction_time notification
119
+ ##### 3. active_record_query_counter.transaction_time notification
100
120
 
101
- This notification is triggered when a transaction takes longer than the `transaction_time` threshold. The payload contains the following keys:
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
- #### active_record_query_counter.transaction_count notification
125
+ ##### 4. active_record_query_counter.transaction_count notification
106
126
 
107
- This notification is triggered when a transaction takes longer than the `transaction_count` threshold. The payload contains the following keys:
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
- The thresholds for triggering notifications can be set globally in an initializer:
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
- They can be set locally inside a `count_queries` block with the `thresholds` object. Local thresholds will override the global thresholds only inside the block and will not change any global state.
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
- You can pass thresholds to individual Sidekiq workers via the `sidekiq_options` on the worker.
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
- You can set separate thresholds on the Rack middleware when you install it.
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 Notification Subscriptions
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.2.1
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 = "Count total number of ActiveRecord queries and row counts inside a block"
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.2.1
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-04-03 00:00:00.000000000 Z
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.12
84
+ rubygems_version: 3.4.10
82
85
  signing_key:
83
86
  specification_version: 4
84
- summary: Count total number of ActiveRecord queries and row counts inside a block
87
+ summary: Provides detailed insights into how your code interacts with the database
88
+ by hooking into ActiveRecord.
85
89
  test_files: []