pg-locks-monitor 0.1.2 → 0.2.1

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: d1cdcf1754671326b02e939ec99c90c2cd8d696bdcbdc82c6c84b378e0365f3b
4
- data.tar.gz: ad862bd65e1db50465ee1456ac18619abeb9f9f10dded487f335348f036b5d1c
3
+ metadata.gz: c15914dcf0512070ba0f629249a9743c04aad078d6f7dcd23a96acda248284f4
4
+ data.tar.gz: bbf242ededb3f441489be230e5e013d362c85b0964f34667a89b9ffe12589aa0
5
5
  SHA512:
6
- metadata.gz: f20cb497a1ba37843441cb244fb581ab26ad7181ea1310c4c8d1db75f243fdac3ea05c9ec0b460b1c9bfe23827cb46360885fb24fef8747879d57342d4ad28cd
7
- data.tar.gz: 9e9493e65efff88e07b33c08f8c7886b7b42b45939d07afe904600c7a9036896255756bcb7a7451754482f03bd150feb89db052a4766e8716e9f230832ed4b61
6
+ metadata.gz: c17edd2b3419837fd7e6f909ba8f7bf2878a28df97f0f80f0a2a12e5534188895d44f3897372445267ff8d524f1b1825d09c4a77b29ad8a991dedd4b71ba4dfb
7
+ data.tar.gz: a876c3894b680a8cc20bb29070d1e9dc8af6678cd09ed6293501ede52eecae134ddfb48b37d7441676f9a9f4499f8b0f2eba46108b963da19ebf8f6ef78992ee
data/README.md CHANGED
@@ -36,6 +36,9 @@ PgLocksMonitor.configure do |config|
36
36
  config.slack_channel = ""
37
37
 
38
38
  config.notifier_class = PgLocksMonitor::DefaultNotifier
39
+
40
+ config.locks_filter_proc = ->(lock) { true }
41
+ config.blocking_filter_proc = ->(lock) { true }
39
42
  end
40
43
  ```
41
44
 
@@ -49,7 +52,8 @@ end
49
52
  - `slack_webhook_url` - webhook necessary for Slack notification to work
50
53
  - `slack_channel` - the name of the target Slack channel
51
54
  - `notifier_class` - customizable notifier class
52
-
55
+ - `locks_filter_proc` - configurable filter to exclude locks based on any custom logic
56
+ - `blocking_filter_proc` - configurable filter to exclude blocking locks based on any custom logic
53
57
 
54
58
  ## Testing the notification channels
55
59
 
@@ -129,14 +133,18 @@ Here's a sample lock notification:
129
133
  "transactionid": null,
130
134
  # bool indicating if the lock is already granted
131
135
  "granted": true,
132
- # type of the acquired lock
136
+ # mode of the acquired lock
133
137
  "mode": "RowExclusiveLock",
134
138
  # SQL query which acquired the lock
135
139
  "query_snippet": "UPDATE \"users\" SET \"updated_at\" = $1 WHERE \"users\".\"id\" = $2 from/sidekiq_job:UserUpdater/",
136
140
  # age of the lock
137
141
  "age": "PT0.94945S",
138
142
  # app that acquired the lock
139
- "application": "bin/sidekiq"
143
+ "application": "bin/sidekiq",
144
+ # ID of the database where lock was acquired
145
+ "database": "84759327",
146
+ # type of the acquired lock
147
+ "locktype": "relation",
140
148
  },
141
149
  ```
142
150
 
@@ -177,6 +185,36 @@ A background job that schedules itself is not the cleanest pattern. So alternati
177
185
 
178
186
  A recommended frequency of invocation depends on your app's traffic. From my experience, even 1 minute apart snapshots can provide a lot of valuable data, but it all depends on how often the locks are occurring in your Rails application.
179
187
 
