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 rather than 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.

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 rather than 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; jaque itself listens for nothing here. 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.