Skip to content

Commit 96a93f6

Browse files
committed
feat: add interactive diagnostic graph and log events for v0.14.0
1 parent 6386841 commit 96a93f6

63 files changed

Lines changed: 12092 additions & 195 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎README.md‎

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,8 +1051,9 @@ visible in stdout and `report.log`.
10511051
server `csvlog` files for a bounded time window, collapses floods of identical
10521052
errors into series, sanitizes messages, and renders items such as the error
10531053
chronology, top errors and warnings by frequency, crash and recovery markers,
1054-
deadlocks, authentication failures, and a stacked time chart of slow-query
1055-
plans written by `auto_explain`.
1054+
deadlocks, authentication failures, system/lifecycle/replication incidents,
1055+
query termination and resource events, heavy maintenance, and a stacked time
1056+
chart of slow-query plans written by `auto_explain`.
10561057

10571058
Flag semantics:
10581059

@@ -1083,20 +1084,30 @@ Collection mode support:
10831084
| `remote-db-only` | Not supported by design; items report `unsupported` |
10841085

10851086
Requirements on the server: `logging_collector = on`, `csvlog` in
1086-
`log_destination`, English or C `lc_messages`, and read access to the log
1087-
directory for the OS user running `pg-diag`. The complete privilege setup,
1088-
including the ACL commands and the `log_file_mode` interaction, is documented
1087+
`log_destination`, and read access to the log directory for the OS user running
1088+
`pg-diag`. English, C, or POSIX `lc_messages` enables every content item. With
1089+
another locale, SQLSTATE-driven authentication failures and deadlocks remain
1090+
fully available. Query termination and system incidents remain available with
1091+
explicit `structured_sqlstate_only` partial coverage; items that require
1092+
localized message text report `unsupported`, and the log-file overview is
1093+
locale-independent. The complete
1094+
privilege setup, including the ACL commands and the `log_file_mode` interaction,
1095+
is documented
10891096
in [docs/access-best-practices.md](docs/access-best-practices.md#server-log-access-optional).
10901097
No additional PostgreSQL grants are needed: the reference `pgdiag` role already
10911098
covers `pg_ls_logdir()`, `pg_current_logfile()`, and the log-related settings
10921099
through `pg_monitor`.
10931100

1094-
The current release ships thirteen log items: the error chronology, top errors
1101+
The current release ships nineteen log items: the error chronology, top errors
10951102
and top warnings by frequency, crash and recovery markers, deadlocks,
10961103
authentication failures, autovacuum runs, checkpoints, WAL archiver failures,
10971104
transaction ID wraparound pressure, lock waits, `auto_explain` plans by
1098-
duration, and the log files overview (the last one needs only `pg_monitor`, no
1099-
log-content access). The `auto_explain` chart uses clock-aligned one-minute
1105+
duration, the log files overview, plus system incidents, server lifecycle,
1106+
replication/WAL transport events, query terminations by minute, query time/temp
1107+
file groups, and heavy/failed maintenance (the log overview needs only
1108+
`pg_monitor`, no log-content access). Chart event text and plans use bounded,
1109+
deduplicated references so repeated events do not duplicate large payloads.
1110+
The `auto_explain` chart uses clock-aligned one-minute
11001111
columns and keeps the ten longest logged queries in each minute. Every stacked
11011112
block represents one query; its tooltip shows the exact log timestamp,
11021113
duration, and a sanitized query sample capped at 300 characters. Clicking a
@@ -1282,6 +1293,40 @@ The bundled content pack includes sections for:
12821293
Availability depends on PostgreSQL version, installed extensions, database
12831294
permissions, collection mode, and host permissions.
12841295

1296+
### Diagnostic Graph
1297+
1298+
The HTML report opens with a diagnostic graph: five roots (`cpu`, `ram`,
1299+
`disk`, `database_health`, `database_security`), each with a cause tree
1300+
underneath, drawn as a top-down tree with siblings side by side on a zoomable,
1301+
pannable canvas. Root names sit inside enlarged circles. Drag to pan, scroll
1302+
to zoom, or use the in-canvas minus/plus, Fit and 1:1 controls. Every node is bound to the report
1303+
items that carry its evidence (every catalog item is bound to at least one
1304+
node), and its color is computed in the browser from the raw item data: green
1305+
to red by score, grey when the report has no data for it. Resource causes such
1306+
as sequential scans or checkpoint bursts are weighted by the pressure of their
1307+
resource. CPU separates user work, system work, I/O wait and hypervisor steal;
1308+
I/O-wait contributors use I/O-wait pressure, not user CPU. RAM separates
1309+
available memory/OOM, swap usage and cache misses. Disk separates device
1310+
latency, reads, writes and free space, with the relevant causes underneath.
1311+
The final branch score is the maximum of its own evidence and its children;
1312+
a critical child always lights the path to its root. I/O wait is not counted
1313+
as CPU work, and replay age alone does not make an idle, caught-up standby
1314+
unhealthy. Log evidence is classified by event type; overlapping error and
1315+
deadlock sources are not added together. Scores are internal color heuristics,
1316+
not displayed percentages. Labels use OK / Warning / Critical / No data,
1317+
including for security risks. Cause arrows appear only for the selected node
1318+
and run through clear lanes between levels.
1319+
Clicking a node unfolds a details card directly underneath it inside the canvas, showing why it has its
1320+
color, the facts behind it, hints about missing data (for example "run snapshots mode" or "use local or remote
1321+
collection mode"), related causes across the graph, and the bound items; clicking
1322+
an item scrolls the report to it. Cards scale and pan with the graph. The layout
1323+
animates to make room for their full content, with the clicked node anchored
1324+
and zoom unchanged; click the node again to close. Reduced-motion preferences
1325+
are respected. The module lives in
1326+
`src/pg_diag/render/graph/` (`graph.json` is the declarative graph,
1327+
`pg-diag-graph.js` the evaluation engine, `pg-diag-graph-render.js` the
1328+
renderer) and is specified in `DIAGNOSTIC_GRAPH_SPEC.md` next to it.
1329+
12851330
Repeated table samples store their column schema once in `snapshot_schemas` and
12861331
keep only status, rows, and an optional failure reason in each snapshot point.
12871332
Raw snapshot points are not duplicated into the self-contained HTML after

‎docs/access-best-practices.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,10 @@ log_directory = '/var/log/postgresql' # recommended outside the data direct
286286
log_file_mode = 0640 # sighup; REQUIRED for the ACL below to work
287287
log_rotation_age = 1d
288288
log_rotation_size = 100MB
289-
lc_messages = 'C' # or en_*; localized logs make pattern
290-
# matching unreliable and the items report
291-
# unsupported instead of a false "no errors"
289+
lc_messages = 'C' # C/POSIX or en_* enables every content item;
290+
# with other locales, SQLSTATE-driven
291+
# auth/deadlock items still work, while
292+
# localized-text items report unsupported
292293
```
293294

294295
### Filesystem permissions

‎docs/server-configuration.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,15 @@ is documented in
122122
| `log_directory` | outside PGDATA | Cleaner permissions story for the collector account |
123123
| `log_file_mode` | `0640` | Required for the documented ACL recipe to survive rotation |
124124
| `log_rotation_age` / `log_rotation_size` | `1d` / `100MB` | Bounded files; `log_files_overview` flags disabled rotation as a finding |
125-
| `lc_messages` | `'C'` or `en_*` | Localized logs make pattern matching unreliable; the items then report `unsupported` instead of a false "no errors" |
125+
| `lc_messages` | `C`, `POSIX`, or `en_*` recommended | Enables all content items. With another locale, SQLSTATE-driven authentication failures/deadlocks remain complete; query termination and system incidents report structured-only partial coverage; the file overview remains complete; localized-message items report `unsupported`. |
126126
| `log_checkpoints` | `on` (default since PG15) | `checkpoints`: trigger reason, buffers, write/sync timings |
127-
| `log_autovacuum_min_duration` | `0` (or a ms threshold) | `autovacuum_runs`: per-run chronology with relations |
127+
| `log_autovacuum_min_duration` | workload-specific ms threshold | `autovacuum_runs` chronology and `maintenance_events`; the latter emits only failures/emergencies/lock waits or successful runs crossing its documented 5 s / 128 MiB / 64 MiB thresholds |
128128
| `log_lock_waits` | `on` | Lock-wait history from the log (waits longer than `deadlock_timeout`); also enriches the error chronology |
129129
| `auto_explain.log_min_duration` | workload-specific threshold | `auto_explain_plans`: ten longest logged queries per minute |
130130
| `auto_explain.log_format` | `json` recommended | Machine-readable plan validation; text, XML, and YAML are also recognized |
131131
| `auto_explain.log_parameter_max_length` | `0` | Avoid logging bind-parameter values alongside plans |
132-
| `log_temp_files` | `0` (or a KB threshold) | Temp-file spill evidence in the log (planned item; already useful raw) |
132+
| `log_min_duration_statement` | workload-specific ms threshold | Duration groups in `query_resource_events`; avoid `0` on high-QPS production systems |
133+
| `log_temp_files` | workload-specific KiB threshold | Temporary-file groups and total/max spill bytes in `query_resource_events` |
133134
| `log_connections` / `log_disconnections` | optional | Connection-churn evidence; high volume — enable deliberately |
134135

135136
Errors, FATAL/PANIC events, deadlocks (`deadlock detected`), authentication

‎pyproject.toml‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "pg-diag"
7-
version = "0.13.0"
7+
version = "0.14.0"
88
description = "PostgreSQL diagnostics with host metrics and portable JSON/HTML reports"
99
readme = "README.md"
1010
requires-python = ">=3.10"
@@ -84,6 +84,10 @@ pg_diag = [
8484
"render/vendor/*.css",
8585
"render/vendor/*.js",
8686
"render/vendor/*.txt",
87+
"render/graph/*.css",
88+
"render/graph/*.js",
89+
"render/graph/*.json",
90+
"render/graph/*.md",
8791
]
8892

8993
[tool.setuptools.exclude-package-data]

‎src/pg_diag/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""pg_diag package."""
22

3-
__version__ = "0.13.0"
3+
__version__ = "0.14.0"

0 commit comments

Comments
 (0)