Skip to main content

EventLog

Struct EventLog 

Source
pub struct EventLog { /* private fields */ }
Expand description

An append-only event log backed by a JSONL file.

Implementations§

Source§

impl EventLog

Source

pub fn open(session_dir: &Path) -> Result<Self, EventLogError>

Open or create an event log for the given session directory.

The session directory is typically .treeship/sessions/<session_id>/. If the directory does not exist, it will be created.

Initialization reads the counter sidecar in O(1) when present and consistent with events.jsonl’s byte size; falls back to an O(N) line count (and rewrites the sidecar) when the sidecar is missing, short-read, or stale from a crashed previous appender.

Source

pub fn append(&self, event: &mut SessionEvent) -> Result<(), EventLogError>

Append a single event to the log.

The event’s sequence_no is set automatically. Under contention from multiple writer processes, the sequence number is re-derived from the on-disk line count under an exclusive flock so two parallel writers never collide.

Source

pub fn read_all(&self) -> Result<Vec<SessionEvent>, EventLogError>

Read all events from the log.

Per-line tolerant: a single malformed line (unknown event type, missing required field, truncated JSON from a crashed writer) is logged to stderr and skipped, not propagated as an error. The caller – session close, in particular – composes a receipt from whatever events parse, instead of dropping every event when any one is bad.

Why this matters: events.jsonl is append-only and written by hooks, daemons, SDKs, and bridges from multiple processes. A single bad event from one buggy emitter would otherwise nuke the entire receipt’s side_effects / agent_graph / timeline. Real-world repro: a hook that emitted events with an unknown type field caused side_effects.files_written to come back empty even though the rest of the events in the log were valid agent.wrote_file events the aggregator would have happily processed.

Source

pub fn read_all_with_stats( &self, ) -> Result<(Vec<SessionEvent>, usize), EventLogError>

Same as read_all but returns the count of malformed lines that were skipped during parsing alongside the valid events.

Codex adversarial review finding #8: skipping malformed events on stderr only is silent data loss from the verifier’s perspective. The receipt gets sealed under a merkle root that represents only the events that successfully parsed – a downstream consumer cannot tell whether the receipt is complete or whether N events were silently dropped.

session::close calls this and stores the count on receipt.proofs.event_log_skipped. treeship package verify surfaces it as a WARN when nonzero so the receipt’s completeness signal is visible without breaking byte-identical re-verification of pre-existing receipts.

Source

pub fn event_count(&self) -> u64

Return the current event count.

Source

pub fn path(&self) -> &Path

Return the path to the JSONL file.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V