A time-interval-based log throttler for Microsoft.Extensions.Logging that suppresses repeated log entries per key and reports the suppressed count when logging resumes.
| Project | Description |
|---|---|
src/ThrottledLogging |
NuGet library |
examples/GettingStarted |
Console demo covering all features |
dotnet add package ThrottledLogging
Call the throttled extension methods on any ILogger. Each call requires a key (identifies the log message for throttling purposes) and an interval (minimum time between emissions).
// Only logs once per minute for the key "disk-full".
// On the next emission after suppression, appends "(N messages suppressed)".
logger.LogWarningThrottled("disk-full", TimeSpan.FromMinutes(1), "Disk usage is above {Percent}%", usage);Available methods mirror the standard ILogger API:
LogTraceThrottledLogDebugThrottledLogInformationThrottledLogWarningThrottledLogErrorThrottledLogCriticalThrottled
Each method signature is (string key, TimeSpan interval, string? messageTemplate, params object?[] args) — on .NET 9 and later args uses params ReadOnlySpan<object?> for reduced allocations.
When a throttled message is allowed through after one or more suppressions, the suppressed count is automatically appended to the message:
Disk usage is above 95% (3 messages suppressed)
The suffix is localized. On a zh-CN system the output is:
Disk usage is above 95% (3个消息被隐藏)
Each key has its own throttle budget — different keys do not share a counter:
logger.LogErrorThrottled("service-a-down", TimeSpan.FromSeconds(5), "Service A is unreachable");
logger.LogErrorThrottled("service-b-down", TimeSpan.FromSeconds(5), "Service B is unreachable");Global expiry and cleanup settings can be adjusted at startup:
// Expire idle entries after 30 minutes; run cleanup every 15 minutes.
ThrottledLogger.Configure(expiry: TimeSpan.FromMinutes(30), cleanupPeriod: TimeSpan.FromMinutes(15));| Parameter | Default | Description |
|---|---|---|
expiry |
1 hour | How long an idle entry is kept before being removed |
cleanupPeriod |
1 hour | How often the background cleanup timer runs |
| Target Framework | Notes |
|---|---|
| .NET Standard 2.0 | Background cleanup timer disabled; idle entries are released when the ILogger is GC'd |
| .NET 8 | Full support |
| .NET 9 | Full support; args uses params ReadOnlySpan<object?> for reduced allocations |
| .NET 10 | Full support; args uses params ReadOnlySpan<object?> for reduced allocations |
dotnet build
dotnet test
dotnet pack基于时间间隔的 Microsoft.Extensions.Logging 日志限流器,可按 key 抑制重复日志,并在恢复输出时报告被抑制的条数。
| 项目 | 说明 |
|---|---|
src/ThrottledLogging |
NuGet 库 |
examples/GettingStarted |
控制台示例,涵盖所有功能 |
dotnet add package ThrottledLogging
在任意 ILogger 上调用限流扩展方法。每次调用需传入一个 key(用于标识被限流的日志消息)和一个 interval(两次输出之间的最短间隔)。
// "disk-full" 这个 key 每分钟最多输出一次。
// 抑制后下次恢复输出时,会自动追加"(N messages suppressed)"。
logger.LogWarningThrottled("disk-full", TimeSpan.FromMinutes(1), "Disk usage is above {Percent}%", usage);可用方法与标准 ILogger API 一一对应:
LogTraceThrottledLogDebugThrottledLogInformationThrottledLogWarningThrottledLogErrorThrottledLogCriticalThrottled
每个方法的签名为 (string key, TimeSpan interval, string? messageTemplate, params object?[] args),在 .NET 9 及更高版本上 args 改用 params ReadOnlySpan<object?> 以减少内存分配。
当某条被限流的消息在经历一次或多次抑制后重新允许输出时,抑制次数会自动追加到消息末尾。追加的后缀已本地化,在 zh-CN 环境下输出为:
Disk usage is above 95% (3个消息被隐藏)
每个 key 拥有独立的限流计数器,互不干扰:
logger.LogErrorThrottled("service-a-down", TimeSpan.FromSeconds(5), "Service A is unreachable");
logger.LogErrorThrottled("service-b-down", TimeSpan.FromSeconds(5), "Service B is unreachable");可在应用启动时调整全局的过期时间和清理周期:
// 空闲条目 30 分钟后过期;每 15 分钟执行一次清理。
ThrottledLogger.Configure(expiry: TimeSpan.FromMinutes(30), cleanupPeriod: TimeSpan.FromMinutes(15));| 参数 | 默认值 | 说明 |
|---|---|---|
expiry |
1 小时 | 空闲条目在被移除前的保留时长 |
cleanupPeriod |
1 小时 | 后台清理定时器的运行间隔 |
| 目标框架 | 说明 |
|---|---|
| .NET Standard 2.0 | 后台清理定时器已禁用;当关联的 ILogger 被垃圾回收时,相关条目仍会被释放 |
| .NET 8 | 完整支持 |
| .NET 9 | 完整支持;args 使用 params ReadOnlySpan<object?> 以减少内存分配 |
| .NET 10 | 完整支持;args 使用 params ReadOnlySpan<object?> 以减少内存分配 |
dotnet build
dotnet test
dotnet pack