pg_reports 0.3.1 → 0.4.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 +36 -0
- data/app/controllers/pg_reports/dashboard_controller.rb +59 -4
- data/app/views/layouts/pg_reports/application.html.erb +1 -1
- data/app/views/pg_reports/dashboard/_show_modals.html.erb +8 -1
- data/app/views/pg_reports/dashboard/_show_scripts.html.erb +56 -18
- data/app/views/pg_reports/dashboard/_show_styles.html.erb +122 -1
- data/app/views/pg_reports/dashboard/show.html.erb +89 -47
- data/config/locales/en.yml +13 -0
- data/config/locales/ru.yml +13 -0
- data/config/locales/uk.yml +13 -0
- data/lib/pg_reports/dashboard/reports_registry.rb +14 -0
- data/lib/pg_reports/definitions/connections/active_connections.yml +23 -0
- data/lib/pg_reports/definitions/connections/blocking_queries.yml +20 -0
- data/lib/pg_reports/definitions/connections/connection_stats.yml +18 -0
- data/lib/pg_reports/definitions/connections/idle_connections.yml +21 -0
- data/lib/pg_reports/definitions/connections/locks.yml +22 -0
- data/lib/pg_reports/definitions/connections/long_running_queries.yml +43 -0
- data/lib/pg_reports/definitions/indexes/bloated_indexes.yml +43 -0
- data/lib/pg_reports/definitions/indexes/duplicate_indexes.yml +19 -0
- data/lib/pg_reports/definitions/indexes/index_sizes.yml +29 -0
- data/lib/pg_reports/definitions/indexes/index_usage.yml +27 -0
- data/lib/pg_reports/definitions/indexes/invalid_indexes.yml +19 -0
- data/lib/pg_reports/definitions/indexes/missing_indexes.yml +27 -0
- data/lib/pg_reports/definitions/indexes/unused_indexes.yml +41 -0
- data/lib/pg_reports/definitions/queries/all_queries.yml +35 -0
- data/lib/pg_reports/definitions/queries/expensive_queries.yml +43 -0
- data/lib/pg_reports/definitions/queries/heavy_queries.yml +49 -0
- data/lib/pg_reports/definitions/queries/low_cache_hit_queries.yml +47 -0
- data/lib/pg_reports/definitions/queries/missing_index_queries.yml +31 -0
- data/lib/pg_reports/definitions/queries/slow_queries.yml +48 -0
- data/lib/pg_reports/definitions/system/activity_overview.yml +17 -0
- data/lib/pg_reports/definitions/system/cache_stats.yml +18 -0
- data/lib/pg_reports/definitions/system/database_sizes.yml +18 -0
- data/lib/pg_reports/definitions/system/extensions.yml +19 -0
- data/lib/pg_reports/definitions/system/settings.yml +20 -0
- data/lib/pg_reports/definitions/tables/bloated_tables.yml +43 -0
- data/lib/pg_reports/definitions/tables/cache_hit_ratios.yml +26 -0
- data/lib/pg_reports/definitions/tables/recently_modified.yml +27 -0
- data/lib/pg_reports/definitions/tables/row_counts.yml +29 -0
- data/lib/pg_reports/definitions/tables/seq_scans.yml +31 -0
- data/lib/pg_reports/definitions/tables/table_sizes.yml +31 -0
- data/lib/pg_reports/definitions/tables/vacuum_needed.yml +39 -0
- data/lib/pg_reports/filter.rb +58 -0
- data/lib/pg_reports/module_generator.rb +44 -0
- data/lib/pg_reports/modules/connections.rb +8 -73
- data/lib/pg_reports/modules/indexes.rb +9 -94
- data/lib/pg_reports/modules/queries.rb +9 -100
- data/lib/pg_reports/modules/schema_analysis.rb +156 -0
- data/lib/pg_reports/modules/system.rb +7 -59
- data/lib/pg_reports/modules/tables.rb +9 -96
- data/lib/pg_reports/report_definition.rb +161 -0
- data/lib/pg_reports/report_loader.rb +38 -0
- data/lib/pg_reports/sql/schema_analysis/unique_indexes.sql +35 -0
- data/lib/pg_reports/version.rb +1 -1
- data/lib/pg_reports.rb +24 -0
- metadata +38 -1
data/config/locales/uk.yml
CHANGED
|
@@ -295,6 +295,19 @@ uk:
|
|
|
295
295
|
- "Цільове значення: >99% для OLTP, >95% для mixed workload."
|
|
296
296
|
- "Низький cache hit: збільште shared_buffers (до 25% RAM), або проблема в запитах."
|
|
297
297
|
|
|
298
|
+
# === SCHEMA ANALYSIS ===
|
|
299
|
+
missing_validations:
|
|
300
|
+
title: "Відсутні валідації"
|
|
301
|
+
what: "Унікальні індекси в базі даних без відповідних валідацій uniqueness в Rails-моделях."
|
|
302
|
+
how: "Аналізує всі унікальні індекси (включаючи композитні) та перевіряє наявність validates :column, uniqueness: true у відповідній Rails-моделі."
|
|
303
|
+
nuances:
|
|
304
|
+
- "Обмеження БД (індекси) та валідації моделі служать різним цілям — обидва мають бути присутніми."
|
|
305
|
+
- "Унікальний індекс запобігає дублікатам на рівні БД, валідація дає зрозумілі повідомлення про помилки."
|
|
306
|
+
- "Для композитних індексів (a, b) потрібна валідація зі scope: validates :a, uniqueness: { scope: :b }"
|
|
307
|
+
- "Деякі таблиці можуть не мати моделей — це нормально для join-таблиць або legacy-таблиць."
|
|
308
|
+
- "Валідації в concerns та батьківських моделях також детектуються."
|
|
309
|
+
- "Первинні ключі не потребують валідацій — вони автоматично унікальні."
|
|
310
|
+
|
|
298
311
|
# Problem explanations for highlighting
|
|
299
312
|
problems:
|
|
300
313
|
high_mean_time: "Високий середній час виконання. Розгляньте додавання індексів або оптимізацію запиту."
|
|
@@ -139,6 +139,12 @@ module PgReports
|
|
|
139
139
|
cache_stats: {
|
|
140
140
|
thresholds: {cache_hit_ratio: {warning: 0.95, critical: 0.90, inverted: true}},
|
|
141
141
|
problem_fields: ["cache_hit_ratio"]
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
# === SCHEMA ANALYSIS ===
|
|
145
|
+
missing_validations: {
|
|
146
|
+
thresholds: {},
|
|
147
|
+
problem_fields: []
|
|
142
148
|
}
|
|
143
149
|
}.freeze
|
|
144
150
|
|
|
@@ -208,6 +214,14 @@ module PgReports
|
|
|
208
214
|
activity_overview: {name: "Activity Overview", description: "Current activity summary"},
|
|
209
215
|
cache_stats: {name: "Cache Stats", description: "Database cache statistics"}
|
|
210
216
|
}
|
|
217
|
+
},
|
|
218
|
+
schema_analysis: {
|
|
219
|
+
name: "Schema Analysis",
|
|
220
|
+
icon: "🔍",
|
|
221
|
+
color: "#06b6d4",
|
|
222
|
+
reports: {
|
|
223
|
+
missing_validations: {name: "Missing Validations", description: "Unique indexes without model validations"}
|
|
224
|
+
}
|
|
211
225
|
}
|
|
212
226
|
}.freeze
|
|
213
227
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Active connections
|
|
2
|
+
# Simple report showing all active database connections
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: active_connections
|
|
6
|
+
module: connections
|
|
7
|
+
description: "All active database connections"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: connections
|
|
11
|
+
file: active_connections
|
|
12
|
+
|
|
13
|
+
title: "Active Connections"
|
|
14
|
+
|
|
15
|
+
columns:
|
|
16
|
+
- pid
|
|
17
|
+
- database
|
|
18
|
+
- username
|
|
19
|
+
- application
|
|
20
|
+
- state
|
|
21
|
+
- query_start
|
|
22
|
+
- state_change
|
|
23
|
+
- query
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Blocking queries - queries that are blocking others
|
|
2
|
+
# Simple report showing lock conflicts
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: blocking_queries
|
|
6
|
+
module: connections
|
|
7
|
+
description: "Queries that are blocking other queries"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: connections
|
|
11
|
+
file: blocking_queries
|
|
12
|
+
|
|
13
|
+
title: "Blocking Queries"
|
|
14
|
+
|
|
15
|
+
columns:
|
|
16
|
+
- blocked_pid
|
|
17
|
+
- blocking_pid
|
|
18
|
+
- blocked_query
|
|
19
|
+
- blocking_query
|
|
20
|
+
- blocked_duration
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Connection statistics by state
|
|
2
|
+
# Simple report showing connection counts grouped by state
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: connection_stats
|
|
6
|
+
module: connections
|
|
7
|
+
description: "Connection counts by database and state"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: connections
|
|
11
|
+
file: connection_stats
|
|
12
|
+
|
|
13
|
+
title: "Connection Statistics"
|
|
14
|
+
|
|
15
|
+
columns:
|
|
16
|
+
- database
|
|
17
|
+
- state
|
|
18
|
+
- count
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Idle connections
|
|
2
|
+
# Simple report showing connections in idle state
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: idle_connections
|
|
6
|
+
module: connections
|
|
7
|
+
description: "Connections currently idle"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: connections
|
|
11
|
+
file: idle_connections
|
|
12
|
+
|
|
13
|
+
title: "Idle Connections"
|
|
14
|
+
|
|
15
|
+
columns:
|
|
16
|
+
- pid
|
|
17
|
+
- database
|
|
18
|
+
- username
|
|
19
|
+
- application
|
|
20
|
+
- idle_duration
|
|
21
|
+
- state_change
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Lock statistics
|
|
2
|
+
# Simple report showing current database locks
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: locks
|
|
6
|
+
module: connections
|
|
7
|
+
description: "Current database locks"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: connections
|
|
11
|
+
file: locks
|
|
12
|
+
|
|
13
|
+
title: "Current Locks"
|
|
14
|
+
|
|
15
|
+
columns:
|
|
16
|
+
- pid
|
|
17
|
+
- database
|
|
18
|
+
- relation
|
|
19
|
+
- locktype
|
|
20
|
+
- mode
|
|
21
|
+
- granted
|
|
22
|
+
- waiting
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Long running queries
|
|
2
|
+
# Report with parameter filtering and title interpolation
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: long_running_queries
|
|
6
|
+
module: connections
|
|
7
|
+
description: "Queries running for extended duration"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: connections
|
|
11
|
+
file: long_running_queries
|
|
12
|
+
|
|
13
|
+
title: "Long Running Queries (>= ${min_duration_seconds}s)"
|
|
14
|
+
title_vars:
|
|
15
|
+
min_duration_seconds:
|
|
16
|
+
source: param
|
|
17
|
+
key: min_duration_seconds
|
|
18
|
+
|
|
19
|
+
columns:
|
|
20
|
+
- pid
|
|
21
|
+
- database
|
|
22
|
+
- username
|
|
23
|
+
- duration_seconds
|
|
24
|
+
- state
|
|
25
|
+
- query
|
|
26
|
+
|
|
27
|
+
parameters:
|
|
28
|
+
min_duration_seconds:
|
|
29
|
+
type: integer
|
|
30
|
+
default: 60
|
|
31
|
+
description: "Minimum query duration in seconds"
|
|
32
|
+
|
|
33
|
+
filters:
|
|
34
|
+
- field: duration_seconds
|
|
35
|
+
operator: gte
|
|
36
|
+
value:
|
|
37
|
+
source: param
|
|
38
|
+
key: min_duration_seconds
|
|
39
|
+
cast: float
|
|
40
|
+
|
|
41
|
+
problem_explanations:
|
|
42
|
+
duration_seconds: long_running
|
|
43
|
+
duration: long_running
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Bloated indexes - indexes with high bloat
|
|
2
|
+
# Report with threshold filtering and title interpolation
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: bloated_indexes
|
|
6
|
+
module: indexes
|
|
7
|
+
description: "Indexes with high bloat percentage"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: indexes
|
|
11
|
+
file: bloated_indexes
|
|
12
|
+
|
|
13
|
+
title: "Bloated Indexes (bloat >= ${threshold}%)"
|
|
14
|
+
title_vars:
|
|
15
|
+
threshold:
|
|
16
|
+
source: config
|
|
17
|
+
key: bloat_threshold_percent
|
|
18
|
+
|
|
19
|
+
columns:
|
|
20
|
+
- schema
|
|
21
|
+
- table_name
|
|
22
|
+
- index_name
|
|
23
|
+
- index_size_mb
|
|
24
|
+
- bloat_size_mb
|
|
25
|
+
- bloat_percent
|
|
26
|
+
|
|
27
|
+
parameters:
|
|
28
|
+
limit:
|
|
29
|
+
type: integer
|
|
30
|
+
default: 20
|
|
31
|
+
description: "Maximum number of results"
|
|
32
|
+
|
|
33
|
+
filters:
|
|
34
|
+
- field: bloat_percent
|
|
35
|
+
operator: gte
|
|
36
|
+
value:
|
|
37
|
+
source: config
|
|
38
|
+
key: bloat_threshold_percent
|
|
39
|
+
cast: float
|
|
40
|
+
|
|
41
|
+
problem_explanations:
|
|
42
|
+
bloat_ratio: high_bloat
|
|
43
|
+
bloat_size: high_bloat
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Duplicate indexes - indexes that may be redundant
|
|
2
|
+
# Simple report with no filtering or parameters
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: duplicate_indexes
|
|
6
|
+
module: indexes
|
|
7
|
+
description: "Indexes that may be redundant"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: indexes
|
|
11
|
+
file: duplicate_indexes
|
|
12
|
+
|
|
13
|
+
title: "Duplicate Indexes"
|
|
14
|
+
|
|
15
|
+
columns:
|
|
16
|
+
- table_name
|
|
17
|
+
- index_name
|
|
18
|
+
- duplicate_of
|
|
19
|
+
- index_size_mb
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Index sizes - largest indexes by size
|
|
2
|
+
# Report with title interpolation using limit parameter
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: index_sizes
|
|
6
|
+
module: indexes
|
|
7
|
+
description: "Largest indexes by size"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: indexes
|
|
11
|
+
file: index_sizes
|
|
12
|
+
|
|
13
|
+
title: "Index Sizes (top ${limit})"
|
|
14
|
+
title_vars:
|
|
15
|
+
limit:
|
|
16
|
+
source: param
|
|
17
|
+
key: limit
|
|
18
|
+
|
|
19
|
+
columns:
|
|
20
|
+
- schema
|
|
21
|
+
- table_name
|
|
22
|
+
- index_name
|
|
23
|
+
- index_size_mb
|
|
24
|
+
|
|
25
|
+
parameters:
|
|
26
|
+
limit:
|
|
27
|
+
type: integer
|
|
28
|
+
default: 50
|
|
29
|
+
description: "Maximum number of results"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Index usage statistics
|
|
2
|
+
# Simple report with limit parameter
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: index_usage
|
|
6
|
+
module: indexes
|
|
7
|
+
description: "Index usage statistics showing scan counts and tuples read"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: indexes
|
|
11
|
+
file: index_usage
|
|
12
|
+
|
|
13
|
+
title: "Index Usage Statistics"
|
|
14
|
+
|
|
15
|
+
columns:
|
|
16
|
+
- schema
|
|
17
|
+
- table_name
|
|
18
|
+
- index_name
|
|
19
|
+
- idx_scan
|
|
20
|
+
- idx_tup_read
|
|
21
|
+
- index_size_mb
|
|
22
|
+
|
|
23
|
+
parameters:
|
|
24
|
+
limit:
|
|
25
|
+
type: integer
|
|
26
|
+
default: 50
|
|
27
|
+
description: "Maximum number of results"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Invalid indexes - indexes that are not valid (e.g., failed to build)
|
|
2
|
+
# Simple report with no filtering or parameters
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: invalid_indexes
|
|
6
|
+
module: indexes
|
|
7
|
+
description: "Indexes that are not valid (e.g., failed to build)"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: indexes
|
|
11
|
+
file: invalid_indexes
|
|
12
|
+
|
|
13
|
+
title: "Invalid Indexes"
|
|
14
|
+
|
|
15
|
+
columns:
|
|
16
|
+
- schema
|
|
17
|
+
- table_name
|
|
18
|
+
- index_name
|
|
19
|
+
- index_definition
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Missing indexes - tables with high sequential scans
|
|
2
|
+
# Simple report with limit parameter
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: missing_indexes
|
|
6
|
+
module: indexes
|
|
7
|
+
description: "Tables with high sequential scans that may benefit from indexes"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: indexes
|
|
11
|
+
file: missing_indexes
|
|
12
|
+
|
|
13
|
+
title: "Tables Potentially Missing Indexes"
|
|
14
|
+
|
|
15
|
+
columns:
|
|
16
|
+
- schema
|
|
17
|
+
- table_name
|
|
18
|
+
- seq_scan
|
|
19
|
+
- seq_tup_read
|
|
20
|
+
- idx_scan
|
|
21
|
+
- table_size_mb
|
|
22
|
+
|
|
23
|
+
parameters:
|
|
24
|
+
limit:
|
|
25
|
+
type: integer
|
|
26
|
+
default: 20
|
|
27
|
+
description: "Maximum number of results"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Unused indexes - indexes that are rarely or never scanned
|
|
2
|
+
# These indexes waste disk space and slow down writes
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: unused_indexes
|
|
6
|
+
module: indexes
|
|
7
|
+
description: "Indexes that are rarely or never scanned"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: indexes
|
|
11
|
+
file: unused_indexes
|
|
12
|
+
|
|
13
|
+
title: "Unused Indexes (scans <= ${threshold})"
|
|
14
|
+
title_vars:
|
|
15
|
+
threshold:
|
|
16
|
+
source: config
|
|
17
|
+
key: unused_index_threshold_scans
|
|
18
|
+
|
|
19
|
+
columns:
|
|
20
|
+
- schema
|
|
21
|
+
- table_name
|
|
22
|
+
- index_name
|
|
23
|
+
- idx_scan
|
|
24
|
+
- index_size_mb
|
|
25
|
+
|
|
26
|
+
parameters:
|
|
27
|
+
limit:
|
|
28
|
+
type: integer
|
|
29
|
+
default: 50
|
|
30
|
+
description: "Maximum number of results"
|
|
31
|
+
|
|
32
|
+
filters:
|
|
33
|
+
- field: idx_scan
|
|
34
|
+
operator: lte
|
|
35
|
+
value:
|
|
36
|
+
source: config
|
|
37
|
+
key: unused_index_threshold_scans
|
|
38
|
+
cast: integer
|
|
39
|
+
|
|
40
|
+
problem_explanations:
|
|
41
|
+
idx_scan: unused_index
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# All query statistics ordered by total time
|
|
2
|
+
# Simple report with enrichment and title interpolation
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: all_queries
|
|
6
|
+
module: queries
|
|
7
|
+
description: "All query statistics ordered by total time"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: queries
|
|
11
|
+
file: all_queries
|
|
12
|
+
|
|
13
|
+
title: "All Query Statistics (top ${limit})"
|
|
14
|
+
title_vars:
|
|
15
|
+
limit:
|
|
16
|
+
source: param
|
|
17
|
+
key: limit
|
|
18
|
+
|
|
19
|
+
columns:
|
|
20
|
+
- query
|
|
21
|
+
- source
|
|
22
|
+
- calls
|
|
23
|
+
- total_time_ms
|
|
24
|
+
- mean_time_ms
|
|
25
|
+
- rows
|
|
26
|
+
|
|
27
|
+
parameters:
|
|
28
|
+
limit:
|
|
29
|
+
type: integer
|
|
30
|
+
default: 50
|
|
31
|
+
description: "Maximum number of results"
|
|
32
|
+
|
|
33
|
+
enrichment:
|
|
34
|
+
hook: enrich_with_annotations
|
|
35
|
+
module: queries
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Expensive queries - queries consuming most total time
|
|
2
|
+
# Report with threshold filtering, enrichment, and title interpolation
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: expensive_queries
|
|
6
|
+
module: queries
|
|
7
|
+
description: "Queries consuming most total execution time"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: queries
|
|
11
|
+
file: expensive_queries
|
|
12
|
+
|
|
13
|
+
title: "Expensive Queries (total time >= ${threshold}ms)"
|
|
14
|
+
title_vars:
|
|
15
|
+
threshold:
|
|
16
|
+
source: config
|
|
17
|
+
key: expensive_query_threshold_ms
|
|
18
|
+
|
|
19
|
+
columns:
|
|
20
|
+
- query
|
|
21
|
+
- source
|
|
22
|
+
- calls
|
|
23
|
+
- total_time_ms
|
|
24
|
+
- percent_of_total
|
|
25
|
+
- mean_time_ms
|
|
26
|
+
|
|
27
|
+
parameters:
|
|
28
|
+
limit:
|
|
29
|
+
type: integer
|
|
30
|
+
default: 20
|
|
31
|
+
description: "Maximum number of results"
|
|
32
|
+
|
|
33
|
+
filters:
|
|
34
|
+
- field: total_time_ms
|
|
35
|
+
operator: gte
|
|
36
|
+
value:
|
|
37
|
+
source: config
|
|
38
|
+
key: expensive_query_threshold_ms
|
|
39
|
+
cast: float
|
|
40
|
+
|
|
41
|
+
enrichment:
|
|
42
|
+
hook: enrich_with_annotations
|
|
43
|
+
module: queries
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Heavy queries - queries called most frequently
|
|
2
|
+
# Report with threshold filtering, enrichment, and title interpolation
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: heavy_queries
|
|
6
|
+
module: queries
|
|
7
|
+
description: "Queries called most frequently"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: queries
|
|
11
|
+
file: heavy_queries
|
|
12
|
+
|
|
13
|
+
title: "Heavy Queries (calls >= ${threshold})"
|
|
14
|
+
title_vars:
|
|
15
|
+
threshold:
|
|
16
|
+
source: config
|
|
17
|
+
key: heavy_query_threshold_calls
|
|
18
|
+
|
|
19
|
+
columns:
|
|
20
|
+
- query
|
|
21
|
+
- source
|
|
22
|
+
- calls
|
|
23
|
+
- total_time_ms
|
|
24
|
+
- mean_time_ms
|
|
25
|
+
- cache_hit_ratio
|
|
26
|
+
|
|
27
|
+
parameters:
|
|
28
|
+
limit:
|
|
29
|
+
type: integer
|
|
30
|
+
default: 20
|
|
31
|
+
description: "Maximum number of results"
|
|
32
|
+
|
|
33
|
+
filters:
|
|
34
|
+
- field: calls
|
|
35
|
+
operator: gte
|
|
36
|
+
value:
|
|
37
|
+
source: config
|
|
38
|
+
key: heavy_query_threshold_calls
|
|
39
|
+
cast: integer
|
|
40
|
+
|
|
41
|
+
enrichment:
|
|
42
|
+
hook: enrich_with_annotations
|
|
43
|
+
module: queries
|
|
44
|
+
|
|
45
|
+
problem_explanations:
|
|
46
|
+
calls: high_calls
|
|
47
|
+
total_time_ms: high_total_time
|
|
48
|
+
mean_time_ms: high_mean_time
|
|
49
|
+
cache_hit_ratio: low_cache_hit
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Queries with low cache hit ratio
|
|
2
|
+
# Report with parameter filtering, enrichment, and title interpolation
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: low_cache_hit_queries
|
|
6
|
+
module: queries
|
|
7
|
+
description: "Queries with poor cache utilization"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: queries
|
|
11
|
+
file: low_cache_hit_queries
|
|
12
|
+
|
|
13
|
+
title: "Queries with Low Cache Hit Ratio (min ${min_calls} calls)"
|
|
14
|
+
title_vars:
|
|
15
|
+
min_calls:
|
|
16
|
+
source: param
|
|
17
|
+
key: min_calls
|
|
18
|
+
|
|
19
|
+
columns:
|
|
20
|
+
- query
|
|
21
|
+
- source
|
|
22
|
+
- calls
|
|
23
|
+
- cache_hit_ratio
|
|
24
|
+
- shared_blks_hit
|
|
25
|
+
- shared_blks_read
|
|
26
|
+
|
|
27
|
+
parameters:
|
|
28
|
+
limit:
|
|
29
|
+
type: integer
|
|
30
|
+
default: 20
|
|
31
|
+
description: "Maximum number of results"
|
|
32
|
+
min_calls:
|
|
33
|
+
type: integer
|
|
34
|
+
default: 100
|
|
35
|
+
description: "Minimum number of calls to include"
|
|
36
|
+
|
|
37
|
+
filters:
|
|
38
|
+
- field: calls
|
|
39
|
+
operator: gte
|
|
40
|
+
value:
|
|
41
|
+
source: param
|
|
42
|
+
key: min_calls
|
|
43
|
+
cast: integer
|
|
44
|
+
|
|
45
|
+
enrichment:
|
|
46
|
+
hook: enrich_with_annotations
|
|
47
|
+
module: queries
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Queries missing indexes - sequential scans on large tables
|
|
2
|
+
# Simple report with enrichment
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: missing_index_queries
|
|
6
|
+
module: queries
|
|
7
|
+
description: "Queries with sequential scans that may benefit from indexes"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: queries
|
|
11
|
+
file: missing_index_queries
|
|
12
|
+
|
|
13
|
+
title: "Queries Potentially Missing Indexes"
|
|
14
|
+
|
|
15
|
+
columns:
|
|
16
|
+
- query
|
|
17
|
+
- source
|
|
18
|
+
- calls
|
|
19
|
+
- seq_scan_count
|
|
20
|
+
- rows_examined
|
|
21
|
+
- table_name
|
|
22
|
+
|
|
23
|
+
parameters:
|
|
24
|
+
limit:
|
|
25
|
+
type: integer
|
|
26
|
+
default: 20
|
|
27
|
+
description: "Maximum number of results"
|
|
28
|
+
|
|
29
|
+
enrichment:
|
|
30
|
+
hook: enrich_with_annotations
|
|
31
|
+
module: queries
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Slow queries - queries with high mean execution time
|
|
2
|
+
# Report with threshold filtering, enrichment, and title interpolation
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: slow_queries
|
|
6
|
+
module: queries
|
|
7
|
+
description: "Queries with high mean execution time"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: queries
|
|
11
|
+
file: slow_queries
|
|
12
|
+
|
|
13
|
+
title: "Slow Queries (mean time >= ${threshold}ms)"
|
|
14
|
+
title_vars:
|
|
15
|
+
threshold:
|
|
16
|
+
source: config
|
|
17
|
+
key: slow_query_threshold_ms
|
|
18
|
+
|
|
19
|
+
columns:
|
|
20
|
+
- query
|
|
21
|
+
- source
|
|
22
|
+
- calls
|
|
23
|
+
- mean_time_ms
|
|
24
|
+
- total_time_ms
|
|
25
|
+
- rows_per_call
|
|
26
|
+
|
|
27
|
+
parameters:
|
|
28
|
+
limit:
|
|
29
|
+
type: integer
|
|
30
|
+
default: 20
|
|
31
|
+
description: "Maximum number of results"
|
|
32
|
+
|
|
33
|
+
filters:
|
|
34
|
+
- field: mean_time_ms
|
|
35
|
+
operator: gte
|
|
36
|
+
value:
|
|
37
|
+
source: config
|
|
38
|
+
key: slow_query_threshold_ms
|
|
39
|
+
cast: float
|
|
40
|
+
|
|
41
|
+
enrichment:
|
|
42
|
+
hook: enrich_with_annotations
|
|
43
|
+
module: queries
|
|
44
|
+
|
|
45
|
+
problem_explanations:
|
|
46
|
+
mean_time_ms: high_mean_time
|
|
47
|
+
calls: high_calls
|
|
48
|
+
total_time_ms: high_total_time
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Database activity overview
|
|
2
|
+
# Simple report showing current database activity metrics
|
|
3
|
+
|
|
4
|
+
report:
|
|
5
|
+
name: activity_overview
|
|
6
|
+
module: system
|
|
7
|
+
description: "Current database activity overview"
|
|
8
|
+
|
|
9
|
+
sql:
|
|
10
|
+
category: system
|
|
11
|
+
file: activity_overview
|
|
12
|
+
|
|
13
|
+
title: "Database Activity Overview"
|
|
14
|
+
|
|
15
|
+
columns:
|
|
16
|
+
- metric
|
|
17
|
+
- value
|