Class: StandardHealth::Checks::EnvSpecAudit
- Inherits:
-
StandardHealth::Check
- Object
- StandardHealth::Check
- StandardHealth::Checks::EnvSpecAudit
- Defined in:
- lib/standard_health/checks/env_spec_audit.rb
Overview
Surfaces EnvSpec violations as a health check.
WHY THIS EXISTS
The env-spec audit is otherwise only visible on /diagnostics/env,
which is authed and polled by nobody. So hosts that wanted config drift
to show up on a health tier wrote their own check to re-derive it —
fundbright-web carried two (ForbiddenToggles, CspEnforcement) built
from hand-maintained constant lists that had to be kept in sync with the
env spec by comment. This check reads the spec directly, so there is one
declaration and no list to drift.
NOT REGISTERED AUTOMATICALLY. See Checks::SolidCable for the reasoning
— briefly: auto-registering would fail existing hosts on a bundle update the moment their spec had any pre-existing violation.
Register it yourself:
c.register_check :env_spec, StandardHealth::Checks::EnvSpecAudit
NON-CRITICAL BY DEFAULT, and that default is load-bearing. Config drift
is visibility, not a rotation signal: an instance with a stale toggle
set is still serving traffic correctly, and pulling it out of rotation
would convert a warning into an outage. It rolls the aggregate up to
:degraded (HTTP 200). Registering it critical: true means "this app
must not serve at all with a bad env", which is a real but rare posture
— and on the readiness tier it will pull instances. Know which you want.
To narrow what counts as a failure, or to make it critical, subclass —
the aggregator instantiates checks with name:/critical: only, so
per-registration options are not available:
class StrictEnvSpec < StandardHealth::Checks::EnvSpecAudit
def initialize(name: :env_spec, critical: false)
super(name: name, critical: critical, fail_on: %i[forbidden])
end
end
Constant Summary collapse
- VIOLATION_LABEL =
Reported as
error_classso the redacted body carries a groupableerror_code(standard_health_env_spec_violation) instead of a meaningless "StandardError". Not an exception class — nothing here raises — just a stable label. "StandardHealth::EnvSpecViolation"
Instance Attribute Summary collapse
-
#fail_on ⇒ Array<Symbol>
readonly
Audit statuses this check treats as failures.
Attributes inherited from StandardHealth::Check
Instance Method Summary collapse
-
#initialize(name: :env_spec, critical: false, fail_on: EnvSpec::VIOLATION_STATUSES) ⇒ EnvSpecAudit
constructor
A new instance of EnvSpecAudit.
- #run ⇒ Object
Methods inherited from StandardHealth::Check
Constructor Details
#initialize(name: :env_spec, critical: false, fail_on: EnvSpec::VIOLATION_STATUSES) ⇒ EnvSpecAudit
Returns a new instance of EnvSpecAudit.
52 53 54 55 |
# File 'lib/standard_health/checks/env_spec_audit.rb', line 52 def initialize(name: :env_spec, critical: false, fail_on: EnvSpec::VIOLATION_STATUSES) super(name: name, critical: critical) @fail_on = Array(fail_on).map(&:to_sym) end |
Instance Attribute Details
#fail_on ⇒ Array<Symbol> (readonly)
Returns audit statuses this check treats as failures.
58 59 60 |
# File 'lib/standard_health/checks/env_spec_audit.rb', line 58 def fail_on @fail_on end |
Instance Method Details
#run ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/standard_health/checks/env_spec_audit.rb', line 60 def run violations = nil # `with_timing` is what keeps the never-raise invariant: `audit` runs # host-supplied `if:`/`unless:` procs and can raise `UnknownModeAlias`, # and neither may reach the aggregator as an exception. timing = with_timing { violations = violating_rows } return timing unless timing[:status] == :ok return timing if violations.empty? timing.merge( status: :fail, error: describe(violations), error_class: VIOLATION_LABEL ) end |