Skip to main content

Structured logging

Kevlar.Extensions.Logging maps built-in strategy events to stable ILogger events without replacing your strategy callbacks.

dotnet add package Kevlar.Extensions.Logging

Log one shield

using Kevlar;
using Kevlar.Extensions.Logging;

var loggedShield = Shield
.Retry(3)
.CircuitBreaker(consecutiveFailures: 5, breakDuration: TimeSpan.FromSeconds(30))
.WithName("catalog")
.WithLogging(logger, options =>
{
options.IncludeScopes = true;
options.MaxLogsPerSecond = 100;
options.ResultFormatter = static result => result?.ToString();
options.SeverityProvider = static logEvent =>
logEvent.Kind == KevlarLogEventKind.Hedge
? LogLevel.Debug
: logEvent.Kind == KevlarLogEventKind.Retry
? LogLevel.Warning
: LogLevel.Information;
});

Return LogLevel.None from SeverityProvider to suppress an event. Suppression happens before ResultFormatter, so disabled events do not format results. MaxLogsPerSecond bounds each logging configuration independently with a one-second monotonic window.

Register logging once

AddKevlarLogging decorates named, reloading, partitioned, and HttpClientFactory shields created through Kevlar's integration packages:

using Microsoft.Extensions.DependencyInjection;

services.AddKevlarLogging(options =>
{
options.IncludeScopes = true;
options.MaxLogsPerSecond = 500;
});

Call it before or after shield registrations. It uses the Kevlar logger category from the registered ILoggerFactory. Explicit WithLogging calls remain local to that shield. Import Kevlar.Extensions.Logging for logging options and runtime types, not for AddKevlarLogging.

Event IDs and levels

EventIdEventDefault level
1001retryWarning
1002timeoutWarning
1003circuit state or rejectionError when opened, isolated, or rejected; Information when half-opened or closed
1004hedgeInformation
1005fallbackWarning
1006rate-limit rejectionWarning
1007concurrency-limit rejectionWarning
1008callback errorError
1009HTTP attempts suppressedWarning for the first unsafe-method suppression per client; Information otherwise
1010timeout cancellation ignoredWarning
1011hedge attempt completionDebug; Information for failed losers

Structured state includes the applicable subset of ShieldName, StrategyIndex, AttemptNumber, Delay, Duration, Elapsed, Outcome, IsWinner, IsCancelled, FromState, ToState, RetryAfter, CallbackKind, and SuppressionReason. HTTP retry and suppression events also include RequestMethod and RequestUri; the URI omits query and fragment data.

Logger, formatter, severity-policy, and scope-disposal exceptions never change shield outcomes. They are reported through KevlarDiagnostics.ReportCallbackError with CallbackErrorKind.Custom with source Kevlar.Extensions.Logging.