ThrottledLogging 1.0.9
dotnet add package ThrottledLogging --version 1.0.9
NuGet\Install-Package ThrottledLogging -Version 1.0.9
<PackageReference Include="ThrottledLogging" Version="1.0.9" />
<PackageVersion Include="ThrottledLogging" Version="1.0.9" />
<PackageReference Include="ThrottledLogging" />
paket add ThrottledLogging --version 1.0.9
#r "nuget: ThrottledLogging, 1.0.9"
#:package ThrottledLogging@1.0.9
#addin nuget:?package=ThrottledLogging&version=1.0.9
#tool nuget:?package=ThrottledLogging&version=1.0.9
ThrottledLogging
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.
Projects
| Project | Description |
|---|---|
src/ThrottledLogging |
NuGet library |
examples/GettingStarted |
Console demo covering all features |
Installation
dotnet add package ThrottledLogging
Usage
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.
Suppressed count
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个消息被隐藏)
Multiple independent keys
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");
Configuration
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 |
Requirements
| 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 |
Build
dotnet build
dotnet test
dotnet pack
ThrottledLogging(中文)
基于时间间隔的 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
每个 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
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
-
net10.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
-
net9.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.