pub trait AuditSink:
Send
+ Sync
+ 'static {
// Required method
fn write<'life0, 'async_trait>(
&'life0 self,
record: AuditRecord,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
}Expand description
What the framework calls to persist an AuditRecord.
One method — the framework awaits write after a scope check resolves
and before the dispatch responds (the “audit before respond” invariant is
AUTHZ-CORE-5’s responsibility; this trait only commits to being
awaitable). Send + Sync + 'static so the sink can be held as
Arc<dyn AuditSink> across dispatch threads.
§Failure handling
A sink that returns / panics-as-error from write is logged at
tracing::error and dispatch continues — per AUTHZ-S01-output §8 the
default audit-vs-availability tradeoff is availability. The trait method
returns () (not Result) for this reason: the contract is “best
effort”. The framework wraps the call in tracing::error!-on-panic
(Arc<dyn AuditSink>::write is awaited inside a panic guard at the
AUTHZ-CORE-5 dispatch path; see the consumer-side tests there). Critical-
sink semantics are deferred (AUTHZ-S01-output §8 open question).
§Default
TracingAuditSink is the default sink. A backend that never calls
with_audit_sink on its hub builder still gets tracing::info! events
on the plexus::audit target — observability for free.
Required Methods§
Sourcefn write<'life0, 'async_trait>(
&'life0 self,
record: AuditRecord,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn write<'life0, 'async_trait>(
&'life0 self,
record: AuditRecord,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Persist one audit record.
The contract is best-effort: a sink that cannot write must not propagate the error to the caller. The framework awaits this future inside a panic guard and treats errors as non-fatal at this layer.