Skip to main content

AuditLogger

Struct AuditLogger 

pub struct AuditLogger { /* private fields */ }
Expand description

Audit logger

Implementations§

Source§

impl AuditLogger

Source

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.

Source

pub fn open_shared( config: AuditConfig, zeroclaw_dir: PathBuf, ) -> Result<Arc<Self>>

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.

Source

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_chain rejects 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.

Source

pub fn log_command_event(&self, entry: CommandExecutionLog<'_>) -> Result<()>

Log a command execution event.

Source

pub fn log_command( &self, channel: &str, command: &str, risk_level: &str, approved: bool, allowed: bool, success: bool, duration_ms: u64, ) -> Result<()>

Backward-compatible helper to log a command execution event.

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
§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

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
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

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

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more