Próbkowanie logów w .NET

Platforma .NET udostępnia funkcje próbkowania dzienników, które umożliwiają kontrolowanie ilości dzienników generowanych przez aplikację bez utraty istotnych informacji. Dostępne są następujące strategie próbkowania:

  • Próbkowanie oparte na śladach: przykładowe dzienniki na podstawie decyzji próbkowania bieżącego śladu.
  • Losowe próbkowanie probabilistyczne: przykładowe dzienniki oparte na skonfigurowanych regułach prawdopodobieństwa.
  • Niestandardowe próbkowanie: zaimplementuj własną niestandardową strategię próbkowania. Aby uzyskać więcej informacji, zobacz Implementowanie niestandardowego próbkowania.

Uwaga / Notatka

Jednocześnie można używać tylko jednego próbkatora. Jeśli zarejestrujesz wiele próbników, zostanie użyty ostatni.

Próbkowanie dzienników rozszerza możliwości filtrowania, zapewniając bardziej szczegółową kontrolę nad tym, jakie dzienniki są emitowane przez aplikację. Zamiast po prostu włączać lub wyłączać dzienniki, można skonfigurować próbkowanie tak, aby emitować tylko część z nich.

Na przykład podczas filtrowania zwykle używa się prawdopodobieństwa, takich jak 0 (emituj nie dzienniki) lub 1 (emituj wszystkie dzienniki), próbkowanie pozwala wybrać dowolną wartość między — na przykład 0.1 emitować 10% dzienników lub 0.25 emitować 25%.

Wprowadzenie

Aby rozpocząć, zainstaluj 📦 pakiet NuGet Microsoft.Extensions.Telemetry :

dotnet add package Microsoft.Extensions.Telemetry

Aby uzyskać więcej informacji, zobacz dotnet add package lub Zarządzanie zależnościami pakietów w aplikacjach platformy .NET.

Konfigurowanie próbkowania opartego na śladach

Próbkowanie oparte na śladach gwarantuje, że dzienniki są próbkowane spójnie z bazowym Activityelementem. Jest to przydatne, gdy chcesz zachować korelację między śladami i dziennikami. Możesz włączyć próbkowanie śledzenia (zgodnie z opisem w przewodniku), a następnie odpowiednio skonfigurować próbkowanie dzienników oparte na śladach:

builder.Logging.AddTraceBasedSampler();

Po włączeniu próbkowania śledzącego, dzienniki będą emitowane tylko wtedy, gdy zostanie próbkowany podstawowy element Activity. Decyzja o próbkowaniu pochodzi z obecnej Recorded wartości.

Konfigurowanie losowego próbkowania probabilistycznego

Losowe próbkowanie probabilistyczne umożliwia próbkowanie dzienników na podstawie skonfigurowanych reguł prawdopodobieństwa. Możesz zdefiniować reguły specyficzne dla:

  • Kategoria dziennika
  • Poziom logowania
  • Identyfikator zdarzenia

Istnieje kilka sposobów konfigurowania losowego próbkowania probabilistycznego przy użyciu reguł:

Konfiguracja oparta na plikach

Utwórz sekcję konfiguracji w appsettings.json, na przykład:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug"
    }
  },

  "RandomProbabilisticSampler": {
    "Rules": [
      {
        "CategoryName": "Microsoft.AspNetCore.*",
        "Probability": 0.25,
        "LogLevel": "Information"
      },
      {
        "CategoryName": "System.*",
        "Probability": 0.1
      },
      {
        "EventId": 1001,
        "Probability": 0.05
      }
    ]
  }
}

Poprzednia konfiguracja:

  • Próbuje 10% logów z kategorii rozpoczynających się od System. ze wszystkich poziomów.
  • Próbki 25% logów z kategorii rozpoczynających się od Microsoft.AspNetCore.LogLevel.Information.
  • Próbuje losować 5% logów z identyfikatorem zdarzenia 1001 ze wszystkich kategorii i poziomów.
  • Pobiera próbki 100% wszystkich innych dzienników.

Ważne

Wartość Probability reprezentuje prawdopodobieństwo z wartościami od 0 do 1. Na przykład 0,25 oznacza, że 25% dzienników będzie próbkowane. 0 oznacza, że nie będą próbkowane żadne dzienniki, a 1 oznacza, że wszystkie dzienniki będą próbkowane. Te przypadki o wartości 0 i 1 mogą być używane do efektywnego wyłączania lub włączania wszystkich dzienników rejestrów dla określonej reguły. Prawdopodobieństwo nie może być mniejsze niż 0 lub większe niż 1, a jeśli wystąpi to w aplikacji, zgłaszany jest wyjątek.

Aby zarejestrować przykładomierz przy użyciu konfiguracji, rozważ następujący kod:

builder.Logging.AddRandomProbabilisticSampler(builder.Configuration);

Zmienianie reguł próbkowania w uruchomionej aplikacji

Losowe próbkowanie probabilistyczne obsługuje aktualizacje konfiguracji środowiska uruchomieniowego za pośrednictwem interfejsu IOptionsMonitor<TOptions> . Jeśli używasz dostawcy konfiguracji obsługującego ponowne ładowanie — na przykład dostawcę konfiguracji plików — możesz zaktualizować reguły próbkowania w czasie wykonywania bez ponownego uruchamiania aplikacji.

Możesz na przykład uruchomić aplikację przy użyciu następującej appsettings.json, która skutecznie działa jako no-op:

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

Gdy aplikacja jest uruchomiona, możesz zaktualizować appsettings.json przy użyciu następującej konfiguracji:

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

