Add health endpoints for monitoring - #91
Open
turegjorup wants to merge 1 commit into
Open
Conversation
turegjorup
added a commit
that referenced
this pull request
Aug 3, 2026
turegjorup
force-pushed
the
feature/health-endpoint
branch
from
August 3, 2026 10:59
f17456f to
fb9945b
Compare
Add /health/live, /health/ready and /health/detail, with checks for the database, the RabbitMQ messenger transport and detection result freshness. Liveness touches no dependencies. Readiness reports the aggregated status only, never which dependency failed. The detailed endpoint discloses internals and is protected by the ITKBasicAuth Traefik middleware on its own router. ^/health is excluded from the Symfony firewalls on purpose: both user providers are Doctrine entity providers, so an application-level firewall could not authenticate while the database is unavailable. Results are cached in a dedicated filesystem-backed cache.health pool so that polling cannot amplify into load on the dependencies being checked.
turegjorup
force-pushed
the
feature/health-endpoint
branch
from
August 3, 2026 11:03
fb9945b to
613a7d6
Compare
API Specification - Non-breaking changesNo changelog changes |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #91 +/- ##
=============================================
+ Coverage 37.14% 38.98% +1.83%
- Complexity 948 995 +47
=============================================
Files 133 141 +8
Lines 2972 3122 +150
=============================================
+ Hits 1104 1217 +113
- Misses 1868 1905 +37
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Link to ticket
TODO: no ticket linked yet — please add before review.
Description
Adds
/health/live,/health/readyand/health/detailso monitoring can tell whether the application is working, not just responding./health/live— public, touches nothing. Says only that PHP-FPM is up. A liveness probe that depended on the database would make an orchestrator restart a container that is not at fault./health/ready— public, but reports the aggregated status only, never which dependency failed. The status code is the payload. Point monitoring at this one./health/detail— per-check results, messages and timings. Discloses internals, so it sits behind theITKBasicAuth@fileTraefik middleware on its own router, mirroring how/cron-metricsis handled.Checks are the database, the RabbitMQ messenger transport and detection result freshness. Freshness reads
MAX(lastContact)rather thancreatedAt, because identical submissions are deduplicated by content hash and only bumplastContact— a harvester reporting unchanged servers is still healthy. The RabbitMQ check counts queued messages, which forces a real broker connection and doubles as a backlog signal.^/healthis excluded from the Symfony firewalls rather than protected by one. Both user providers are Doctrine entity providers, so an application-level firewall would fail to authenticate when the database is unavailable and answer500instead of reporting it. Authentication belongs at the edge here.Results are cached in a dedicated, filesystem-backed
cache.healthpool so polling cannot amplify into load on the dependencies being checked. Filesystem on purpose: the pool has to work when the database and broker do not. Dedicated so the adapter can be swapped incache.yamlwithout touching code.Screenshot of the result
No user interface changes.
Checklist
Additional comments or questions
HEALTH_INGEST_MAX_AGEdefaults to 1800 seconds, based on the harvester's current cadence. Worth a second opinion from whoever knows it best.A Redis check was written and then dropped. Nothing in the application uses Redis, there is a single
phpfpmcontainer, andphpfpmandsupervisoralready sharevar/through the.:/appbind mount. A check that reportsskippedforever is noise. Dropping it also let theext-redisandsymfony/cacherequirements be reverted, so this branch does not touchcomposer.jsonorcomposer.lock.Two unrelated follow-ups noticed on the way, both left alone:
doctrine.yamlconfigures a result cache driver that no query enables, andDashboardController.php:59counts advisories on every admin page load to draw a menu badge.