Expand description
Emit application events for P specs, from tests and production alike.
§snappea::emit
Emit application events once, then check them against P specs in tests (with
snappea::test) and in production (with snappea observe). With only the emit
feature, snappea compiles no checker and depends only on serde / serde_json:
[dependencies]
snappea = { version = "0.1", default-features = false, features = ["emit"] }use snappea::emit::{emit, json};
// After the reservation commits:
emit("eReserved", "coffee", json!({"order": "o1", "units": 2}));emit(event, key, payload) takes the P event name, the partition key (anything
Display; each key gets its own spec instance) and a Serialize payload: json!, a
#[derive(Serialize)] struct, a scalar, or () for none. emit_at(time, ...) sets the
time (a SystemTime, or i64 epoch nanoseconds for a logical clock). The call site is
recorded as src and shown in failure reports.
Where emit sends events:
| Process | Events go to |
|---|---|
A test with a snappea::test recording | that recording (snappea::emit::test_hook) |
Started by a test (SNAPPEA_EVENTS_DIR set) | its own <name>-<pid>-<random>.jsonl in that folder |
After snappea::emit::set_sink(...) | the sink: JSON lines snappea observe reads |
| Otherwise | nowhere: a few atomic loads, no lock |
use snappea::emit::Emitter;
use std::time::Duration;
snappea::emit::set_sink(Emitter::file("/var/log/app/events/inventory.jsonl")?);
// or Emitter::stdout(), Emitter::writer(w), Emitter::callback(|event| ...)
// ... at shutdown:
snappea::emit::close(); // writes what is queued; snappea::emit::flush(timeout) only waitssnappea observe -pf specs/inventory.p --spec InventoryCorrect -l '/var/log/app/events/*.jsonl'set_sink replaces the earlier sink (Emitter::off() turns it off) and does nothing
in a process a test started. Testing and production covers
deploying this.
An Emitter is also a value: code that takes one (instead of calling the global
emit) gets recording.emitter() in tests and a production Emitter otherwise;
clones share a destination. Emitter::callback(f) calls f with each Event on the
emitting thread, under the emitter’s lock, so f must be quick; the other production
sinks write from a background thread.
Emitting never panics, returns an error, or blocks on I/O. Production writers queue up
to 16,384 lines and drop events when the queue is full or a write fails;
snappea::emit::dropped() (or Emitter::dropped()) counts them. When off, emit costs a few atomic loads, but the
payload is still built: guard costly payloads with is_on(). The events folder writer
appends each line synchronously, so a child’s events are on disk when it exits.
Lines follow the events folder format:
timestamp is ISO-8601 with nanoseconds, from a wall clock that never goes back within a
process, plus src, seq and pid.
Modules§
- test_
hook - For test helpers such as
snappea::test: lets in-process recordings receive the events application code emits through the globalemit. Not for application code.
Macros§
- json
- Construct a
serde_json::Valuefrom a JSON literal.
Structs§
- Emitter
- Where emitted events go. Clones share one destination. The default is off.
- Event
- One emitted event, as written to an events file.
- Time
- An event time: nanoseconds since the Unix epoch. Any increasing counter works as a logical clock.
Enums§
- Value
- Represents any valid JSON value.
Constants§
- EVENTS_
DIR_ ENV - The environment variable naming the folder test child processes write events to.
Functions§
- close
- Writes what the global sink has queued (waiting up to 5 s) and turns it off. Call it at shutdown.
- dropped
- Events the global emitter dropped since the process started: a full queue, a failed write, or a payload that could not be serialized.
- emit
- Records
eventon streamkeynow: into an in-process test recording while a test helper routes events (seetest_hook), else toSNAPPEA_EVENTS_DIRwhen a test started this process, else to the sink set withset_sink, else nowhere. - emit_at
emitat a given time instead of the wall clock.- flush
Emitter::flushon the global emitter.- set_
sink - Sends events from
emitoutside tests tosink(Emitter::file(path)?,Emitter::stdout(),Emitter::writer(w)orEmitter::callback(f)), replacing the earlier sink and writing what it had queued.Emitter::off()turns it off. In a process a test started (SNAPPEA_EVENTS_DIRset) it does nothing: events go to the test.