Expand description
backbeat: a system-wide flight recorder with a self-describing on-disk format and a schema-driven query CLI.
backbeat is the steady rhythm running underneath your application: every instrumented event is captured into a low-overhead, lock-free ring and dumped to disk along with a schema describing how to read it, so a reader needs no compiled-in knowledge of the event types.
use backbeat::Event;
use backbeat::zerocopy::{Immutable, IntoBytes};
use backbeat::recorder::Recorder;
/// A packet was sent.
#[derive(Event, IntoBytes, Immutable)]
#[event(namespace = "my_app::net")]
#[repr(C)]
struct PacketSent {
#[event(key)] connection_id: u64,
#[event(unit = "bytes")] len: u32,
_pad: [u8; 4], // explicit padding: IntoBytes rejects implicit gaps
}
let rec = Recorder::new(/* shards */ 4, /* bytes/shard */ 1 << 20);
rec.set_enabled(true);
rec.record(&PacketSent { connection_id: 7, len: 1200, _pad: [0; 4] });
// Dump every event compiled in (the registry self-populates via the derive).
let dump = rec.dump(
backbeat::registry::schemas(),
std::iter::empty(),
backbeat::registry::views(),
"my-host",
);Feature gates keep the dependency footprint matched to the use case:
- default (
std) — the full recorder runtime, dumper, and self-populating registry. default-features = false— the format and descriptors only,no_std, for crates that just define events.
The dump → Parquet/summary tooling lives in the separate backbeat-cli crate
(cargo install backbeat-cli), so a library consumer never pulls in arrow/parquet/clap.
§Modules
id— the stable, compile-time 64-bitEventIdderived from an event’s fully-qualified name; the join key between a record and its schema.schema—EventSchemaand friends: the self-describing field layout the derive emits and the dump embeds.event— theEventtrait the derive implements.- [
format] /wire— the on-disk dump envelope and its byte-level serialization. record— the shared[ts][event_id][fields]record framing.ring— the lock-free, bump-allocatingRingeach shard captures into.cpu— the cheap rseq-based current-CPU hint used to pick a shard without a syscall.recorder/registry— the runtime (stdonly): sharded capture and the dumper, plus theinventory-populated schema registry.
Re-exports§
pub use event::Event;pub use event::EventEnum;pub use event::FieldTy;pub use id::EventId;pub use schema::EnumLabel;pub use schema::EventSchema;pub use schema::FieldRole;pub use schema::FieldSchema;pub use schema::FieldType;pub use schema::Phase;pub use zerocopy;pub use bytes;pub use inventory;
Modules§
- cpu
- Cheap current-CPU hint for shard selection.
- event
- The
Eventtrait tying a struct to its schema and its bytes. - format
- The on-disk dump format.
- global
- A process-wide global
Recorderwith an asynchronous, throttled dumper. - id
- Stable, compile-time event identifiers.
- record
- The record framing shared by the recorder (writer) and the reader.
- recorder
- The recorder runtime: sharded capture rings and the dumper.
- registry
- Self-populating registry of every event type compiled into the binary.
- ring
- A lock-free, bump-allocating ring buffer — the per-shard capture store.
- schema
- Self-describing event schemas.
- wire
- Byte-level serialization of the dump format.
Macros§
- register_
event - Registers an event type into the global
registryso the dumper can enumerate it. - register_
views - Registers a set of query DDL — opaque SQL (typically DuckDB
CREATE VIEW/CREATE MACROstatements) describing how to query this binary’s events — so the dumper embeds it in every dump.
Derive Macros§
- Event
- The
Eventderive macro: annotate a#[repr(C)]struct to make it a traceable event. DerivesEventfor a struct: its compile-timeEventId, a reflectedEventSchema, and animpl Event. - Event
Enum - The
EventEnumderive macro: annotate a fieldless#[repr(u8|u16|u32|u64)]enum to use it as a strongly-typed event field whose variants become value→label pairs in the schema. DerivesEventEnumfor a fieldless#[repr(u8|u16|u32|u64)]enum, so it can be a strongly-typed event field. Emits the variant→label map and the repr width.