Skip to main content
Version: v1.2.7 (latest)

Delivery Log Storage Backends

Each backend implements IEventPublishDeliveryLog. Storage packages are distributed separately and must be installed explicitly.

Note: Only one storage backend is active — subsequent Use* calls replace the previous registration.

In-Memory Storage

Package: Hermodr.Publisher.DeliveryLog.InMemory

InMemoryEventDeliveryLogRepository holds all records in a thread-safe, volatile collection. Registered as Singleton.

Characteristics

AspectDescription
PersistenceNone — records lost on process restart
PerformanceFastest — no I/O overhead
Query capabilityIn-memory LINQ queries
Best forDevelopment, testing, local debugging

Registration

builder.Services
.AddEventPublisher()
.AddDeliveryLog(log => log.UseInMemory());

Querying

var log = provider.GetRequiredService<InMemoryEventDeliveryLogRepository>();
var records = log.Records.Where(r => r.Outcome == EventDeliveryOutcome.Failed);

NDJSON Rolling Files

Package: Hermodr.Publisher.DeliveryLog.NDJson

The NDJSON implementation appends each record as a JSON line to a sequentially-named file.

Characteristics

AspectDescription
PersistenceFile-based — survives process restarts
PerformanceGood — sequential writes, async I/O
Query capabilityStream-based reading, filtering on read
Best forProduction, audit scenarios, external processing

File Naming

Files are named delivery-log-{yyyyMMdd-HHmmss}.ndjson in a configurable directory:

/var/logs/delivery-logs/
delivery-log-20260614-103012.ndjson
delivery-log-20260614-103045.ndjson
delivery-log-20260614-104500.ndjson

Auto-Roll Behavior

The backend auto-rolls to a new file when either:

  • Current file exceeds MaxFileSizeBytes (default 10 MB)
  • RollInterval has elapsed

After each write, it checks the file count and deletes the oldest files beyond MaxFileCount (default 30).

Registration

builder.Services
.AddEventPublisher()
.AddDeliveryLog(log => log.UseNDJson(opts =>
{
opts.DirectoryPath = "/var/logs/delivery-logs";
opts.MaxFileSizeBytes = 10 * 1024 * 1024;
opts.RollInterval = TimeSpan.FromHours(6);
opts.MaxFileCount = 30;
}));

Options Reference

OptionTypeDefaultDescription
DirectoryPathstring%TEMP%/delivery-logsDirectory for NDJSON files
MaxFileSizeByteslong10 MBSize threshold for rolling
RollIntervalTimeSpan?nullTime threshold for rolling
MaxFileCountint30Max files retained (≤0 = no cleanup)

Reading NDJSON Files

var query = new DeliveryLogStreamQuery
{
From = DateTimeOffset.UtcNow.AddHours(-1),
Outcome = EventDeliveryOutcome.Failed
};

await foreach (var record in reader.ReadAsync(query))
{
Console.WriteLine($"Failed: {record.Event.Type} - {record.ErrorMessage}");
}

Entity Framework Core

Package: Hermodr.Publisher.DeliveryLog.EntityFramework

Stores records in a relational database using Kista.EntityFramework.

Characteristics

AspectDescription
PersistenceDatabase — durable, transactional
PerformanceModerate — depends on database
Query capabilityFull LINQ, indexes, aggregations
Best forProduction, monitoring dashboards, reporting

Registration

builder.Services
.AddEventPublisher()
.AddDeliveryLog(log => log.UseEntityFramework(opts =>
opts.UseSqlServer(connectionString)));

Database Schema

The EF Core backend creates a DeliveryLogEntries table with columns for all EventDeliveryRecord fields.

Querying

using var db = provider.GetRequiredService<DeliveryLogDbContext>();

// Count failures in last hour
var failureCount = await db.DeliveryLogEntries
.CountAsync(e => e.Outcome == EventDeliveryOutcome.Failed
&& e.Timestamp > DateTimeOffset.UtcNow.AddHours(-1));

// Average latency by event type
var avgLatency = await db.DeliveryLogEntries
.Where(e => e.EventTime > DateTimeOffset.UtcNow.AddHours(-1))
.GroupBy(e => e.Event.Type)
.Select(g => new
{
EventType = g.Key,
AvgLatencyMs = g.Average(e => e.ElapsedTime.TotalMilliseconds)
})
.ToListAsync();

Backend Comparison

BackendPersistencePerformanceQuery CapabilityBest For
In-MemoryNoneFastestLINQDevelopment/Testing
NDJSONFilesGoodStream-basedProduction, audit
EF CoreDatabaseModerateFull LINQProduction, reporting