# hc-runner
master: [](https://github.com/n8henrie/hc-runner/actions/workflows/ci.yml)
A personal project that runs commands and submits the execution result to a
configurable instance of [healthchecks.io] (>=v3, requires auto-provisioning).
The URL for your HealthChecks instance, including your `ping_key`, is required
at runtime\*. Because the `ping_key` is considered a secret, users may wish to
keep it out of their shell history and out of any cron scripts that are calling
`hc-runner`; to this end, as an alternative to the `--url` flag, the URL can
also be specified in a config file or by the `HC_RUNNER_URL` environment
variable. All other options are taken only from command line flags.
Please consider restricting access (e.g. `chmod 0600`) to any files that
contain your `ping_key`, possibly including the `hc-runner` config file.
\* If you're using the hosted healthchecks server, your URL may look something
like `https://hc-ping.com/{ping_key}/`.
## Quickstart
```console
$ cargo run -q -- --help
Command runner for healthchecks.io
Usage: hc-runner [OPTIONS] --slug <NAME> <COMMAND>...
Arguments:
<COMMAND>...
Options:
-c, --config <CONFIG> Specify a config file in non-default location
-q, --quiet Silence logging / warnings. Does not affect called command's output
-s, --slug <NAME> Set healthchecks slug for this call
--success-only Disable calling `/start` and only ping healthchecks if the test was successful
-t, --timeout <TIMEOUT> Set timeout for requests to healthchecks server
-u, --url <URL> Specify the URL of the healthchecks server for this call
-v, --verbose... Increase logging verbosity. May be repeated. Defaults to `Level::WARN`
-h, --help Print help
-V, --version Print version
```
`hc-runner`:
- by default sends a request to `/start` to mark the beginning of the scripts
execution and uses `?create=1` here to create a new healthcheck for this slug
if it doesn't already exist
- by default sends a request to `/{status_code}` to mark the end of execution
and reflect the exit status (e.g. `/0` for successful exit) and sends stderr
as the body
- mirrors the exit status, stdout, and stderr of the called command
- can optionally only report successful runs with `--success-only`
- this will prevent failure notifications for services that are expected to
fail *sometimes*, but for which notifications are still desired if there
isn't at least one successful run per (healthchecks-configured) time
period
- does not report execution time or collect stderr
- can disambiguate flags in the called command using `-- trailing args` syntax,
e.g.:
- `hc-runner -v -- command` makes `hc-runner` more verbose
- `hc-runner -- command -v` passes the `-v` flag to `command`
- `hc-runner -v -- command -v` does both
- prepends commands with `/usr/bin/caffeinate` on MacOS to keep long-running
commands alive
Example:
```console
$ git clone https://github.com/n8henrie/hc-runner.git
$ cd hc-runner
$ export HC_RUNNER_URL=http://your.server.url
$ cargo build --release
$ ./target/release/runner --slug say_foo -- echo foo
foo
$ echo $?
0
$ ./target/release/runner \
--slug epic_fail \
-- bash -c 'echo bar >/dev/stderr; exit 1'
bar
$ echo $?
1
```
## Notes
### debugging
`-vvv` is your friend. Note that the output will contain your `ping_key`.
Due to the default of `create=1`, you will pollute your HealthChecks instance
when testing with fake slugs (`--slug=foo`), but your output will be cluttered
with errors if you use a fake URL (`--url=http://broken`). During testing /
experimentation, consider using `--success-only` with a command that is
guaranteed to fail (e.g. `false`) which will prevent calls to the server
entirely.
### testing
The integration tests use the `httpmock` library to provide a mock server.
Testing should be done with `--test-threads=1` or errors will likely result. The
`make test` target sets this for you.
### macOS
On macOS, `runner` prefixes commands with `caffeinate` in order to keep
long-running processes awake.
Newer versions of macOS have built-in privacy and security tools that may
prevent `runner` from accessing sensitive directories like `~/Documents`,
particularly if run in an automated script from `launchd`. The `install-macos`
target in the `Makefile` includes a workaround that should read `RUNNER_URL`
from `config.env` (see `config-sample.env`), compile and install the project,
then present some permissions dialogs to allow you to give access to these
directories to `runner`. If the scripts you are running do *not* access
sensitive directories such as `~/Desktop`, `~/Documents`, `~/Downloads`, don't
bother with this. If you *do* use this approach, you'll have to remove a check
named `hc-runner-setup-delete-me` from your [healthchecks.io] instance.
### Alternatives
There are several similar projects on crates.io that may be much more
comprehensive and/or functional than this hobby project. I encourage you to
check them out! Here are a couple:
- https://github.com/msfjarvis/healthchecks-rs
- https://github.com/dimo414/task-mon
# Acknowledgements
- Pēteris Caune, creator of [healthchecks.io]!
[healthchecks.io]: https://healthchecks.io
[1]: https://healthchecks.io/docs/http_api/#start-slug