import { AuditLogger, ENTERPRISE_DEFAULTS, type IAdapter } from 'logbun';
import { FileReliabilityAdapter } from 'logbun/durability/filesystem';
declare const destination: IAdapter;
const audit = new AuditLogger({
...ENTERPRISE_DEFAULTS, // mode: 'durable', requireTenantId: true
namespace: 'api-replica-1',
reliability: new FileReliabilityAdapter({
namespace: 'api-replica-1',
dataDir: '.logbun',
wal: { fsync: true },
dlq: { fsync: true, maxEntries: 10_000 },
maxWalBytes: 64 * 1024 * 1024,
encryptionKey: process.env.LOGBUN_ENCRYPTION_KEY,
}),
adapter: destination,
requireTenantId: true,
batching: {
maxSize: 50,
flushInterval: 2_000,
maxQueueSize: 2_000,
onQueueFull: 'dlq',
},
retry: {
insertMaxRetries: 3,
insertBaseDelayMs: 1_000,
maxScanAttempts: 10,
},
retention: { days: 365 },
});ENTERPRISE_DEFAULTS is only { mode: 'durable', requireTenantId: true }. Durable mode still requires a persistent reliability adapter.
Core
| Option | Default | Meaning |
|---|---|---|
namespace |
required | Logger namespace: [a-zA-Z0-9_-]{1,64}, validated at bootstrap. Not the WAL/DLQ path. |
mode |
volatile |
durable requires reliability.persistent === true synchronously. Volatile emits limit / unsafe_default_volatile. |
reliability |
memory in volatile mode | Journal + DLQ backend |
adapter |
required | Destination IAdapter |
onEvent |
— | Observability hook. Listener throws are swallowed. |
Tenancy and pooling
| Option | Default | Meaning |
|---|---|---|
tenancy.mode |
single_database when omitted |
database_per_tenant forces requireTenantId and requires adapterFactory |
tenancy.resolveConnection |
— | Returns per-tenant connection config for adapterFactory |
tenancy.knownTenantIds |
— | Extra tenant ids visited by retention prune in database_per_tenant |
adapterFactory |
— | Recreates per-tenant adapters from resolveConnection config |
pool.maxActiveConnections |
50 | LRU pool size. Exhaustion throws pool_exhausted. |
requireTenantId |
false | Forced true when database_per_tenant. When left false (and not DPT), emits limit / unsafe_default_require_tenant. |
Batching and retry
| Option | Default | Meaning |
|---|---|---|
batching.maxSize |
100 | Maximum insert batch size |
batching.flushInterval |
5_000 ms | Short-lived batching timer; not retry scheduling |
batching.maxQueueSize |
1_000 | Per-tenant RAM queue cap |
batching.onQueueFull |
dlq |
drop is rejected for durable mode |
retry.insertMaxRetries |
3 | Total bulkInsert attempts per destination insertion (includes the first try) |
retry.insertBaseDelayMs |
1_000 | Base backoff; doubles each retry |
retry.maxScanAttempts |
10 | Failed DLQ scans before a batch becomes dead |
Durable + onQueueFull: 'drop' throws:
Configuration error: onQueueFull="drop" is not valid with mode="durable".
Use "dlq" to prevent data loss, or switch to mode="volatile" for drop behavior.Caps and safety
| Option | Default | Meaning |
|---|---|---|
maxActiveTenants |
10_000 | Max concurrent RAM queue keys. Durable: excess tenant keys go to DLQ. Volatile: drop. |
maxTotalQueued |
50_000 | Sum of all per-tenant queue lengths + reservations |
maxFlushConcurrency |
16 | Global bulkInsert semaphore (minimum 1) |
flushTimeoutMs |
30_000 | Overall flush / shutdown deadline |
maxQueryLimit |
500 | Hard cap on query() page size. Omitted caller limit defaults to 50, then clamped to [1, maxQueryLimit]. |
maxPayloadBytes |
64_000 | Serialized oldValues/newValues/metadata cap. Oversize shrinks by dropping metadata, then oldValues, then newValues, then {_truncated:true} placeholders. Emits truncated. |
maxStringFieldBytes |
2_048 | UTF-8 cap for actorId, action, entityId, userAgent, ipAddress (truncated). Never applied to tenantId. |
maxTenantIdBytes |
256 | Hard UTF-8 cap on tenantId. Oversized ids are dropped or rejected — never truncated. |
maxPreReadyBuffer |
10_000 | Volatile buffer before ready. Excess emits drop / pre_ready_buffer_full. |
maxRecoveryBatch |
max queue size | Bound on a journal recovery wave. Floored at 1; 0 does not disable recovery. |
integrityChain |
false | Per-tenant SHA-256 chain. Detection only. |
redactPaths |
— | Deep paths removed before persistence. Bare keys also delete inside oldValues / newValues / metadata. Root identity fields are never deleted. |
retention.days |
— | Finite integer >= 1. Pruned only by runMaintenance(). |
Removed in 1.0: RetentionConfig.cronExpression, RetryConfig.scanIntervalMs, RetryConfig.initialDelayMs. Filesystem options (dataDir, wal, encryptionKey, …) live on FileReliabilityAdapter, not LogbunConfig.