Comprehensive audit logging extension for WorkflowForge providing detailed tracking of workflow execution, data changes, and compliance reporting.
$ dotnet add package WorkflowForge.Extensions.Audit
Comprehensive audit logging extension for WorkflowForge with pluggable storage providers for compliance and observability.
This extension has ZERO external dependencies. This means:
Architecture: Implement IAuditProvider for your storage (file, database, cloud).
dotnet add package WorkflowForge.Extensions.Audit
Requires: .NET Standard 2.0 or later
using WorkflowForge.Extensions.Audit;
// Implement audit provider
public class FileAuditProvider : IAuditProvider
{
private readonly string _logPath;
public FileAuditProvider(string logPath)
{
_logPath = logPath;
}
public async Task WriteAuditEntryAsync(
AuditEntry entry,
CancellationToken cancellationToken = default)
{
var json = JsonSerializer.Serialize(entry);
await File.AppendAllTextAsync(_logPath, json + Environment.NewLine, cancellationToken);
}
public Task FlushAsync(CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
}
// Configure audit logging
var auditProvider = new FileAuditProvider("audit.log");
var auditLogger = new AuditLogger(
auditProvider,
userId: "user@example.com",
sessionId: Guid.NewGuid().ToString(),
timeProvider: new SystemTimeProvider());
// Subscribe to events
smith.WorkflowStarted += async (s, e) =>
await auditLogger.LogWorkflowStartedAsync(e);
smith.WorkflowCompleted += async (s, e) =>
await auditLogger.LogWorkflowCompletedAsync(e);
foundry.OperationCompleted += async (s, e) =>
await auditLogger.LogOperationCompletedAsync(e);
await smith.ForgeAsync(workflow, foundry);
IAuditProvider for any storageISystemTimeProvider for testabilitypublic class AuditEntry
{
public string EventType { get; set; } // WorkflowStarted, OperationCompleted, etc.
public DateTimeOffset Timestamp { get; set; }
public string UserId { get; set; }
public string SessionId { get; set; }
public string WorkflowName { get; set; }
public string OperationName { get; set; }
public TimeSpan? Duration { get; set; }
public bool Success { get; set; }
public string ErrorMessage { get; set; }
public Dictionary<string, object> Metadata { get; set; }
}
{
"WorkflowForge": {
"Extensions": {
"Audit": {
"Enabled": true,
"DetailLevel": "Standard",
"LogDataPayloads": false,
"IncludeTimestamps": true,
"IncludeUserContext": true
}
}
}
}
using WorkflowForge.Extensions.Audit.Options;
var options = new AuditMiddlewareOptions
{
Enabled = true,
DetailLevel = AuditDetailLevel.Standard,
LogDataPayloads = false,
IncludeTimestamps = true,
IncludeUserContext = true
};
foundry.UseAudit(auditProvider, options);
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WorkflowForge.Extensions.Audit;
services.AddAuditConfiguration(configuration);
var options = serviceProvider.GetRequiredService<IOptions<AuditMiddlewareOptions>>().Value;
See Configuration Guide for complete options.
public class DatabaseAuditProvider : IAuditProvider
{
private readonly IDbConnection _connection;
public async Task WriteAuditEntryAsync(AuditEntry entry, CancellationToken cancellationToken)
{
await _connection.ExecuteAsync(
"INSERT INTO AuditLog (EventType, Timestamp, UserId, ...) VALUES (@EventType, @Timestamp, @UserId, ...)",
entry);
}
}
public class AzureAuditProvider : IAuditProvider
{
private readonly BlobContainerClient _container;
public async Task WriteAuditEntryAsync(AuditEntry entry, CancellationToken cancellationToken)
{
var blobName = $"{entry.Timestamp:yyyy-MM-dd}/{Guid.NewGuid()}.json";
var blob = _container.GetBlobClient(blobName);
await blob.UploadAsync(JsonSerializer.Serialize(entry), cancellationToken);
}
}