Root import: import { AuditLogger } from 'logbun'.
Generic: AuditLogger<TActions extends string = string>.
Constructor
new AuditLogger<TActions>(config: LogbunConfig<TActions>)Synchronous throws:
- Durable mode without
reliability, or withpersistent: false tenancy.mode === 'database_per_tenant'withoutadapterFactory- Invalid
retention.days
See Configuration.
Members
| Member | Contract |
|---|---|
ready |
Bootstrap promise. Never rejects. Bootstrap failure sets degraded and emits bootstrap_fail / degraded. |
degraded |
true after bootstrap failure. fire drops; fireAsync / query / DLQ / flush / maintenance throw. |
fire(action, input, context?)
Returns void, never throws. If provided, context.waitUntil receives the admission task, including pre-ready draining. DurableAdmissionSchedulingError is rethrown into that task (and emitted as flush_fail / durable_admission_scheduling) so Workers keep the isolate awake; fire() itself still does not throw.
After shutdown(), emits drop / shutdown and returns.
fireAsync(action, input, context?)
Resolves after admission; in durable mode, journal commit occurs first. Rejects on hard admission failure, degraded/uninitialized, missing tenant when required, or oversize tenantId. Cloudflare alarm scheduling can also reject after commit with DurableAdmissionSchedulingError.
Messages:
| Condition | Error |
|---|---|
degraded before ready wait |
AuditLogger is degraded — fireAsync unavailable |
| Degraded / no engine after ready | AuditLogger is not initialized — fireAsync unavailable |
| Missing tenant, DPT | tenantId is required when tenancy.mode is "database_per_tenant" |
Missing tenant, requireTenantId |
tenantId is required when requireTenantId is true |
| Oversize tenant | tenantId exceeds maxTenantIdBytes (N) |
| Hard fail / backpressure | Failed to enqueue audit log (durable hard fail / backpressure) |
resolveTenantId on context fills tenantId only when the caller omitted it. Thrown resolver errors: fire emits drop / get_tenant_id and never throws; fireAsync rejects.
query({ tenantId, filters, pagination })
Newest-first page from the destination. Default pagination.limit is 50, clamped to [1, maxQueryLimit] (default cap 500). Throws AuditLogger is not initialized — query unavailable when degraded or shut down. Empty/requireTenantId tenant rules match fireAsync.
await audit.query({
tenantId: 't1',
filters: { action, actorId, entityId, startDate, endDate },
pagination: { cursor, limit },
});
// → { logs, nextCursor } // nextCursor is the last row's id, or nulltenantId omitted/undefined queries the base adapter with null (unscoped) unless requireTenantId is on. In database_per_tenant, a missing tenant throws; a present tenant pins the pooled adapter. Adapter query failures after a successful pin are not wrapped. Pin/resolve failures throw Failed to resolve tenant adapter for tenantId "…": ….
flush()
Drains current RAM queues and compacts the journal when durable. Throws AuditLogger is not initialized when degraded or shut down.
Prefer for request-end volatile delivery: await fireAsync(...); await flush().
runMaintenance()
Single-flight: flushes, recovers DLQ orphans, scans the DLQ once, and prunes configured retention. A caller during a pass queues one extra pass after. See Maintenance.
retryDlqNow()
Recover orphans + one DLQ scan without flush or retention.
listDlq(opts?)
Lists opaque DLQEntry values. Pending is included by default; processing and dead are opt-in.
listDlq(opts?: {
includePending?: boolean;
includeProcessing?: boolean;
includeDead?: boolean;
}): Promise<DLQEntry[]>requeueDead(id) / deleteDead(id)
requeueDead moves a dead entry to pending, resets attempts, and preserves its ID. deleteDead permanently deletes a dead entry. Both throw AuditLogger is not initialized when degraded.
getStats()
Sync RAM snapshot. Always includes queued, tenants, degraded, recoveryBacklog, inflightFlushes. Does not hit disk. Before ready, queued is the pre-ready buffer length (tenants is 1 when that buffer is non-empty). When degraded: zeros with degraded: true. After shutdown with no engine: zeros with degraded: false.
getStatsDetailed()
getStats() plus walApproxBytes / dlqPending / dlqProcessing / dlqDead. When degraded or not ready those disk fields are 0. When reliability.getStats() throws they are omitted (not zeroed) and a stats / reliability_get_stats event is emitted.
verifyIntegrity(logs, opts?)
Verifies an oldest-first integrity chain. Optional opts.genesis (default INTEGRITY_GENESIS, 64 zero hex). Returns { ok, failedAt, error? }.
shutdown()
Best-effort drain then closes destination and reliability resources. Subsequent fire emits drop / shutdown. Idempotent. Waits for in-flight maintenance before closing. Flush honors flushTimeoutMs; leftover inflightFlushes emit limit / shutdown_deadline.
AuditLoggerStats
interface AuditLoggerStats {
queued: number;
tenants: number;
degraded: boolean;
recoveryBacklog: number;
inflightFlushes: number;
walApproxBytes?: number; // getStatsDetailed only
dlqPending?: number;
dlqProcessing?: number;
dlqDead?: number;
}