How darynongera/fort_audit works
Fort is an Elixir audit-logging library for host applications. The main workflow wraps business Ecto.Multi operations with an audit step, persists the business changes and audit row atomically, then emits the committed row through Logger and stamps it as emitted. It also supports standalone and best-effort logging, changeset-derived audit data, and recovery of persisted-but-unemitted rows. The README documents these paths; some transaction and reconciliation internals were not included in the sampled source, so only documented wiring is shown.
Main entry points: audit.ex Atomic transaction · emitter.ex Logger emitter · audit_log.ex Audit log schema · reconcile.ex Reconcile task
Components 14
Audit workflows
- Audit API
lib/fort/audit.ex - Audited Multi
lib/fort/audited_multi.ex - Missing-step guard
lib/fort/missing_audit_step_error.ex - Atomic transaction
lib/fort/audit.ex - Best-effort logging
lib/fort/audit.ex - Standalone logging
lib/fort/audit.ex - Changeset derivation
lib/fort/audit.ex
Audit persistence
- Configured Ecto repo
- Audit log schema
lib/fort/schemas/audit_log.ex
Emission and recovery
- Logger emitter
lib/fort/emitter.ex - Reconciliation API
lib/fort/audit.ex - Reconcile task
lib/mix/tasks/fort/reconcile.ex
Other components
- Host application
- Elixir Logger
Connections 20
- Host application → Audit API: calls
- Audit API → Audited Multi: wraps
- Audit API → Atomic transaction: runs
- Atomic transaction → Missing-step guard: raises on omission
- Atomic transaction → Audit log schema: builds audit row
- Atomic transaction → Configured Ecto repo: transacts
- Atomic transaction → Logger emitter: emits committed rows
- Host application → Best-effort logging: calls
- Best-effort logging → Audit log schema: builds audit row
- Best-effort logging → Configured Ecto repo: inserts row
- Host application → Standalone logging: calls
- Standalone logging → Audit log schema: builds audit row
- Standalone logging → Configured Ecto repo: inserts row
- Standalone logging → Logger emitter: emits row
- Host application → Changeset derivation: derives audit data
- Logger emitter → Elixir Logger: logs structured event
- Logger emitter → Configured Ecto repo: stamps emitted time
- Reconcile task → Reconciliation API: invokes
- Reconciliation API → Configured Ecto repo: queries unemitted rows
- Reconciliation API → Logger emitter: re-emits rows