Skip to content

Native checks

Most of what you’re checking doesn’t need a subprocess: a TCP connect, an HTTP request, a DNS lookup. jaque runs these as plain Go, in-process — no fork, no shell, no plugin binary to keep patched.

Type What it does
tcp Connects to host:port, succeeds on connect.
http Requests a URL; 5xx is CRITICAL, 4xx is WARNING, anything else is OK.
dns Resolves a name against a specific server:port.
icmp Pings a host.
tls Connects and checks certificate expiry (warn_within / crit_within).
snmp Queries an OID over SNMP v2c or v3.

SNMP is first-class rather than an afterthought because a switch or a router can’t run an agent — polling it over the wire is the only option that exists.

services: {
ssh: check: {type: "tcp", address: "10.0.0.1:22"}
web: check: {type: "http", url: "https://10.0.0.1/"}
dns: check: {type: "dns", server: "10.0.0.1:53", name: "example.com"}
cert: check: {type: "tls", address: "10.0.0.1:443", warn_within: "336h", crit_within: "72h"}
}

tls’s defaults are 14 days warning, 3 days critical — tuned so a certificate rotation failure gives you a real window to notice, not a same-day scramble.

icmp uses unprivileged datagram sockets; on most Linux distributions run sudo sysctl -w net.ipv4.ping_group_range="0 2147483647" (or the narrower group range you prefer) or the check returns UNKNOWN with permission denied.

check: {
type: "snmp"
address: "10.0.0.254:161"
oid: "1.3.6.1.2.1.1.3.0"
community: "public"
// or, for v3 USM:
// user: "monitor"
// auth_proto: "SHA256" // "", "MD5", "SHA", "SHA224", "SHA256", "SHA384", "SHA512"
// auth_pass: "..."
// priv_proto: "AES256" // "", "DES", "AES", "AES192", "AES256", "AES192C", "AES256C"
// priv_pass: "..."
warn: "" // Nagios-style threshold range, or...
crit: "" // ...another one, or...
expect: "" // ...an exact-match string. Mutually exclusive.
}

The schema enforces exactly one of community (v2c) or user (v3) at the config level — a config mixing both fails validation before jaque ever opens a socket.

Native checks share the same #Schedule shape as every other check type: check_interval (default 60s), retry_interval (default 15s), timeout (default 10s), max_attempts (default 3), and flap. See State model for what those numbers actually control.

Two flags bound how much runs at once: -global-concurrency (default 50) caps checks in flight across the whole process, -host-concurrency (default 4) caps them per host — one flapping host can’t starve the scheduler for everyone else. Each object’s schedule carries a deterministic jitter derived from a hash of its own ID, so 500 checks with the same check_interval don’t all fire in the same instant just because they were loaded from the same config.