standard_health 0.6.0 → 0.6.1
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 +12 -0
- data/README.md +24 -1
- data/lib/standard_health/aggregator.rb +28 -0
- data/lib/standard_health/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: 2c32e1366e2b116f86a8be7780d4717a35b07952402f14e213a2533530c30fe8
|
|
4
|
+
data.tar.gz: 7c0fe9a0993be6e1ef46adcd95f3ba6c05dc029e7f621557ea314eb0a7062f0e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad3e4a667c77a923dfa0ab49aa1de21f86923e7a1e30e7f7204c9ebb4c471f284f61c4f1d0a768155345da3fd46f10b7b77216d6feeeb0c9b799bc7f29bc02f7
|
|
7
|
+
data.tar.gz: '00853d5d4423f12269bf47f67692bcea3c43bc7da5ac9b64ff39fb9f080364131bea90156cc3fd41387d37421cef886695965c66d28fa024c9e3de418b07458b'
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.6.1] - 2026-09-24
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **A check that raises on the aggregate tier is reported to `Rails.error` again.** Before 0.6.0 every host's aggregate controller rescued a raising check and called `Rails.error.report(e, handled: true, ...)`. When the engine took over the tier, the exception was only logged by the Logger notifier, so a buggy aggregate check stopped reaching Sentry (noted in the jumpdrive-web and sidekick-web adoptions). The Aggregator now reports it as handled with context `{ health_check: <name>, tier: "aggregate" }`. Severity follows the readiness Sentry notifier: `:error` for a critical check, `:warning` otherwise. The readiness tier is unchanged. Its failures still reach Sentry through the transition-gated `ready.evaluated` notifier, which keeps a ~6/min probe from flooding the tracker. Checks that return a `:fail` row (every built-in check) are not reported. The report is rescued, so a broken error subscriber cannot 500 the tier.
|
|
15
|
+
|
|
16
|
+
### Documentation
|
|
17
|
+
|
|
18
|
+
- The aggregate tier re-runs the `register_check` readiness checks by default (`aggregate_readiness_checks = true`), so a failing critical check (database, Solid Queue) makes `/health` answer **503 `unavailable`**, not only `/ready`.
|
|
19
|
+
- The aggregate body reports `"unavailable"`, never StandardCircuit's `"critical"`. Monitors matching on `"critical"` need updating (as noted in 0.6.0's migration notes).
|
|
20
|
+
- `StandardHealth::DiagnosticsAuthentication` is the request-time gate behind `diagnostics_basic_auth`. The README now notes that a host can include it into its own diagnostics controller, as sidekick-web does. It is not yet a documented, semver-stable extension point.
|
|
21
|
+
|
|
10
22
|
## [0.6.0] - 2026-09-24
|
|
11
23
|
|
|
12
24
|
DX release: absorbs the code every consumer app copy-pasted around the engine.
|
data/README.md
CHANGED
|
@@ -109,14 +109,30 @@ end
|
|
|
109
109
|
| `degraded` | 200 | a non-critical check failed or was skipped, or the circuit roll-up is `:degraded` |
|
|
110
110
|
| `ok` | 200 | otherwise |
|
|
111
111
|
|
|
112
|
+
**The aggregate tier re-runs your readiness checks by default.** With
|
|
113
|
+
`aggregate_readiness_checks` on (the default), every `register_check`
|
|
114
|
+
registration runs here as well as on `/ready`. A failing critical check, such
|
|
115
|
+
as `:database` or `:solid_queue` from `register_default_checks`, therefore turns
|
|
116
|
+
`/health` into a **503 `unavailable`**, not just `/ready`. Point an uptime
|
|
117
|
+
monitor at `/health` and a database outage pages as a 503. If your aggregate
|
|
118
|
+
tier should only report soft signals (sidekick), set
|
|
119
|
+
`aggregate_readiness_checks = false`.
|
|
120
|
+
|
|
112
121
|
StandardCircuit's own word `critical` is translated to `unavailable`, so both
|
|
113
|
-
tiers speak one vocabulary. `circuits` is omitted when StandardCircuit isn't
|
|
122
|
+
tiers speak one vocabulary. The aggregate body never says `"critical"`. `circuits` is omitted when StandardCircuit isn't
|
|
114
123
|
loaded (or `aggregate_circuits = false`); if `health_report` raises (circuit
|
|
115
124
|
store down) the tier degrades and reports `circuits_error: { error_class,
|
|
116
125
|
error_code }` instead of 500ing. Check rows are redacted exactly like `/ready`,
|
|
117
126
|
with the same `detail_token` break-glass. `register_aggregate_check` checks
|
|
118
127
|
run **only** here — never on `/ready` — and default to `critical: false`.
|
|
119
128
|
|
|
129
|
+
A check that **raises** on this tier, rather than returning a `:fail` row, is
|
|
130
|
+
also reported to `Rails.error` as handled (since 0.6.1), with context
|
|
131
|
+
`{ health_check:, tier: "aggregate" }` and severity `:error` for a critical
|
|
132
|
+
check or `:warning` otherwise. That matches what the pre-0.6 host controllers
|
|
133
|
+
did. `/ready` does not do this: its failures reach Sentry through the
|
|
134
|
+
transition-gated `ready.evaluated` notifier.
|
|
135
|
+
|
|
120
136
|
With `aggregate_endpoint` off (the default) the engine's root route carries a
|
|
121
137
|
per-request constraint that never matches, so a bare `/health` cascades to your
|
|
122
138
|
own route exactly as before. Once on, the engine answers `/health` regardless
|
|
@@ -590,6 +606,13 @@ c.diagnostics_basic_auth = {
|
|
|
590
606
|
nothing.
|
|
591
607
|
- Off by default; independent of `diagnostics_parent_controller` (if you set
|
|
592
608
|
both, the parent's callbacks run first).
|
|
609
|
+
- The request-time gate is the `StandardHealth::DiagnosticsAuthentication`
|
|
610
|
+
concern, which the engine includes into its own `DiagnosticsController`.
|
|
611
|
+
sidekick-web also includes it into its own `HealthDiagnosticsController`
|
|
612
|
+
(an `ActionController::API` subclass) so that controller shares the same
|
|
613
|
+
gate. That works: the concern is a no-op until `diagnostics_basic_auth` is
|
|
614
|
+
set, and it adds one `before_action`. It is not yet a documented,
|
|
615
|
+
semver-stable extension point, so pin your minor version if you depend on it.
|
|
593
616
|
|
|
594
617
|
**Replace your host code with it.** Delete
|
|
595
618
|
`app/controllers/standard_health_host_controller.rb` and the
|
|
@@ -131,10 +131,38 @@ module StandardHealth
|
|
|
131
131
|
error_class: e.class.name
|
|
132
132
|
}
|
|
133
133
|
emit_check(row, tier)
|
|
134
|
+
report_raised_check(e, reg, tier)
|
|
134
135
|
row
|
|
135
136
|
end
|
|
136
137
|
private_class_method :safe_run
|
|
137
138
|
|
|
139
|
+
# A check that RAISES (rather than returning a :fail row) on a
|
|
140
|
+
# non-readiness tier goes to `Rails.error` as handled. Before 0.6.0 every
|
|
141
|
+
# host's aggregate controller did exactly this; moving the tier into the
|
|
142
|
+
# engine left the exception only in the Logger notifier's line, so a buggy
|
|
143
|
+
# aggregate check stopped reaching the error tracker.
|
|
144
|
+
#
|
|
145
|
+
# Readiness is deliberately excluded: its failures already reach Sentry
|
|
146
|
+
# through the transition-gated `ready.evaluated` notifier, and reporting
|
|
147
|
+
# every raise from a ~6/min/instance probe would be exactly the noise that
|
|
148
|
+
# notifier exists to prevent. Severity mirrors that notifier: a critical
|
|
149
|
+
# check is an :error (it makes the tier :unavailable), otherwise :warning.
|
|
150
|
+
def self.report_raised_check(error, reg, tier)
|
|
151
|
+
return if tier == :ready
|
|
152
|
+
return unless defined?(::Rails) && ::Rails.respond_to?(:error) && ::Rails.error
|
|
153
|
+
|
|
154
|
+
::Rails.error.report(
|
|
155
|
+
error,
|
|
156
|
+
handled: true,
|
|
157
|
+
severity: reg.critical ? :error : :warning,
|
|
158
|
+
context: { health_check: reg.name.to_s, tier: tier.to_s }
|
|
159
|
+
)
|
|
160
|
+
rescue StandardError
|
|
161
|
+
# Never-raise: a broken error subscriber must not 500 the tier.
|
|
162
|
+
nil
|
|
163
|
+
end
|
|
164
|
+
private_class_method :report_raised_check
|
|
165
|
+
|
|
138
166
|
def self.budget_exhausted?(budget, started)
|
|
139
167
|
return false unless budget
|
|
140
168
|
|