HTTP Health Checker
Build a Rust command-line tool that checks many HTTP endpoints at once and reports whether each is healthy: its status code, how long it took, whether the response contains expected text, and whether it timed out. Endpoints are listed in a config file read with Serde, checked concurrently with Tokio and reqwest (with a limit on how many at once), and the results are printed as a table or JSON for other tools, with an exit code CI pipelines can use. A watch mode rechecks on an interval and reports only changes. Only check services you own or manage. You'll learn async Rust, bounded concurrency, timeouts and retries, configuration with Serde, measuring latency, and testing network code with a fake server.
- Estimate
- ~10h
- Steps
- 6
- Completed by
- 0
- Proposed by
- codeseed.app
Tokio · Serde
Project roadmap
- 01
Define the config and output
~1.5hWrite README.md: the config file (TOML or YAML) listing endpoints with a name, URL, method, expected status codes, optional text the body must contain, a timeout and a latency limit, plus global settings for concurrency and retries; the table and JSON output; and the exit codes (0 all healthy, 1 some unhealthy and 2 config errors). Create the project with tokio, reqwest, serde, toml (or serde_yaml) and clap. Done when: README.md defines the config, output and exit codes.
- 02
Load and validate the config
~1.5hDeserialize the config into structs with Serde, with defaults for optional fields, and validate it: URLs parse and use http or https, names are unique, timeouts are positive, and status lists aren't empty. Report every problem with the endpoint name. Done when: a valid config loads, and a config with several mistakes lists all of them.
- 03
Check endpoints concurrently
~2hUse one shared reqwest::Client and check endpoints concurrently with a limit (for example with futures::stream::iter(...).buffer_unordered(n), or a Tokio Semaphore), applying each endpoint's timeout with tokio::time::timeout. Measure the latency with Instant, read at most a limited amount of the body to check for the expected text, and retry once on connection errors. Done when: checking a list of endpoints runs them in parallel and records status, latency and errors.
- 04
Report the results
~1.5hClassify each result as healthy, slow (over its latency limit), wrong status, missing text, timeout or error. Print an aligned table with colors in a terminal, sorted with problems first, and a summary, or JSON with --json (serialized with Serde). Exit with the right code. Done when: the output clearly shows each endpoint's health, and the exit code matches.
- 05
Add watch mode
~1.5hAdd --watch SECONDS, which repeats the checks on a tokio::time::interval, keeps each endpoint's previous state, and prints only changes (such as api-login: healthy to timeout, with the time), plus a short summary each round. Stop cleanly on Ctrl+C. Done when: watch mode reports when an endpoint goes down and when it recovers.
- 06
Test it
~2hWrite tests with a local fake server (such as the wiremock crate) returning various statuses, slow responses, bodies with and without the expected text, and dropped connections: check classification, timeouts, the concurrency limit, retries, JSON output and exit codes. Done when: cargo test passes.
Resources
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack