.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.开头的LogLevel.Information类别中抽取25%的日志样本。 - 示例所有类别和级别中事件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启动应用程序,实际上,该appsettings.json充当一个不执行任何操作的配置:
{
"Logging": {
"RandomProbabilisticSampler": {
"Rules": [
{
"Probability": 1
}
]
}
}
}
在应用运行时,可以使用以下配置更新 appsettings.json :
{
"Logging": {
"RandomProbabilisticSampler": {
"Rules": [
{
"Probability": 0.01,
"LogLevel": "Information"
}
]
}
}
}
例如,使用上述配置,将自动应用新规则,1% 的包含 LogLevel.Information 的日志会被采样。
如何应用采样规则
该算法与 日志筛选非常相似,但存在一些差异。
对每个日志记录执行日志采样规则评估,但存在性能优化,例如缓存。 以下算法用于给定类别的每个日志记录:
- 选择等于或高于记录器日志级别的规则
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);
上述代码注册了一个采样器,该采样器将对Warning日志进行10%的采样,并对Information(及以下)日志进行1%的采样。 如果配置中没有 Information 的规则,则会对 Warning 日志及其以下所有级别,包括 Information,进行 10% 的采样。
实现自定义采样
可以通过从 LoggingSampler 抽象类派生并重写其抽象成员来创建自定义采样策略。 这样,就可以根据特定要求定制采样行为。 例如,自定义采样器可以:
- 根据日志状态中特定键/值对的状态和值进行采样决策。
- 仅当预定义时间间隔内的日志数保持在低于特定阈值时,才应用速率限制逻辑,例如发出日志。
若要实现自定义采样器,请执行以下步骤:
- 创建继承自 LoggingSampler. 的类。
- 重写LoggingSampler.ShouldSample方法以定义自定义采样逻辑。
- 使用 AddSampler 扩展方法在日志记录管道中注册自定义采样器。
对于未筛选出的每个日志记录,该方法 LoggingSampler.ShouldSample 将完全调用一次。 其返回值确定是否应发出日志记录。
性能注意事项
日志采样旨在降低存储成本,但代价是 CPU 使用率略有增加。 如果您的应用程序生成存储成本高昂的大量日志,日志抽样可以帮助减少这些日志的数量。 正确配置时,采样可以降低存储成本,而不会丢失诊断事件至关重要的信息。
有关内置采样,请参阅 基准。
有关何时使用采样的日志级别指南
| 日志级别 | 建议 |
|---|---|
| Trace | 请勿应用采样,因为通常在生产环境中禁用这些日志 |
| Debug | 请勿应用采样,因为通常在生产环境中禁用这些日志 |
| Information | 请务必应用采样 |
| Warning | 考虑应用采样 |
| Error | 不要应用采样 |
| Critical | 不要应用采样 |
最佳做法
- 从更高的采样率开始,并根据需要向下调整。
- 使用基于类别的规则以特定组件为目标。
- 如果使用分布式跟踪,请考虑实现基于跟踪的采样。
- 共同监视采样规则的有效性。
- 为应用程序找到适当的平衡 - 采样率过低可以降低可观测性,而过高的速率可能会增加成本。