Case study
Go Checker
A Go tool that answers the question every team asks several times a day: is everything working? It checks that the answer is right and fast and that the certificate is valid. It also stops a broken deploy in CI and, as a monitor, alerts the team only when an outage is real.
- 50 acceptance criteria, all tested
- 96% test coverage, on Linux, macOS and Windows
- 11 documented use cases with real output
Figures for v1.0.0, measured on 2026-10-15. Everything can be checked in the public repository.
View the repository →Read the documentation →Download the releases →
$ go-checker check
✓ UP Storefront 200 OK 37ms
✓ UP Orders API 200 OK 43ms
✗ DOWN Checkout API 200 OK 63ms
→ $.status is "degraded", want "ok"
→ $.db.ok is false, want true
! WARN Search 200 OK 1.24s
→ latency 1.243s above max_latency 800ms
✗ DOWN Payments 503 Service Unavailable 9ms (2 attempts)
! WARN Auth service 200 OK 45ms
→ certificate expires in 9 days (minimum 14)
✓ UP Postgres connected to 127.0.0.1:5432 498µs
7 checks: 3 up, 2 warn, 2 down in 1.24s
$ go-checker check -f typo.yaml
error: typo.yaml: line 4: unknown key "timout" (did you mean "timeout"?)The problem
Some failures slip past simple checks:
Simple checkers only look at the status code. Full platforms need a database, a UI and upkeep.
go-checker started as a 190-line prototype with serious problems. The printed latency was always 2562047h. The process exited 0 even when services were down, which made it useless in CI. It had no tests, no README and no CI, and a 9.5 MB binary was committed.
- a /health endpoint that returns 200 with the database disconnected;
- a site that slows down, and nobody knows whether DNS, the network, TLS or the server is to blame;
- a certificate that expires on a Sunday;
- a lost packet that pages the on-call engineer at 3 a.m.
The solution
A single binary, configured in YAML versioned next to the code, that works in the terminal, in the pipeline and as a continuous monitor:
- Content assertions: status, max latency, body text and regex, JSON values ($.data.items[0].id) and headers. Each failure says what was expected and what was found.
- Request trace: DNS, TCP connect, TLS handshake and first-byte times, and the days until the certificate expires.
- CI exit codes (0, 1 and 2), JSON, JUnit and Markdown reports, an automatic GitHub Actions job summary and a ready-made GitHub Action.
- Monitor mode with Prometheus metrics (p50, p95 and p99) and alerts to Slack, Discord, Teams, Telegram or any webhook, with flap protection.
- Checks generated from an OpenAPI spec, TCP port and DNS checks, and secrets read from the environment.
- Binaries for five platforms, a multi-arch Docker image, and go install.
From prototype to v1.0.0
I started with an evidence-based analysis. I ran the tool, recorded each defect with the output that proved it, and agreed with the owner on what to change before touching the code. That produced 10 specifications with acceptance criteria, and each delivery became a pull request with green CI.
Before the release, I benchmarked go-checker against Gatus, Uptime Kuma, Blackbox Exporter, Hurl, StepCI, Checkly and k6. It was already above average in diagnostics, CI integration and OpenAPI generation. It was below average in secrets handling, protocols, alert channels and distribution. I closed those gaps before v1.0.0: environment variables, authentication, TCP and DNS checks, Discord, Teams and Telegram alerts, and the Docker image.
Technical decisions
- Timings come from net/http/httptrace, with a new connection per request, so DNS, TCP and TLS count as they would for a first-time visitor.
- Retries use exponential backoff with jitter, and only for transient errors (network and 5xx). A 404 is the server's final answer and is not retried.
- A per-check state machine filters flapping: a new state only counts after N rounds in a row, so one lost packet does not become an alert.
- The Prometheus exposition format and the JSON path are written in the project. The only dependencies are cobra and yaml.v3.
- The configuration is strict: an unknown key is an error with its line and the closest suggestion, computed by edit distance.
How quality is ensured
- 50 acceptance criteria, each cited by an automated test, and 96% coverage with the race detector on.
- Tests never reach the internet. Local servers and a dedicated certificate authority produce certificates with the exact lifetime each scenario needs.
- CI runs on Linux, macOS and Windows. The GitHub Action itself is tested against a local server on Linux and Windows.
- Every pull request that touches the release rehearses it, building binaries and the Docker image without publishing.
- The README commands run in CI, so the documentation never promises what the tool does not do.
Outcome
v1.0.0 is out, with binaries for Linux, macOS and Windows, an image on the GitHub Container Registry and a GitHub Action. The documentation, in Portuguese and English, presents every feature as a use case, with a command to copy and the real output.
Limits
There is no public status page and no ICMP or gRPC checks. For a status page, Gatus and Uptime Kuma are better fits. So far I am the only real user; feedback from other teams is still missing.
Need someone who delivers like this?
I work in QA and development: specification, automated tests, CI and delivery to production, with documentation for the people who will use it.
Get in touch →