Architecture Overview¶
This chapter is a map of the framework's moving parts — what each table and function is for, and how they connect. You don't need to memorise it before using the framework day to day, but it's a useful chapter to come back to when something isn't behaving the way you expect.
The catalog¶
- Namespaces and categories are the top two levels of organisation. pg_health_framework seeds one namespace,
PGHF("PostgreSQL Health Framework"), with 15 categories underneath it — for example category01, "Connection & Availability." Namespaces and categories are maintained only through their own registration functions, each of which can also activate or inactivate the row it manages — see Inactivating a Namespace or Category. - Checks are the repository itself — what a check is: which function backs it, its namespace/category/run number, the metadata describing its result (see Metadata Columns Explained), and a required explanation of why it matters. Every check has two identifiers: a permanent, invisible internal ID that every other table actually points to, and the human-readable check ID (
PGHF01-006-style) computed from its namespace, category, and run number — renumbering a check recomputes its check ID automatically. Checks are maintained only through their own registration functions — direct table edits are blocked. pghf.seed_data()is the one function that writes this project's own catalog data: thePGHFnamespace, its 15 categories, all 165 built-in checks, the ready-made suites, and their default thresholds. It runs once automatically at install time, and is safe to run again yourself at any point to reset the built-in catalog back to what your installed version ships — see Resetting to Defaults.
Suites and runs¶
- Suites (internally called "check runs") are named, ordered lists of checks —
default, or one you create yourself. A suite doesn't care which namespace or category a check came from, so mixing your own checks in with built-in ones in a single suite is normal, not a special case. - Runs are one row per actual execution of a suite, together with the raw data each check collected and any extra parameters that execution was given (for example, which PostgreSQL version to check upgrade-readiness against).
- The collection engine is the single procedure that runs every member of a suite, in order, calling each one's backing function and recording what came back. Every check is committed to the database as soon as it finishes, one at a time, so an interrupted run leaves you with a complete, real result for everything collected up to that point — not a half-written mess.
Thresholds and evaluation¶
- Thresholds are how you tell the framework what a good or bad result looks like — a check-level default that applies everywhere, optionally overridden for a specific suite. Thresholds are maintained only through their own registration function.
- Evaluations are one row per check per run — the severity a check's collected data was actually judged to be. Written only by the evaluation engine described next.
- The evaluation engine is the single procedure that judges an already-collected run's data against the thresholds configured for it. It is entirely separate from collection: it never re-runs a check, only reads what an earlier collection pass already recorded.
- A convenience function runs collection and evaluation together in one call, for the common case where you always want both.
Reading results back out¶
- One function returns a run's results as a single block of structured data, meant for another piece of software to consume (a notification pipeline, a webhook, a dashboard).
- A second function returns the same data as an ordinary, human-readable result set — worst severity first — meant for a database administrator reading output directly at the command line.
- A separate function reports the raw counts that let you delete old history in bulk, once you decide you no longer need it.
What a check actually is¶
A check is nothing more than an ordinary PostgreSQL function with one fixed shape: it takes the ID of the current run, and returns a specific, framework-defined structure recording what it observed. The collection engine has no built-in knowledge of any individual check at all — it looks up which function backs a given check and calls it. This is the entire mechanism that makes the framework extensible: register a function with the right shape, and it runs, with nothing else needing to change. See Creating Your Own Checks and Thresholds and the dedicated Adding Your Own Checks book for the full walkthrough.
A check that needs something specific to be true before it can collect anything — for example, a check that only makes sense on a server that's part of a Spock replication cluster — tests for that itself, inside its own function body, and reports that it was skipped if the condition isn't met. The collection engine itself has no special-case logic for any particular kind of check; every data prerequisite lives inside the check that needs it.
Continue to Using the Seed Catalog.