pg_reports 0.6.1 → 0.6.2
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 +16 -0
- data/README.md +29 -9
- data/lib/pg_reports/annotation_parser.rb +13 -1
- data/lib/pg_reports/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a61a108ff2ba498edaa622cfc11f3f746d56a54f1b964ced3e941516c2eaaec4
|
|
4
|
+
data.tar.gz: 9e0d3da7d606309d51c64e5daf96e66875a6645f23649433d98001209be175d7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f25452a5db23c9288b02334d4c900b838d063e8d754695d0047f931b24d1ec7c2b6a98fbfea3898277df0c124a3cbc52ed40f22e325adc85af503a6d9db43351
|
|
7
|
+
data.tar.gz: 046aca0f21ec77c649f3a5a0658aac92ba4c44bedbd15ec979838b183574b16fe67fcaebf8e7b6b3727de9f082712b7f67ed321c0f8c89723cffbc59cd93e845
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.6.2] - 2026-04-25
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Native Rails QueryLogs source_location support** — `AnnotationParser` now recognizes the `source_location` tag emitted by `ActiveRecord::QueryLogs` and splits it into separate `:file` / `:line` fields for the dashboard's source column. Values are URL-decoded first, since Rails CGI-escapes tag values (so `%2F.../%3A19` becomes `/.../foo.rb:19`).
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **`counter_cache_issues` crashed/misreported on Rails 7.1+ Hash form.** `belongs_to :user, counter_cache: :col` is internally normalized to `{active: true, column: :col}` on Rails 7.1+, but the helper only handled `true` / Symbol / String — so the column came out as `Hash#inspect` (`{active: true, column: "usage_count"}`) and the suggested migration was malformed. `counter_cache_column_name` now handles all four forms (Boolean, Symbol, String, Hash with `:column` key, Hash without `:column`).
|
|
19
|
+
- **`polymorphic_without_index` crashed with `NoMethodError: undefined method '&' for an instance of String`** when a table had an expression index (e.g. `CREATE INDEX ON x (LOWER(email))`). PostgreSQL returns `IndexDefinition#columns` as a String for expression indexes, not an Array. Both the polymorphic check and `coverage_label` now filter out non-array indexes.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **README simplified** — full reports listing moved to [docs/reports.md](docs/reports.md), long sections (EXPLAIN ANALYZE, SQL Query Monitor, Connection pool analytics, IDE integration, Telegram delivery, raw query execution, source tracking) collapsed into `<details>` blocks. From 582 lines to ~340.
|
|
24
|
+
- **Query source tracking** documentation now leads with native `ActiveRecord::QueryLogs` (Rails 7.0+) including a `source_location` lambda example. Marginalia mentioned only as the option for Rails < 7.0.
|
|
25
|
+
|
|
10
26
|
## [0.6.1] - 2026-04-24
|
|
11
27
|
|
|
12
28
|
### Added
|
data/README.md
CHANGED
|
@@ -131,25 +131,40 @@ end
|
|
|
131
131
|
</details>
|
|
132
132
|
|
|
133
133
|
<details>
|
|
134
|
-
<summary><strong>Query source tracking (
|
|
134
|
+
<summary><strong>Query source tracking (Rails query logs)</strong></summary>
|
|
135
135
|
|
|
136
|
-
PgReports parses query annotations to show **where queries originated**.
|
|
136
|
+
PgReports parses query annotations to show **where queries originated**. On Rails 7.0+ use the built-in `ActiveRecord::QueryLogs` (no extra gem needed). On older Rails, install [Marginalia](https://github.com/basecamp/marginalia) — PgReports auto-detects both formats.
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
Minimal setup — adds controller/action:
|
|
139
139
|
|
|
140
140
|
```ruby
|
|
141
|
-
|
|
141
|
+
# config/application.rb
|
|
142
|
+
config.active_record.query_log_tags_enabled = true
|
|
143
|
+
config.active_record.query_log_tags = [:controller, :action]
|
|
142
144
|
```
|
|
143
145
|
|
|
144
|
-
|
|
146
|
+
To also surface **file path and line number** (so source links jump to the actual call site, not just the controller), add a custom `source_location` lambda that walks `caller_locations` and skips gem/framework frames:
|
|
145
147
|
|
|
146
148
|
```ruby
|
|
147
149
|
# config/application.rb
|
|
148
150
|
config.active_record.query_log_tags_enabled = true
|
|
149
|
-
config.active_record.query_log_tags = [
|
|
151
|
+
config.active_record.query_log_tags = [
|
|
152
|
+
:controller,
|
|
153
|
+
:action,
|
|
154
|
+
:job,
|
|
155
|
+
{
|
|
156
|
+
source_location: -> {
|
|
157
|
+
ignore = %r{/(gems|active_record|active_support|active_model|railties|
|
|
158
|
+
action_controller|action_view|action_pack|action_dispatch|
|
|
159
|
+
rack|core_ext|relation|associations|scoping|connection_adapters)/}x
|
|
160
|
+
loc = caller_locations.find { |l| !l.path.match?(ignore) }
|
|
161
|
+
"#{loc.path}:#{loc.lineno}" if loc
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
]
|
|
150
165
|
```
|
|
151
166
|
|
|
152
|
-
|
|
167
|
+
PgReports recognizes the `source_location` tag and splits it into file and line for the **source** column.
|
|
153
168
|
|
|
154
169
|
</details>
|
|
155
170
|
|
|
@@ -284,7 +299,10 @@ The Export dropdown includes **Copy Prompt** (visible on actionable reports). It
|
|
|
284
299
|
|
|
285
300
|
</details>
|
|
286
301
|
|
|
287
|
-
|
|
302
|
+
<details>
|
|
303
|
+
<summary><strong>Telegram delivery</strong></summary>
|
|
304
|
+
|
|
305
|
+
Get a bot token from [@BotFather](https://t.me/BotFather) and your chat ID from [@userinfobot](https://t.me/userinfobot), then:
|
|
288
306
|
|
|
289
307
|
```ruby
|
|
290
308
|
PgReports.configure do |config|
|
|
@@ -296,7 +314,9 @@ PgReports.slow_queries.send_to_telegram
|
|
|
296
314
|
PgReports.health_report.send_to_telegram_as_file
|
|
297
315
|
```
|
|
298
316
|
|
|
299
|
-
|
|
317
|
+
Reports under ~50 rows go as a message; larger ones are sent as a file attachment.
|
|
318
|
+
|
|
319
|
+
</details>
|
|
300
320
|
|
|
301
321
|
## Development
|
|
302
322
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "cgi"
|
|
4
|
+
|
|
3
5
|
module PgReports
|
|
4
6
|
# Parses SQL query comments to extract source location and metadata
|
|
5
7
|
# Supports:
|
|
6
8
|
# - Marginalia format: /*application:myapp,controller:users,action:index*/
|
|
7
|
-
# - Rails QueryLogs: /*action='index',controller='users'*/
|
|
9
|
+
# - Rails QueryLogs: /*action='index',controller='users',source_location='app/foo.rb:42'*/
|
|
8
10
|
#
|
|
9
11
|
module AnnotationParser
|
|
10
12
|
class << self
|
|
@@ -32,6 +34,16 @@ module PgReports
|
|
|
32
34
|
end
|
|
33
35
|
end
|
|
34
36
|
|
|
37
|
+
# Rails QueryLogs custom tag — Rails URL-encodes tag values (CGI.escape) to keep
|
|
38
|
+
# SQL comments safe, so "/" → "%2F" and ":" → "%3A". Decode then split into :file/:line.
|
|
39
|
+
if result[:source_location] && !result[:file]
|
|
40
|
+
decoded = CGI.unescape(result[:source_location].to_s)
|
|
41
|
+
if (match = decoded.match(%r{^(.+):(\d+)$}))
|
|
42
|
+
result[:file] = match[1]
|
|
43
|
+
result[:line] = match[2]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
35
47
|
result
|
|
36
48
|
end
|
|
37
49
|
|
data/lib/pg_reports/version.rb
CHANGED