通过


.NET 中的日志采样

.NET 提供日志采样功能,使你能够控制应用程序发出的日志量,而不会丢失重要信息。 可以使用以下采样策略:

  • 基于跟踪的采样:根据当前跟踪的采样决策进行日志采样。
  • 随机概率采样:基于配置的概率规则对日志进行采样。
  • 自定义采样:实现自己的自定义采样策略。 有关详细信息,请参阅 “实现自定义采样”。

注释

一次只能使用一个采样器。 如果注册多个采样器,则使用最后一个采样器。

日志采样通过更精细地控制应用程序发出的日志来扩展 筛选功能 。 与其简单地启用或禁用日志,您可以配置日志采样,以仅发出其中的一小部分。

例如,虽然筛选通常使用概率( 0 不发出日志)或 1 (发出所有日志),但采样允许你选择介于两者之间的任何值,例如 0.1 发出 10 个日志%,或 0.25 发出 25 个%。

开始

若要开始,请安装 📦 Microsoft.Extensions.Telemetry NuGet 包:

dotnet add package Microsoft.Extensions.Telemetry

有关详细信息,请参阅 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 抽象类派生并重写其抽象成员来创建自定义采样策略。 这样,就可以根据特定要求定制采样行为。 例如,自定义采样器可以:

  • 根据日志状态中特定键/值对的状态和值进行采样决策。
  • 仅当预定义时间间隔内的日志数保持在低于特定阈值时,才应用速率限制逻辑,例如发出日志。

若要实现自定义采样器,请执行以下步骤:

  1. 创建继承自 LoggingSampler. 的类。
  2. 重写LoggingSampler.ShouldSample方法以定义自定义采样逻辑。
  3. 使用 AddSampler 扩展方法在日志记录管道中注册自定义采样器。

对于未筛选出的每个日志记录,该方法 LoggingSampler.ShouldSample 将完全调用一次。 其返回值确定是否应发出日志记录。

性能注意事项

日志采样旨在降低存储成本,但代价是 CPU 使用率略有增加。 如果您的应用程序生成存储成本高昂的大量日志,日志抽样可以帮助减少这些日志的数量。 正确配置时,采样可以降低存储成本,而不会丢失诊断事件至关重要的信息。

有关内置采样,请参阅 基准

有关何时使用采样的日志级别指南

日志级别 建议
Trace 请勿应用采样,因为通常在生产环境中禁用这些日志
Debug 请勿应用采样,因为通常在生产环境中禁用这些日志
Information 请务必应用采样
Warning 考虑应用采样
Error 不要应用采样
Critical 不要应用采样

最佳做法

  • 从更高的采样率开始,并根据需要向下调整。
  • 使用基于类别的规则以特定组件为目标。
  • 如果使用分布式跟踪,请考虑实现基于跟踪的采样。
  • 共同监视采样规则的有效性。
  • 为应用程序找到适当的平衡 - 采样率过低可以降低可观测性,而过高的速率可能会增加成本。

另请参阅