go-net-health

An active network health-probe runner in pure Go โ€” stateless TCP/HTTP checks, a rolling healthy/unhealthy verdict, no cgo.

pure Go ยท zero cgo TCP probe HTTP probe rolling status success / failure thresholds initial delay no redirect follow timeout vs refused injectable clock 100% coverage 6 arches
Documentation GitHub
Documentation (MkDocs Material + mike) License: BSD-3-Clause Go 1.26.4+ Coverage 100%

go-net-health is a pure-Go (no cgo) active health-probe runner: stateless network checks โ€” HTTP or TCP โ€” pointed at a single target address and folded into a rolling healthy / unhealthy / unknown verdict. A Probe runs one attempt of a configured check and reports pass/fail plus latency; a Runner drives it on a fixed period, honours an optional initial delay, and derives the rolling Status by stacking consecutive passes/failures against success/failure thresholds โ€” a Kubernetes-style liveness/readiness probe as a small, embeddable library. It has no opinion on what to do with a verdict: Healthy vs Unhealthy is just a fact your own state machine acts on. Depends only on the standard library, is differential-free and dependency-free, 100% covered, and CI-green across 6 arches.

TCP & HTTP probes ready

Two stateless probe kinds: TypeTCP opens a connection and checks it succeeds; TypeHTTP issues a request and checks the response status โ€” configurable path, method and per-probe timeout, accepting any 2xx by default or an explicit status set.

Health-check semantics ready

The behaviour a real health check needs: the HTTP probe does not follow redirects (it checks this endpoint, not where it points), surfaces the attempt latency even on failure, and uses a fresh keep-alive-disabled transport per probe so pools don’t bleed between targets.

Rolling status & Runner ready

A Runner drives a probe on a fixed period, honours a one-shot initial delay, and derives a rolling Status: SuccessThreshold consecutive passes โ†’ Healthy, FailureThreshold consecutive failures โ†’ Unhealthy, Unknown until a threshold is met. Every attempt emits a Result on a buffered channel.

Timeout vs refused ready

IsTimeout distinguishes “the probe never reached the target” from “the target actively refused”, so a caller’s grace period can apply only to unreachable targets. An injectable clock keeps wall time off the hot path for deterministic tests.

100% coverage ยท 6 arches ready

Every branch โ€” timeout, connection-refused, redirect-not-followed, threshold roll-over and the buffer-drop safety valve โ€” is covered with loopback httptest / net.Listen servers and a deterministic fake probe, under -race; 100% coverage, gofmt + go vet clean, green across all six 64-bit Go arches.

EXEC probe planned

TypeExec โ€” running a command inside the target โ€” is reserved. It needs an in-target agent channel this stateless network runner has no access to, so it stays out of scope until that channel exists.

A stateless probe runner in pure Go, cgo disabled, so it cross-compiles and embeds anywhere. It implements HTTP and TCP probes with health-check-correct semantics (no redirect following, per-probe timeouts, latency on failure), a periodic Runner with initial delay and success/failure thresholds, and IsTimeout to separate unreachable targets from refusing ones. It probes and reports; the caller decides. Part of the github.com/go-net-health organization.