pub struct LogEntry {
pub hlc: HlcTimestamp,
pub node_id: String,
pub table: TableId,
pub op: WriteOp,
pub prev_hlc: Option<HlcTimestamp>,
pub prev_value: Option<Vec<u8>>,
pub originator: Originator,
pub request_id: Option<String>,
pub interface: Option<String>,
}Expand description
A single durable record of a committed write.
Persisted to the per-deployment TransactionLog at commit time.
Both audit and replication observers consume from this log:
- Replication tail-reads by HLC: streams new entries to peers,
filtering out
Originator::Replicatedwrites so applied- from-peer entries don’t echo back. - Audit range-reads by HLC + filters by table / originator / user for query responses.
Wire-stable (serde-derived) because LogEntry frames also flow
across the replication network protocol between nodes.
Fields§
§hlc: HlcTimestampHLC timestamp assigned at commit time. Strictly greater than any previously-appended entry’s HLC on the same node.
node_id: StringNode id of the node that PERSISTED this entry (the node that
observed the commit). Both locally-originated and replication-
applied writes log here, so node_id is always the local
node. Distinguished from Originator::Replicated::from_node
which records the conceptual writer.
table: TableIdIn-deployment table identity.
op: WriteOpThe write operation that was committed.
prev_hlc: Option<HlcTimestamp>HLC of the existing record at this key prior to the write, if
any. None for inserts. Used by anti-entropy to
record causal predecessor relationships for the receive-side
HLC-LWW comparison.
prev_value: Option<Vec<u8>>Raw bytes of the existing record at this key prior to the
write, if the table opted into @audit(capture_state: true)
and the LoggingBackend was configured with
capture_before: true. None when capture was disabled OR
the key didn’t exist (insert path). Decoded as JSON by audit
readers to surface as AuditEntry.before.
Storage cost is significant — each captured write doubles
the log entry size plus pays one extra get at write time
— so this is opt-in per table via the @audit directive.
Note: encoded inline (not skip_serializing_if) because the
wire format is rmp-serde tuple-positional; skipping fields
breaks the decoder’s positional expectations.
originator: OriginatorWho / what initiated the write.
request_id: Option<String>Optional correlation id for traceability — typically the request id from the HTTP / MQTT / gRPC layer.
interface: Option<String>Which protocol / interface the write came in through — "rest",
"graphql", "mqtt", "mcp", or "internal" for platform-
originated writes. None when the originator couldn’t be
determined (background tasks, startup bootstrap that didn’t
set the task-local). Audit queries surface this for filtering.
Implementations§
Source§impl LogEntry
impl LogEntry
Sourcepub fn encode(&self) -> Result<Vec<u8>>
pub fn encode(&self) -> Result<Vec<u8>>
Serialize to MessagePack bytes for storage / wire.
§Errors
Returns crate::error::YetiError::Internal if encoding fails
(in practice, impossible for fully-owned LogEntry values; the
Result is preserved for forward-compatibility with future
fields that may have encoding constraints).
Trait Implementations§
Source§impl<'de> Deserialize<'de> for LogEntry
impl<'de> Deserialize<'de> for LogEntry
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for LogEntry
impl StructuralPartialEq for LogEntry
Auto Trait Implementations§
impl Freeze for LogEntry
impl RefUnwindSafe for LogEntry
impl Send for LogEntry
impl Sync for LogEntry
impl Unpin for LogEntry
impl UnsafeUnpin for LogEntry
impl UnwindSafe for LogEntry
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.