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.