.NET 提供日志采样功能,使你能够控制应用程序发出的日志量,而不会丢失重要信息。 可以使用以下采样策略:
- 基于跟踪的采样:基于当前跟踪的采样决策采样日志。
- 随机概率采样:基于配置的概率规则对日志进行采样。
- 自定义采样:实现自己的自定义采样策略。 有关详细信息,请参阅 “实现自定义采样”。
注释
一次只能使用一个采样器。 如果注册多个采样器,则使用最后一个采样器。
日志采样通过更精细地控制应用程序发出的日志来扩展 筛选功能 。 与其简单地启用或禁用日志,您可以通过配置采样比例来仅发出部分日志。
例如,虽然筛选通常使用概率( 0
不发出日志)或 1
(发出所有日志),但采样允许你选择介于两者之间的任何值,例如 0.1
发出 10 个日志%,或 0.25
发出 25 个%。
开始吧
若要开始,请安装 📦 Microsoft.Extensions.Telemetry NuGet 包:
有关详细信息,请参阅 dotnet add package 或管理 .NET 应用程序中的包依赖项。
配置基于跟踪的采样
基于跟踪的采样可确保日志被与底层Activity一致地采样。 如果要在跟踪和日志之间保持相关性,这非常有用。 可以启用跟踪采样(如 指南中所述),然后相应地配置基于跟踪的日志采样:
builder.Logging.AddTraceBasedSampler();
当启用基于跟踪的采样时,仅当基础 Activity 被采样时才会记录日志。 采样决策来自当前 Recorded 值。
配置随机概率采样
随机概率采样允许你根据配置的概率规则对日志进行采样。 可以定义以下特定规则:
- 日志类别
- 日志级别
- 事件编号
有多种方法可以配置随机概率采样及其规则:
基于文件的配置
在 appsettings.json中创建配置部分,例如:
{
"Logging": {
"LogLevel": {
"Default": "Debug"
}
},
"RandomProbabilisticSampler": {
"Rules": [
{
"CategoryName": "Microsoft.AspNetCore.*",
"Probability": 0.25,
"LogLevel": "Information"
},
{
"CategoryName": "System.*",
"Probability": 0.1
},
{
"EventId": 1001,
"Probability": 0.05
}
]
}
}
上述配置:
- 从所有级别开始
System.
的类别中的日志示例 10%。 - 从以
Microsoft.AspNetCore.
开头的类别中抽取 25% 的日志样本 LogLevel.Information。 - 包含事件 ID 为 1001 的所有类别和级别日志的示例 5%。
- 从所有其他日志中采样 100%。
重要
该值 Probability 表示值为 0 到 1 的概率。 例如,0.25 表示将采集25单位的% 日志。 0 表示不会采样任何日志,1 表示将采样所有日志。 这些包含 0 和 1 的案例可以有效地禁用或启用特定规则的所有日志。 概率不能小于 0 或大于 1,如果这种情况发生在应用程序中,则会引发异常。
要将采样器与配置进行注册,请按以下代码操作:
builder.Logging.AddRandomProbabilisticSampler(builder.Configuration);
更改正在运行的应用中的采样规则
随机概率采样支持通过 IOptionsMonitor<TOptions> 接口进行运行时配置更新。 如果使用支持重载的配置提供程序(如 文件配置提供程序),则可以在运行时更新采样规则,而无需重启应用程序。
例如,可以使用以下 appsettings.json 启动应用程序,它实际上充当 no-op:
{
"Logging": {
"RandomProbabilisticSampler": {
"Rules": [
{
"Probability": 1
}
]
}
}
}
在应用运行时,可以使用以下配置更新 appsettings.json :
{
"Logging": {
"RandomProbabilisticSampler": {
"Rules": [
{
"Probability": 0.01,
"LogLevel": "Information"
}
]
}
}
}
例如,根据上述配置,新规则将被自动应用,例如,带有 LogLevel.Information 标记的% 类日志中,有 1 个会被采样。
如何应用采样规则
该算法与 日志筛选非常相似,但存在一些差异。
对每个日志记录执行日志采样规则评估,但存在性能优化,例如缓存。 以下算法用于给定类别的每个日志记录:
- 选择等于或高于记录器日志级别的规则
LogLevel
。 - 选择
EventId
未定义或已定义且等于日志事件 ID 的规则。 - 选择具有最长匹配类别前缀的规则。 如果找不到任何匹配项,则选择未指定类别的所有规则。
- 如果选择了多条规则,则采用最后一条 。
- 如果未选择任何规则,则不会应用采样,例如,日志记录会照常发出。
内联代码配置
builder.Logging.AddRandomProbabilisticSampler(options =>
{
options.Rules.Add(
new RandomProbabilisticSamplerFilterRule(
probability: 0.05d,
eventId : 1001));
});
上述配置:
- 包含事件 ID 为 1001 的所有类别和级别日志的示例 5%。
- 从所有其他日志中采样 100%。
简单概率配置
对于基本方案,可以配置适用于指定级别或以下的所有日志的单个概率值:
builder.Logging.AddRandomProbabilisticSampler(0.01, LogLevel.Information);
builder.Logging.AddRandomProbabilisticSampler(0.1, LogLevel.Warning);
上面的代码注册了采样器,该采样器将采集 10 次% 类型的 Warning 日志,以及 1 次% 类型的 Information(及以下)日志。 如果配置中没有为 Information 设置规则,则会采集 Warning 日志以及以下所有级别的日志(包括 Information),总计 10%。
实现自定义采样
可以通过从 LoggingSampler 抽象类派生并重写其抽象成员来创建自定义采样策略。 这样,就可以根据特定要求定制采样行为。 例如,自定义采样器可以:
- 根据日志状态中特定键/值对的状态和值进行采样决策。
- 仅当预定义时间间隔内的日志数保持在低于特定阈值时,才应用速率限制逻辑,例如发出日志。
若要实现自定义采样器,请执行以下步骤:
- 创建继承自 LoggingSampler. 的类。
- LoggingSampler.ShouldSample重写方法以定义自定义采样逻辑。
- 使用 AddSampler 扩展方法在日志记录管道中注册自定义采样器。
对于未筛选出的每个日志记录,该方法 LoggingSampler.ShouldSample 将完全调用一次。 其返回值确定是否应发出日志记录。
性能注意事项
日志采样旨在降低存储成本,但需要平衡的是 CPU 使用率略有增加。 如果您的应用程序生成大量且存储成本高昂的日志,抽样有助于减少这些日志的数量。 正确配置时,采样可以降低存储成本,而不会丢失诊断事件至关重要的信息。
有关内置采样,请参阅 基准。
有关何时使用采样的日志级别指南
日志级别 | 建议 |
---|---|
Trace | 请勿应用采样处理,因为在生产环境中通常会禁用这些日志 |
Debug | 请勿应用采样处理,因为在生产环境中通常会禁用这些日志 |
Information | 务必进行采样 |
Warning | 可以考虑采取采样技术 |
Error | 不要应用采样 |
Critical | 不要应用采样 |
最佳做法
- 从更高的采样率开始,并根据需要向下调整。
- 使用基于类别的规则以特定组件为目标。
- 如果使用分布式跟踪,请考虑实现基于跟踪的采样。
- 共同监视采样规则的有效性。
- 为应用程序找到适当的平衡 - 采样率过低可以降低可观测性,而过高的速率可能会增加成本。