Name | health-check-wrap JSON |
Version |
1.0.0
JSON |
| download |
home_page | None |
Summary | A lightweight process supervisor that restarts a service if health checks fail. |
upload_time | 2025-10-06 20:27:31 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.9 |
license | None |
keywords |
supervision
health-check
systemd
cli
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Health Check Wrap
**@readwithai** - [X](https://x.com/readwithai) - [blog](https://readwithai.substack.com/) - [machine-aided reading](https://www.reddit.com/r/machineAidedReading/) - [📖](https://readwithai.substack.com/p/what-is-reading-broadly-defined
)[⚡️](https://readwithai.substack.com/s/technical-miscellany)[🖋️](https://readwithai.substack.com/p/note-taking-with-obsidian-much-of)
Wrap a daemon in a periodic [health check](https://komodor.com/blog/kubernetes-health-checks-everything-you-need-to-know/). Terminate the process and exit if the health check fails allowing your [service manager](https://unix.stackexchange.com/questions/489742/what-is-the-difference-between-init-and-service-manager) like systemd to restart your process.
## Motivation
I am using a service manager (specifically [circusd](https://circus.readthedocs.io/en/latest/man/circusd/)) to manage some processes.
One of these processes is intermittently breaking but the error is rare and in code that I did not write myself. I therefore want to periodically run a health check to see if my service is working and then restart the process if it is not.
However, I dislike the code of my application communicating with my service manager. It feels like it breaks a layer of abstraction, does not allow me to switch out the service manager, and in theory allows one part of the system to restart all processes. Instead, I want to combine the health check with command to run the service and restart the service when the health check dies.
## Usage
To monitor 'service' and terminate it and exit when 'check1' completes with a non-zero exit code you can use the following command:
`health-check-wrap --service service --health-check check1`
This runs a health check every minute. Normally, you would run this command from a service manager such as [systemd](https://wiki.archlinux.org/title/Systemd), [supervisor](https://supervisord.org/) or [circusd](https://circus.readthedocs.io/en/latest/man/circusd/) which would then restart health-check-wrap and so the service.
You can use quotes to specify a full command with arguments to run:
```health-check-wrap --service "/usr/bin/my-app --config production.yml" --health-check "curl --fail http://localhost:8080/ready"
```
You can run multiple health check commands using repeated `--health-check` arguments.
You can use the `--interval` argument to change how often a command runs.
## Caveats
This is very much written with the single-server set up in mind. This is useful for home servers, single board (raspberry pi) projects, and any project that does not yet have users paying you money. Other tools provide tools for distributing services across machines together with health check functionality [such as kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) but these are too heavy weight for many projects.
## Alternatives and prior work
It may be better to merely fix the bug. This sort of layering can add complexity and it can be far simpler to have something work consistently rather than try to fix the results of it not working.
The general approach of "die if something breaks" is influenced by Erlang's concept of a [supervision tree](https://erlang.org/documentation/doc-4.9.1/doc/design_principles/sup_princ.html).
## Related tools
I produce [a stream of command-line tools](https://readwithai.substack.com/p/my-productivity-tools) like this which you may be interested in.
Most similar to this is [killable sudo](https://github.com/talwrii/killable-sudo) which allows you to run processes as another user, such as root, with `sudo` but kill the process with SIGTERM. Many service managers kill processes with SIGTERM.
[env subset](https://github.com/talwrii/env-subset) is a tool to help you control the environment uses to run a process. This is useful for debugging.
## About me
I am **@readwithai**. I create tools for reading, research and agency sometimes using the markdown editor [Obsidian](https://readwithai.substack.com/p/what-exactly-is-obsidian).
I also create a [stream of tools](https://readwithai.substack.com/p/my-productivity-tools) that are related to carrying out my work.
I write about lots of things - including tools like this - on [X](https://x.com/readwithai).
My [blog](https://readwithai.substack.com/) is more about reading and research and agency.
Raw data
{
"_id": null,
"home_page": null,
"name": "health-check-wrap",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "supervision, health-check, systemd, cli",
"author": null,
"author_email": "readwithai <talwrii@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/3d/d3/20a13a6ce029fea48cbb11e289b87547bf0736e141c47c309b8a4d016e61/health_check_wrap-1.0.0.tar.gz",
"platform": null,
"description": "# Health Check Wrap\n**@readwithai** - [X](https://x.com/readwithai) - [blog](https://readwithai.substack.com/) - [machine-aided reading](https://www.reddit.com/r/machineAidedReading/) - [\ud83d\udcd6](https://readwithai.substack.com/p/what-is-reading-broadly-defined\n)[\u26a1\ufe0f](https://readwithai.substack.com/s/technical-miscellany)[\ud83d\udd8b\ufe0f](https://readwithai.substack.com/p/note-taking-with-obsidian-much-of)\n\nWrap a daemon in a periodic [health check](https://komodor.com/blog/kubernetes-health-checks-everything-you-need-to-know/). Terminate the process and exit if the health check fails allowing your [service manager](https://unix.stackexchange.com/questions/489742/what-is-the-difference-between-init-and-service-manager) like systemd to restart your process.\n\n## Motivation\nI am using a service manager (specifically [circusd](https://circus.readthedocs.io/en/latest/man/circusd/)) to manage some processes.\nOne of these processes is intermittently breaking but the error is rare and in code that I did not write myself. I therefore want to periodically run a health check to see if my service is working and then restart the process if it is not.\n\nHowever, I dislike the code of my application communicating with my service manager. It feels like it breaks a layer of abstraction, does not allow me to switch out the service manager, and in theory allows one part of the system to restart all processes. Instead, I want to combine the health check with command to run the service and restart the service when the health check dies.\n\n## Usage\nTo monitor 'service' and terminate it and exit when 'check1' completes with a non-zero exit code you can use the following command:\n\n`health-check-wrap --service service --health-check check1`\n\nThis runs a health check every minute. Normally, you would run this command from a service manager such as [systemd](https://wiki.archlinux.org/title/Systemd), [supervisor](https://supervisord.org/) or [circusd](https://circus.readthedocs.io/en/latest/man/circusd/) which would then restart health-check-wrap and so the service.\n\n\nYou can use quotes to specify a full command with arguments to run:\n\n```health-check-wrap --service \"/usr/bin/my-app --config production.yml\" --health-check \"curl --fail http://localhost:8080/ready\"\n```\n\nYou can run multiple health check commands using repeated `--health-check` arguments.\n\nYou can use the `--interval` argument to change how often a command runs.\n\n## Caveats\nThis is very much written with the single-server set up in mind. This is useful for home servers, single board (raspberry pi) projects, and any project that does not yet have users paying you money. Other tools provide tools for distributing services across machines together with health check functionality [such as kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) but these are too heavy weight for many projects.\n\n## Alternatives and prior work\nIt may be better to merely fix the bug. This sort of layering can add complexity and it can be far simpler to have something work consistently rather than try to fix the results of it not working.\n\nThe general approach of \"die if something breaks\" is influenced by Erlang's concept of a [supervision tree](https://erlang.org/documentation/doc-4.9.1/doc/design_principles/sup_princ.html).\n\n## Related tools\nI produce [a stream of command-line tools](https://readwithai.substack.com/p/my-productivity-tools) like this which you may be interested in.\n\nMost similar to this is [killable sudo](https://github.com/talwrii/killable-sudo) which allows you to run processes as another user, such as root, with `sudo` but kill the process with SIGTERM. Many service managers kill processes with SIGTERM.\n\n[env subset](https://github.com/talwrii/env-subset) is a tool to help you control the environment uses to run a process. This is useful for debugging.\n\n## About me\nI am **@readwithai**. I create tools for reading, research and agency sometimes using the markdown editor [Obsidian](https://readwithai.substack.com/p/what-exactly-is-obsidian).\n\nI also create a [stream of tools](https://readwithai.substack.com/p/my-productivity-tools) that are related to carrying out my work.\n\nI write about lots of things - including tools like this - on [X](https://x.com/readwithai).\nMy [blog](https://readwithai.substack.com/) is more about reading and research and agency.\n",
"bugtrack_url": null,
"license": null,
"summary": "A lightweight process supervisor that restarts a service if health checks fail.",
"version": "1.0.0",
"project_urls": null,
"split_keywords": [
"supervision",
" health-check",
" systemd",
" cli"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "4811047c970510d3c2a46bad696193c70b884c7872f22291858331fe84ee02be",
"md5": "8071a79bfdfe2cc5b383826598ae2c33",
"sha256": "052cec85f85b6ca9ffd9fa8b0ad4219599d22ca53764830f13d021f1a1482a59"
},
"downloads": -1,
"filename": "health_check_wrap-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8071a79bfdfe2cc5b383826598ae2c33",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 7021,
"upload_time": "2025-10-06T20:27:30",
"upload_time_iso_8601": "2025-10-06T20:27:30.370446Z",
"url": "https://files.pythonhosted.org/packages/48/11/047c970510d3c2a46bad696193c70b884c7872f22291858331fe84ee02be/health_check_wrap-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "3dd320a13a6ce029fea48cbb11e289b87547bf0736e141c47c309b8a4d016e61",
"md5": "11f02cad9da7cbf9b6e5129b38d8f43a",
"sha256": "5b2250fa484e221474104983cb6a47777e76c56bc821ee946d50fa2dfd7958d0"
},
"downloads": -1,
"filename": "health_check_wrap-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "11f02cad9da7cbf9b6e5129b38d8f43a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 6376,
"upload_time": "2025-10-06T20:27:31",
"upload_time_iso_8601": "2025-10-06T20:27:31.662859Z",
"url": "https://files.pythonhosted.org/packages/3d/d3/20a13a6ce029fea48cbb11e289b87547bf0736e141c47c309b8a4d016e61/health_check_wrap-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-06 20:27:31",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "health-check-wrap"
}