Struct AuditLogger
pub struct AuditLogger { /* private fields */ }Expand description
Audit logger
Implementations§
Source§impl AuditLogger
impl AuditLogger
Sourcepub fn new(config: AuditConfig, zeroclaw_dir: PathBuf) -> Result<Self>
pub fn new(config: AuditConfig, zeroclaw_dir: PathBuf) -> Result<Self>
Construct a logger over <zeroclaw_dir>/<config.log_path>.
One instance per file. The Merkle chain’s sequence and prev_hash
live in this struct’s mutex, so the mutex serializes only the writers
that go through THIS instance. Two loggers over one file each recover
the same tip at construction and then both claim it, producing
duplicate sequence numbers and broken links that make verify_chain
reject the file — see two_loggers_on_one_file_duplicate_a_sequence.
Production code must therefore never construct a logger per request or
per subsystem. Build one at daemon startup with
AuditLogger::open_shared and inject the Arc; the certificate
paths reach it through RpcContext::cert_audit. This constructor stays
public for tests and for the single startup call behind open_shared.
Open THE audit logger for zeroclaw_dir — the single instance every
certificate path in a daemon shares.
Returns an Arc because sharing is the whole point: enrollment,
renewal and the issued-cert ledger all append to one file, and the
chain is only consistent while one instance owns it (see
AuditLogger::new for what a second instance does). Call this once
per daemon iteration, store it in RpcContext::cert_audit, and clone
the Arc into every consumer.
Sourcepub fn log(&self, event: &AuditEvent) -> Result<()>
pub fn log(&self, event: &AuditEvent) -> Result<()>
Log an event.
One event is one atomic step. The chain lock spans rotation,
sequencing, hashing, signing, serialization AND the durable append,
and the in-memory chain state is committed only after sync_all
returns. Two properties the trail depends on follow from that order:
- Concurrent callers cannot interleave. If the lock were released
before the append, two threads could take sequences 0 and 1 and then
write their lines in the opposite order —
verify_chainrejects the file even though each write was individually correct. - A failed append changes nothing. Rotation, serialization, open,
write and fsync all fail before the commit, so the state stays
exactly as it was and the caller’s retry reuses the same sequence
and
prev_hash. Advancing first left the in-memory chain ahead of the file, and every later entry then linked to a hash that was never written.
Both properties hold only WITHIN one instance: one AuditLogger per
file is a hard requirement, see AuditLogger::new.
Sourcepub fn log_command_event(&self, entry: CommandExecutionLog<'_>) -> Result<()>
pub fn log_command_event(&self, entry: CommandExecutionLog<'_>) -> Result<()>
Log a command execution event.
Auto Trait Implementations§
impl !Freeze for AuditLogger
impl !RefUnwindSafe for AuditLogger
impl Send for AuditLogger
impl Sync for AuditLogger
impl Unpin for AuditLogger
impl UnsafeUnpin for AuditLogger
impl UnwindSafe for AuditLogger
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more