Skip to content

feat(render): gauge strip and checked line in the default inspect view - #43

Merged
alexshapalov merged 1 commit into
mainfrom
feat/gauge-strip
Sep 9, 2026
Merged

alexshapalov merged 1 commit into
mainfrom
feat/gauge-strip

Conversation

@alexshapalov

Copy link
Copy Markdown
Contributor

What changes

The default `pgbot inspect` view gets a four-row gauge strip right under the header, and the GOOD bullet list becomes a compact `checked · …` line. Score, CRITICAL/WARNING/NOTE bullets and the footer stay. `--full`, `--json`, MCP, SARIF and the HTML report are untouched.

```
connected · prod-eu-1 · postgres 16.3 · read-only · 6h window

cache hit [████████████████████] 99.2% ok
lock wait [████████████░░░░░░░░] 61.0% query 4f2a
rollbacks [██░░░░░░░░░░░░░░░░░░] 12.0% watch
idle idx [██████░░░░░░░░░░░░░░] 43.0 GiB review

checked · queries · vacuum · replication · checkpoints
· connections · settings · deadlocks

Database health: 82/100
```

The four gauges

Each row is a label, a 20-cell bar (rounded to the nearest cell, one-cell minimum for any non-zero value), a value, and a status word driven by the finding that grades the same signal — never a threshold of its own.

  • cache hit — sampled ratio; `ok`, or `low` when `low_cache_hit` fired. Under the block threshold the row reads `— thin sample`, dim.
  • lock wait — the Lock bucket's share of sampled active time from the wait profile. `ok` with no blocked sessions; with blocked sessions it names the culprit (`query <4 hex of query_id>`, highest lock share), falling back to `N blocked`. Without a wait profile the value is `—` and only the status shows.
  • rollbacks — rollback ratio; `ok` or `watch` when `high_rollback_ratio` fired. Nil ratio → not measurable.
  • idle idx — summed size of zero-scan indexes; fill is that size over database size (the model has no total-index-bytes, and db size is the honest stand-in). `ok` or `review` when `unused_indexes` fired. Cold window → dim `window < 15m`.

The checked line

Subsystems that were collected and produced no finding, fixed order: queries, indexes, vacuum, replication, checkpoints, connections, settings, wraparound, deadlocks. A subsystem whose gauge is already orange/red is left out so the line never contradicts the strip. Wraps whole items with an eight-space hanging indent. Skipped under the schema profile, like GOOD was.

Files

  • `internal/render/gauges.go` — new: the four gauges, the strip, the checked list and its renderer.
  • `internal/render/dashboard.go` — calls them before the score, drops the GOOD block and `buildGood`.
  • `internal/render/gauges_test.go` — fill rounding, every not-measurable state, culprit selection (incl. negative query ids), exact no-color layout, 80-column width, checked ordering/exclusion/wrapping, schema skip.
  • `terminal_test.go` GOOD expectations updated; grouped golden regenerated (bullets unchanged).
  • README quickstart sample, CHANGELOG.

Four vital signs right under the header — cache hit, lock wait (naming
the culprit query when sessions are blocked), rollbacks, and idle index
bytes as a share of the database — each a 20-cell bar, a value and a
one-word status driven by the finding that grades the same signal.
Unmeasurable signals render dim with — and say why (thin sample,
window < 15m, not measurable). The GOOD bullet list becomes a compact
'checked · queries · vacuum · …' line of the subsystems that were
collected and produced no finding, wrapped with a hanging indent. Both
are skipped under the schema profile, like GOOD was. Score, severity
bullets, --full, --json, MCP, SARIF and the HTML report are unchanged.
Footer ask hint now reads: pgbot ask "why is it slow?".
@alexshapalov
alexshapalov merged commit e3cb8e3 into main Sep 9, 2026
17 checks passed
@alexshapalov
alexshapalov deleted the feat/gauge-strip branch September 9, 2026 04:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant