jaque has no trap listener, no MIB parser and no SNMP trap dependency in
the binary. A trap reaches jaque as an ordinary passive check
result, produced by a translator the operator runs
alongside it. The shape is the same one jaque takes with legacy config:
translate outside the binary, never absorb the legacy tooling. The cost
is two daemons beside jaque instead of one flag; the benefit is a pipeline
that survives a trap storm, because nothing in it forks per trap, which
is the one thing Nagios's traphandle never managed.
1. The recipe
snmptrapd ---(traps.log, one line per trap)---> Vector ---(batch POST)---> jaque
snmptrapd receives traps and logs each one as a single line
(peer|trapOID|varbinds). Vector tails that log,
maps each trap OID to a service, a status and an output through a CSV
lookup table, and posts the mapped results to
CommandService/ProcessCheckResults in a batch. A translator receiving
bursts is exactly the batch RPC's use case, so this is the API door, not
the FIFO; see FIFO and API, section 2.1. A
syslog variant swaps the source and keeps the same OID mapping and
posting shape.
2. What traphandle cost
A classic traphandle script forks a process per trap and does not
survive a storm. Here snmptrapd 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, and a burst becomes one batch call
that either enqueues whole or fails whole.
3. 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 and down traps onto the same service: a linkDown trap
sets CRITICAL and 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 stand in for a recovery
trap. Either the translator (or a cron job beside it) posts the
STATUS_OK that clears the condition once it is genuinely resolved, or
that trap is not modelled as an object's state at all and flows only to
an archive or a sink for the record.
4. Security considerations
The trap listener in this recipe is snmptrapd, not jaque, and its
exposure (UDP 162, community strings, v3 users) is configured there. The
translator holds the credential for jaque's API (-api-token) and is the
only thing that needs it. A trap is an unauthenticated datagram in v1 and
v2c; the OID-to-service lookup table is what decides which traps may
assert state on which objects, and a trap with no row in it should map to
nothing rather than to a default service.