SNMP traps
A trap flood shouldn’t fork a process per trap, and it shouldn’t require jaque to link an SNMP stack either. Both are avoided by keeping trap reception entirely outside the core.
Why this is out of core
Section titled “Why this is out of core”No SNMP listener, no MIB parsing, and no trap dependency enters the jaque binary itself. A trap reaches jaque as an ordinary passive check result, produced by a translator the operator runs alongside jaque — the same posture jaque takes for legacy config import (translate outside the binary, never absorb the legacy tooling directly), applied here to another legacy surface.
A recipe that works well
Section titled “A recipe that works well”snmptrapd --(traps.log, one line per trap)--> Vector --(batch POST)--> jaquesnmptrapd receives traps and logs each as one line
(peer|trapOID|varbinds) — no per-trap process fork.
Vector tails that log, maps each trap OID to a
service/status/output via a CSV lookup table, and posts the mapped result
to CommandService/ProcessCheckResults in a batch. Because a translator
receiving bursts is exactly the batch RPC’s use case, this is the API
door, not the FIFO — see FIFO and API. A
syslog variant that swaps the source but keeps the same OID-mapping and
posting shape works the same way.
What Nagios’s traphandle cost, and what this avoids
Section titled “What Nagios’s traphandle cost, and what this avoids”A classic traphandle script forks a process per trap — it does not
survive a trap storm. snmptrapd here runs once as a daemon and only
appends lines to a file; Vector runs once too, holding one persistent
connection to jaque. Nothing is spawned per trap.
A trap is an event; a service is a state
Section titled “A trap is an event; a service is a state”This is the part a naive integration gets wrong. A trap fires once and is
gone; a jaque service holds a status until something changes it. The
recipe pairs up/down traps onto the same service (a linkDown trap sets
CRITICAL, the matching linkUp clears it to OK) — the same shape as an
active check flipping status between runs.
For a trap type with no recovery counterpart, jaque never self-clears:
stale_status on a passive check only accepts UNKNOWN | WARNING | CRITICAL — it exists to alarm on staleness, not to reset a problem back
to OK — so a bare freshness_threshold cannot substitute for a recovery
trap. Either the translator (or a cron beside it) posts the STATUS_OK
that clears the condition once it’s genuinely resolved, or that trap
isn’t modeled as an object’s state at all, and only flows to an archive
or a sink for the record.