Nowe reguły zostaną zastosowane automatycznie, na przykład z wcześniejszą konfiguracją, 1% dzienników z LogLevel.Information jest analizowany.

Jak są stosowane reguły próbkowania

Algorytm jest bardzo podobny do filtrowania dzienników, ale istnieją pewne różnice.

Ocena reguł próbkowania logów jest wykonywana dla każdego rekordu logu, jednak wprowadzono optymalizacje wydajności, takie jak cache'owanie. Następujący algorytm jest używany dla każdego rekordu dziennika dla danej kategorii:

  • Wybierz reguły o LogLevel wartości równej lub wyższej niż poziom dziennika rejestratora.
  • Wybierz reguły, gdzie EventId nie jest zdefiniowane lub gdzie jest zdefiniowane i równe identyfikatorowi zdarzenia dziennika.
  • Wybierz reguły z najdłuższym pasującym prefiksem kategorii. Jeśli nie zostanie znalezione żadne dopasowanie, wybierz wszystkie reguły, które nie określają kategorii.
  • Jeśli wybrano wiele reguł, użyj ostatniej.
  • Jeśli nie wybrano żadnych reguł, próbkowanie nie jest stosowane, na przykład rekord dziennika jest emitowany jak zwykle.

Konfiguracja kodu wbudowanego

builder.Logging.AddRandomProbabilisticSampler(options =>
{
    options.Rules.Add(
        new RandomProbabilisticSamplerFilterRule(
            probability: 0.05d,
            eventId : 1001));
});

Poprzednia konfiguracja:

  • Próbuje losować 5% logów z identyfikatorem zdarzenia 1001 ze wszystkich kategorii i poziomów.
  • Pobiera próbki 100% wszystkich innych dzienników.

Prosta konfiguracja prawdopodobieństwa

W przypadku podstawowych scenariuszy można skonfigurować pojedynczą wartość prawdopodobieństwa, która ma zastosowanie do wszystkich dzienników na lub poniżej określonego poziomu:

builder.Logging.AddRandomProbabilisticSampler(0.01, LogLevel.Information);
builder.Logging.AddRandomProbabilisticSampler(0.1, LogLevel.Warning);

Powyższy kod rejestruje sampler, który próbuje 10% dzienników Warning i 1% dzienników Information (i niższych). Jeśli konfiguracja nie ma reguły dla Information, próbkowałby 10% dzienników Warning i wszystkich poziomów poniżej, w tym Information.

Implementowanie niestandardowego próbkowania

Możesz utworzyć niestandardową strategię próbkowania, wyprowadzając ją z LoggingSampler klasy abstrakcyjnej i przesłaniając jej abstrakcyjne elementy członkowskie. Dzięki temu można dostosować zachowanie próbkowania do określonych wymagań. Na przykład niestandardowy próbnik może:

  • Podejmuj decyzje dotyczące próbkowania w oparciu o obecność i wartość określonych par klucz/wartość w stanie logu.
  • Zastosuj logikę ograniczania szybkości, taką jak emitowanie dzienników tylko wtedy, gdy liczba dzienników w wstępnie zdefiniowanym przedziale czasu pozostaje poniżej określonego progu.

Aby zaimplementować niestandardowy próbnik, wykonaj następujące kroki:

  1. Utwórz klasę, która dziedziczy po LoggingSampler.
  2. Zastąp metodę LoggingSampler.ShouldSample, aby zdefiniować niestandardową logikę próbkowania.
  3. Zarejestruj niestandardowy próbnik w potoku rejestrowania przy użyciu metody rozszerzenia AddSampler.

Dla każdego rekordu dziennika, który nie jest odfiltrowany, LoggingSampler.ShouldSample metoda jest wywoływana dokładnie raz. Jego wartość zwracana określa, czy rekord dziennika powinien być emitowany.

Zagadnienia dotyczące wydajności

Próbkowanie logów zostało zaprojektowane w celu zmniejszenia kosztów magazynowania z nieznacznie zwiększonym użyciem CPU. Jeśli aplikacja generuje dużą ilość dzienników, które są kosztowne do przechowywania, próbkowanie może pomóc zmniejszyć ten wolumin. W przypadku odpowiedniego skonfigurowania próbkowanie może obniżyć koszty magazynowania bez utraty informacji, które mają krytyczne znaczenie dla diagnozowania zdarzeń.

Aby zapoznać się z wbudowanym próbkowaniem, zobacz Testy porównawcze.

Wskazówki dotyczące poziomu logowania o tym, kiedy używać próbkowania

Poziom logowania Rekomendacja
Trace Nie stosuj próbkowania, ponieważ zwykle te dzienniki są wyłączone w środowisku produkcyjnym
Debug Nie stosuj próbkowania, ponieważ zwykle te dzienniki są wyłączone w środowisku produkcyjnym
Information Zastosuj próbkowanie
Warning Rozważ zastosowanie próbkowania
Error Nie stosuj próbkowania
Critical Nie stosuj próbkowania

Najlepsze rozwiązania

  • Zacznij od wyższych częstotliwości próbkowania i dostosuj je w dół w razie potrzeby.
  • Użyj reguł opartych na kategoriach, aby kierować do określonych składników.
  • Jeśli używasz śledzenia rozproszonego, rozważ zaimplementowanie próbkowania opartego na śladach.
  • Zbiorcze monitorowanie skuteczności reguł próbkowania.
  • Znajdź właściwą równowagę dla aplikacji — zbyt niska częstotliwość próbkowania może zmniejszyć zauważalność, podczas gdy zbyt wysoka stawka może zwiększyć koszty.

Zobacz także