pub enum AuditSink {
Disabled,
File {
path: PathBuf,
max_bytes: Option<u64>,
state: Mutex<FileState>,
},
}Expand description
Where audit events go.
Disabled unless a path is configured: writing to a file nobody asked for would be a surprising side effect, and the operator is the one who knows where such a file belongs.
Variants§
Implementations§
Source§impl AuditSink
impl AuditSink
Sourcepub fn file(path: impl AsRef<Path>) -> Result<Self>
pub fn file(path: impl AsRef<Path>) -> Result<Self>
Open path for appending, creating it if needed.
Sourcepub fn file_with_limit(
path: impl AsRef<Path>,
max_bytes: Option<u64>,
) -> Result<Self>
pub fn file_with_limit( path: impl AsRef<Path>, max_bytes: Option<u64>, ) -> Result<Self>
Open path, rotating to <path>.1 once it passes max_bytes.
One generation is kept. A trail that grows without bound eventually fills the disk it is meant to protect, and keeping several generations would be a retention policy — which belongs to whoever runs the machine, not to this process.
Sourcepub fn is_enabled(&self) -> bool
pub fn is_enabled(&self) -> bool
Whether anything is being recorded.
Sourcepub async fn record_async(self: &Arc<Self>, event: AuditEvent)
pub async fn record_async(self: &Arc<Self>, event: AuditEvent)
Record one event from an async context, off the runtime’s workers.
record opens, writes and flushes a file, which is
blocking work — the filesystem handlers already thread it into the
spawn_blocking bodies they are running in for that reason, so a slow
disk cannot starve the worker pool that also runs /health and the
accept loop. A handler that has no blocking body of its own has nowhere
to put it and used to call record straight from the runtime thread.
This is that missing half: same write, same ordering.
Awaited rather than detached, deliberately. Spawning and walking away
would return the response first and leave the entry to land whenever —
or not at all, if the process stops in between. An audit trail that
drops its last entries under load is untrustworthy exactly where it is
load-bearing, which is the same reason record flushes per event.
The hop is skipped entirely when nothing is being recorded: with no
trail configured record returns immediately, and paying for a task
dispatch to do nothing would be a cost on every request of the default
configuration.
Sourcepub fn record(&self, event: AuditEvent)
pub fn record(&self, event: AuditEvent)
Record one event.
Flushed per event rather than buffered until convenient: a trail that loses its last entries when the process dies is least trustworthy exactly when it matters most.
Blocking. From an async context use
record_async, or call this inside a
spawn_blocking body that is already running.