共用方式為


.NET 中的日誌取樣

.NET 提供日誌取樣功能,讓你能控制應用程式所發出的日誌量,同時不損失重要資訊。 以下抽樣策略可用:

  • 基於痕跡的取樣:根據當前追蹤的取樣決策取樣日誌。
  • 隨機機率抽樣:基於配置的機率規則進行抽樣日誌。
  • 客製化抽樣:實施您自己的客製化抽樣策略。 更多資訊請參見 「實作自訂抽樣」。

備註

一次只能使用一個取樣器。 如果你註冊多個取樣器,最後一個會被使用。

日誌取樣擴展了 過濾功能 ,讓你能更細緻地控制應用程式會發出哪些日誌。 與其只是啟用或關閉日誌檔,你可以設定取樣率來僅發送其中一小部分。

例如,過濾通常使用機率,如0(不輸出日誌)或1(輸出所有日誌),而抽樣允許你選擇介於兩者之間的任意值——例如0.1 以輸出10%的日誌,或0.25 以輸出25%的日誌。

開始

若要開始使用,請安裝 📦 Microsoft.Extensions.Telemetry NuGet 套件:

dotnet add package Microsoft.Extensions.Telemetry

如需詳細資訊,請參閱 dotnet 新增套件在 .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啟動你的應用程式,實際上就像是無操作:

{
  "Logging": {
    "RandomProbabilisticSampler": {
      "Rules": [
        {
          "Probability": 1
        }
      ]
    }
  }
}

當應用程式執行時,您可以使用下列設定來更新 appsettings.json

{
  "Logging": {
    "RandomProbabilisticSampler": {
      "Rules": [
        {
          "Probability": 0.01,
          "LogLevel": "Information"
        }
      ]
    }
  }
}

新規則將自動套用,例如在前述配置中,會抽取 1% 的 LogLevel.Information 日誌。

抽樣規則的應用方式

這個演算法與 對數過濾非常相似,但仍有一些差異。

日誌取樣規則的評估會對每個日誌記錄進行,然而已實施效能優化機制,例如快取。 針對給定類別的每個對數記錄,使用以下演算法:

  • 選擇日誌等級等於或高於記錄器所設定的規則。
  • 請選擇未定義或已定義且等於日誌事件 ID 的 EventId 規則。
  • 選擇具有最長類別前綴的匹配規則。 如果找不到匹配,請選擇所有未指定類別的規則。
  • 如果選取多個規則,請使用最後一個。
  • 若未選擇規則,則不進行抽樣,例如日誌記錄會照常發出。

內嵌程式碼設定

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 的規則,則將抽樣10%的 Warning 日誌及其以下所有層級,包括 Information

實作自訂抽樣

你可以從抽象類別 LoggingSampler 衍生並重寫其抽象成員,來建立自訂取樣策略。 這讓你能根據自身需求調整抽樣行為。 例如,客製化取樣器可以:

  • 根據日誌狀態中特定鍵值對的存在與價值來做抽樣決策。
  • 應用速率限制邏輯,例如只有在預定時間區間內的日誌數量低於某個閾值時才會發出日誌。

要實作自訂取樣器,請依照以下步驟操作:

  1. 建立繼承自 LoggingSampler的類別。
  2. LoggingSampler.ShouldSample 方法覆寫來定義您的自訂取樣邏輯。
  3. AddSampler 擴充功能在日誌管線註冊你的自訂取樣器。

對於每個未被過濾的日誌記錄, LoggingSampler.ShouldSample 該方法只被呼叫一次。 其回傳值決定是否應該發出該日誌記錄。

效能考量

日誌取樣旨在降低儲存成本,但需在 CPU 使用率略有增加的代價中取得平衡。 如果您的應用程式產生大量存儲成本高的日誌,抽樣可以幫助減少這些數量。 適當配置時,抽樣能降低儲存成本,同時避免遺失對事故診斷至關重要的資訊。

關於內建的取樣,請參見 基準測試

日誌層級的指引,關於何時使用抽樣

記錄等級 Recommendation
Trace 不要套用取樣,因為在生產環境中通常會停用這些日誌。
Debug 不要套用取樣,因為在生產環境中通常會停用這些日誌。
Information 請應用抽樣
Warning 考慮應用抽樣
Error 不要套用抽樣
Critical 不要套用抽樣

最佳做法

  • 從較高的取樣率開始,並視需要調整。
  • 使用類別式規則來鎖定特定元件。
  • 如果你使用的是分散式追蹤,可以考慮實作基於痕跡的取樣。
  • 集體監控抽樣規則的有效性。
  • 找到適合您應用的平衡點——取樣率過低會降低可觀察性,而取樣率過高則會增加成本。

另請參閱