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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5845fe7433611028fb103afb457683b22717a8f1aa79848f425a2cd5d7c9bd7a
4
- data.tar.gz: c83d29991ba9b19b2ce234e5ef3cacabf198af323b97809927ef36608c49ba7e
3
+ metadata.gz: 2c32e1366e2b116f86a8be7780d4717a35b07952402f14e213a2533530c30fe8
4
+ data.tar.gz: 7c0fe9a0993be6e1ef46adcd95f3ba6c05dc029e7f621557ea314eb0a7062f0e
5
5
  SHA512:
6
- metadata.gz: eddef6b2df86d0ff116a63793b009f3b3afe81ed3f437fcd5f1fea15be0545ca2a384ea346bae3c12050ffc8f95183af4ee5414a8739ead14910b2bcd0a45ea5
7
- data.tar.gz: cb15f56c75ec0464412c16360d788b8f714d73c844a3e7bde8564295e56d2e56bdc63bb9c5987792efd65c8c3158e4e9b0edde991f0ea69e0a8dfecf93c9361f
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StandardHealth
4
- VERSION = "0.6.0"
4
+ VERSION = "0.6.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: standard_health
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaryl Sim