188
+ ## Filter procs
189
+
190
+ You can modify `locks_filter_proc` and `blocking_filter_proc` to exclude locks from getting reported. For example, here's how you can report only locks that originated from the Puma server process:
191
+
192
+ `config/initializers/pg_locks_monitor.rb`
193
+ ```ruby
194
+ PgLocksMonitor.configure do |config|
195
+ # ...
196
+
197
+ config.locks_filter_proc = -> (lock) {
198
+ lock.fetch("application").downcase.include?("puma")
199
+ }
200
+ end
201
+ ```
202
+
203
+ or exclude blocking locks which are affecting only the Sidekiq process:
204
+
205
+ `config/initializers/pg_locks_monitor.rb`
206
+ ```ruby
207
+ PgLocksMonitor.configure do |config|
208
+ # ...
209
+
210
+ config.blocking_filter_proc = -> (lock) {
211
+ !lock.fetch("blocked_sql_app").downcase.include?("sidekiq")
212
+ }
213
+ end
214
+ ```
215
+
216
+ Please beware that configuring these procs does not overwrite the min duration settings, i.e., `locks_min_duration_ms` and `blocking_min_duration_ms`.
217
+
180
218
  ## Custom notifier class
181
219
 
182
220
  `PgLocksMonitor::DefaultNotifier` supports sending lock notifications with `Rails.logger` or to a Slack channel. If you want to use different notification channels you can define your custom notifier like that:
@@ -5,23 +5,23 @@ require "pg"
5
5
 
6
6
  module PgLocksMonitor
7
7
  def self.snapshot!
8
- locks = RailsPgExtras.locks(
9
- in_format: :hash, args: {
10
- limit: configuration.locks_limit,
11
- },
8
+ locks = RubyPgExtras.locks(
9
+ in_format: :hash,
12
10
  ).select do |lock|
13
11
  if (age = lock.fetch("age"))
14
12
  (ActiveSupport::Duration.parse(age).to_f * 1000) > configuration.locks_min_duration_ms
15
13
  end
16
- end
14
+ end.select(&configuration.locks_filter_proc)
15
+ .first(configuration.locks_limit)
17
16
 
18
17
  if locks.present? && configuration.monitor_locks
19
18
  configuration.notifier_class.call(locks)
20
19
  end
21
20
 
22
- blocking = RailsPgExtras.blocking(in_format: :hash).select do |block|
21
+ blocking = RubyPgExtras.blocking(in_format: :hash).select do |block|
23
22
  (ActiveSupport::Duration.parse(block.fetch("blocking_duration")).to_f * 1000) > configuration.blocking_min_duration_ms
24
- end
23
+ end.select(&configuration.blocking_filter_proc)
24
+ .first(configuration.locks_limit)
25
25
 
26
26
  if blocking.present? && configuration.monitor_blocking
27
27
  configuration.notifier_class.call(blocking)
@@ -13,6 +13,8 @@ module PgLocksMonitor
13
13
  slack_webhook_url: nil,
14
14
  slack_channel: nil,
15
15
  notifier_class: PgLocksMonitor::DefaultNotifier,
16
+ locks_filter_proc: ->(lock) { true },
17
+ blocking_filter_proc: ->(lock) { true },
16
18
  }
17
19
 
18
20
  attr_accessor *DEFAULT.keys
@@ -43,6 +45,9 @@ PgLocksMonitor.configure do |config|
43
45
  config.slack_channel = "#{DEFAULT[:slack_channel]}"
44
46
 
45
47
  config.notifier_class = #{DEFAULT[:notifier_class]}
48
+
49
+ config.locks_filter_proc = ->(lock) { true }
50
+ config.blocking_filter_proc = ->(lock) { true }
46
51
  end
47
52
  CONFIG
48
53
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgLocksMonitor
4
- VERSION = "0.1.2"
4
+ VERSION = "0.2.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg-locks-monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-17 00:00:00.000000000 Z
11
+ date: 2024-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-pg-extras