Rejestrowanie na platformie .NET Core i ASP.NET Core

Autor: Kirk Larkin, Juergen Gutsch i Rick Anderson

W tym temacie opisano rejestrowanie na platformie .NET, ponieważ dotyczy ASP.NET Core aplikacji. Aby uzyskać szczegółowe informacje na temat rejestrowania na platformie .NET, zobacz Rejestrowanie na platformie .NET. Aby uzyskać więcej informacji na temat rejestrowania Blazor aplikacji, zobacz rejestrowanie ASP.NET CoreBlazor.

Dostawcy rejestrowania

Dostawcy rejestrowania przechowują Console dzienniki z wyjątkiem dostawcy, który wyświetla dzienniki. Na przykład dostawca usługi aplikacja systemu Azure Insights przechowuje dzienniki w usłudze aplikacja systemu Azure Insights. Można włączyć wielu dostawców.

Domyślne szablony aplikacji internetowej ASP.NET Core:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Powyższy kod przedstawia Program.cs plik utworzony przy użyciu szablonów aplikacji internetowej ASP.NET Core. W następnych kilku sekcjach przedstawiono przykłady oparte na szablonach aplikacji internetowej ASP.NET Core, które korzystają z hosta ogólnego.

Poniższy kod zastępuje domyślny zestaw dostawców rejestrowania dodany przez program WebApplication.CreateBuilder:

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Alternatywnie powyższy kod rejestrowania można napisać w następujący sposób:

var builder = WebApplication.CreateBuilder();
builder.Host.ConfigureLogging(logging =>
{
    logging.ClearProviders();
    logging.AddConsole();
});

Aby uzyskać więcej dostawców, zobacz:

Tworzenie dzienników

Aby utworzyć dzienniki, użyj ILogger<TCategoryName> obiektu z iniekcji zależności (DI).

Poniższy przykład:

  • Tworzy rejestrator , ILogger<AboutModel>który używa kategorii dziennika w pełni kwalifikowanej nazwy typu AboutModel. Kategoria dziennika jest ciągiem skojarzonym z każdym dziennikiem.
  • Wywołania LogInformation do rejestrowania na Information poziomie. Poziom dziennika wskazuje ważność zarejestrowanego zdarzenia.
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("About page visited at {DT}", 
            DateTime.UtcNow.ToLongTimeString());
    }
}

Poziomy i kategorie zostały szczegółowo wyjaśnione w dalszej części tego dokumentu.

Aby uzyskać informacje na Blazortemat programu , zobacz rejestrowanie ASP.NET CoreBlazor.

Konfigurowanie rejestrowania

Konfiguracja rejestrowania jest często dostarczana przez Logging sekcję appsettings.{ENVIRONMENT}.json plików, w której {ENVIRONMENT} symbol zastępczy jest środowiskiem. Następujący appsettings.Development.json plik jest generowany przez szablony aplikacji internetowej ASP.NET Core:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

W poprzedniej JSsekcji ON:

  • Określono "Default" kategorie i "Microsoft.AspNetCore" .
  • Kategoria "Microsoft.AspNetCore" ma zastosowanie do wszystkich kategorii rozpoczynających się od "Microsoft.AspNetCore". Na przykład to ustawienie dotyczy "Microsoft.AspNetCore.Routing.EndpointMiddleware" kategorii.
  • Kategoria "Microsoft.AspNetCore" rejestruje się na poziomie Warning dziennika i wyższym.
  • Nie określono określonego dostawcy dziennika, więc LogLevel dotyczy wszystkich dostawców rejestrowania z włączoną obsługą z wyjątkiem dziennika zdarzeń systemu Windows.

Właściwość Logging może zawierać LogLevel właściwości dostawcy dzienników i je rejestrować. Parametr LogLevel określa minimalny poziom rejestrowania dla wybranych kategorii. W poprzednich JSpoziomach WŁ., Information a Warning poziomy dziennika są określone. LogLevel wskazuje ważność dziennika i zakresy od 0 do 6:

Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5 i None = 6.

Po określeniu parametru LogLevel rejestrowanie jest włączone dla komunikatów na określonym poziomie i wyższym. W poprzedniej JSsekcji WŁ. kategoria jest rejestrowana Default i Information wyższa. Na przykład rejestrowane Informationsą komunikaty , Warning, Errori Critical . Jeśli nie LogLevel zostanie określony, rejestrowanie jest domyślnie ustawione na Information poziomie. Aby uzyskać więcej informacji, zobacz Poziomy dzienników.

Właściwość dostawcy może określać LogLevel właściwość. LogLevel w obszarze dostawcy określa poziomy rejestrowania dla tego dostawcy i zastępuje ustawienia dziennika innego niż dostawca. Rozważ następujący appsettings.json plik:

{
  "Logging": {
    "LogLevel": { // All providers, LogLevel applies to all the enabled providers.
      "Default": "Error", // Default logging, Error and higher.
      "Microsoft": "Warning" // All Microsoft* categories, Warning and higher.
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information", // Overrides preceding LogLevel:Default setting.
        "Microsoft.Hosting": "Trace" // Debug:Microsoft.Hosting category.
      }
    },
    "EventSource": { // EventSource provider
      "LogLevel": {
        "Default": "Warning" // All categories of EventSource provider.
      }
    }
  }
}

Ustawienia w Logging.{PROVIDER NAME}.LogLevel ustawieniach zastępowania w programie Logging.LogLevel, gdzie {PROVIDER NAME} symbol zastępczy jest nazwą dostawcy. W poprzednim JSDebug wł. domyślny poziom dziennika dostawcy ma wartość Information:

Logging:Debug:LogLevel:Default:Information

Poprzednie ustawienie określa Information poziom dziennika dla każdej Logging:Debug: kategorii z wyjątkiem Microsoft.Hosting. Po wyświetleniu określonej kategorii określona kategoria zastępuje kategorię domyślną. W poprzednim JSobszarze WŁ Logging:Debug:LogLevel . kategorie "Microsoft.Hosting" i "Default" przesłaniają ustawienia w pliku Logging:LogLevel.

Minimalny poziom dziennika można określić dla dowolnego z następujących elementów:

  • Konkretni dostawcy: na przykład Logging:EventSource:LogLevel:Default:Information
  • Określone kategorie: na przykład Logging:LogLevel:Microsoft:Warning
  • Wszyscy dostawcy i wszystkie kategorie: Logging:LogLevel:Default:Warning

Wszystkie dzienniki poniżej poziomu minimalnego nie są następujące:

  • Przekazano do dostawcy.
  • Zarejestrowane lub wyświetlone.

Aby pominąć wszystkie dzienniki, określ LogLevel.Nonewartość . LogLevel.None ma wartość 6, która jest wyższa niż LogLevel.Critical (5).

Jeśli dostawca obsługuje zakresy dzienników, wskazuje, IncludeScopes czy są one włączone. Aby uzyskać więcej informacji, zobacz zakresy dzienników.

appsettings.json Następujący plik zawiera domyślnie wszystkich dostawców, którzy są włączeni:

{
  "Logging": {
    "LogLevel": { // No provider, LogLevel applies to all the enabled providers.
      "Default": "Error",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information" // Overrides preceding LogLevel:Default setting.
      }
    },
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "Default": "Information"
      }
    },
    "EventSource": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "EventLog": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "AzureAppServicesFile": {
      "IncludeScopes": true,
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "AzureAppServicesBlob": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "ApplicationInsights": {
      "LogLevel": {
        "Default": "Information"
      }
    }
  }
}

W poprzednim przykładzie:

  • Kategorie i poziomy nie są sugerowane. Przykład jest dostarczany, aby wyświetlić wszystkich dostawców domyślnych.
  • Ustawienia w Logging.{PROVIDER NAME}.LogLevel ustawieniach zastępowania w programie Logging.LogLevel, gdzie {PROVIDER NAME} symbol zastępczy jest nazwą dostawcy. Na przykład poziom w Debug.LogLevel.Default zastąpieniu poziomu w LogLevel.Defaultelemecie .
  • Każdy domyślny alias dostawcy jest używany. Każdy dostawca definiuje alias , który może być używany w konfiguracji zamiast w pełni kwalifikowanej nazwy typu. Aliasy wbudowanych dostawców to:
    • Console
    • Debug
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

Zaloguj się Program.cs

Poniższy przykład wywołuje komunikaty informacyjne Builder.WebApplication.Logger i Program.cs rejestruje komunikaty informacyjne:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Logger.LogInformation("Adding Routes");
app.MapGet("/", () => "Hello World!");
app.Logger.LogInformation("Starting the app");
app.Run();

W poniższym przykładzie są wywoływane i AddConsoleProgram.cs dzienniki punktu końcowego /Test :

var builder = WebApplication.CreateBuilder(args);

var logger = LoggerFactory.Create(config =>
{
    config.AddConsole();
}).CreateLogger("Program");

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async context =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await context.Response.WriteAsync("Testing");
});

app.Run();

Następujące przykładowe wywołania AddSimpleConsole w programie Program.cswyłącza dane wyjściowe kolorów i rejestruje /Test punkt końcowy:

using Microsoft.Extensions.Logging.Console;

var builder = WebApplication.CreateBuilder(args);

using var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddSimpleConsole(i => i.ColorBehavior = LoggerColorBehavior.Disabled);
});

var logger = loggerFactory.CreateLogger<Program>();

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async context =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await context.Response.WriteAsync("Testing");
});

app.Run();

Ustawianie poziomu dziennika według wiersza polecenia, zmiennych środowiskowych i innych konfiguracji

Poziom dziennika można ustawić przez dowolnego dostawcę konfiguracji.

Separator : nie działa z kluczami hierarchicznymi zmiennych środowiskowych na wszystkich platformach. __, podwójne podkreślenie, to:

  • Obsługiwane przez wszystkie platformy. Na przykład separator nie jest obsługiwany przez powłokę :Bash, ale __ jest.
  • Automatycznie zastąpione przez :

Następujące polecenia:

  • Ustaw klucz Logging:LogLevel:Microsoft środowiska na wartość Information w systemie Windows.
  • Przetestuj ustawienia podczas korzystania z aplikacji utworzonej przy użyciu szablonów aplikacji internetowych ASP.NET Core. Polecenie dotnet run musi być uruchamiane w katalogu projektu po użyciu polecenia set.
set Logging__LogLevel__Microsoft=Information
dotnet run

Poprzednie ustawienie środowiska:

  • Jest ustawiany tylko w procesach uruchamianych z okna poleceń, w których zostały ustawione.
  • Nie jest odczytywany przez przeglądarki uruchomione za pomocą programu Visual Studio.

Następujące polecenie setx ustawia również klucz środowiska i wartość w systemie Windows. W przeciwieństwie do setelementu setx ustawienia są utrwalane. Przełącznik /M ustawia zmienną w środowisku systemowym. Jeśli /M nie jest używana, zostanie ustawiona zmienna środowiskowa użytkownika.

setx Logging__LogLevel__Microsoft Information /M

Rozważ następujący appsettings.json plik:

"Logging": {
  "Console": {
    "LogLevel": {
      "Microsoft.Hosting.Lifetime": "Trace"
    }
  }
}

Następujące polecenie ustawia poprzednią konfigurację w środowisku:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

Na Azure App Service wybierz pozycję Nowe ustawienie aplikacji na stronie Konfiguracja ustawień>. Azure App Service ustawienia aplikacji są następujące:

  • Szyfrowane w spoczynku i przesyłane za pośrednictwem zaszyfrowanego kanału.
  • Uwidocznione jako zmienne środowiskowe.

Aby uzyskać więcej informacji, zobacz Azure Apps: Zastępowanie konfiguracji aplikacji przy użyciu witryny Azure Portal.

Aby uzyskać więcej informacji na temat ustawiania wartości konfiguracji ASP.NET Core przy użyciu zmiennych środowiskowych, zobacz zmienne środowiskowe. Aby uzyskać informacje na temat korzystania z innych źródeł konfiguracji, w tym wiersza polecenia, usługi Azure Key Vault, Azure App Configuration, innych formatów plików i nie tylko, zobacz Konfiguracja w ASP.NET Core.

Jak są stosowane reguły filtrowania

Po utworzeniu ILogger<TCategoryName> obiektu obiekt wybiera jedną regułę dla każdego dostawcy, ILoggerFactory która ma być stosowana do tego rejestratora. Wszystkie komunikaty zapisywane przez ILogger wystąpienie są filtrowane na podstawie wybranych reguł. Najbardziej konkretna reguła dla każdego dostawcy i pary kategorii jest wybierana z dostępnych reguł.

Następujący algorytm jest używany dla każdego dostawcy podczas ILogger tworzenia elementu dla danej kategorii:

  • Wybierz wszystkie reguły zgodne z dostawcą lub jego aliasem. Jeśli nie zostanie znalezione dopasowanie, wybierz wszystkie reguły z pustym dostawcą.
  • W wyniku poprzedniego kroku wybierz reguły z najdłuższym pasującym prefiksem kategorii. Jeśli nie zostanie znalezione dopasowanie, wybierz wszystkie reguły, które nie określają kategorii.
  • Jeśli wybrano wiele reguł, weź ostatni .
  • Jeśli nie wybrano żadnych reguł, użyj polecenia MinimumLevel.

Rejestrowanie danych wyjściowych z polecenia dotnet run i programu Visual Studio

Zostaną wyświetlone dzienniki utworzone przy użyciu domyślnych dostawców rejestrowania :

  • W programie Visual Studio
    • W oknie Debugowanie danych wyjściowych podczas debugowania.
    • W oknie ASP.NET Core Serwera sieci Web.
  • W oknie konsoli po uruchomieniu aplikacji za pomocą dotnet runpolecenia .

Dzienniki rozpoczynające się od kategorii "Microsoft" pochodzą z kodu platformy ASP.NET Core. ASP.NET Core i kod aplikacji używają tego samego interfejsu API rejestrowania i dostawców.

Kategoria dziennika

Po utworzeniu ILogger obiektu zostanie określona kategoria . Ta kategoria jest dołączona do każdego komunikatu dziennika utworzonego przez to wystąpienie klasy ILogger. Ciąg kategorii jest dowolny, ale konwencja polega na użyciu nazwy klasy. Na przykład w kontrolerze nazwą może być "TodoApi.Controllers.TodoController". Aplikacje internetowe ASP.NET Core automatycznie ILogger<T> pobierają ILogger wystąpienie, które używa w pełni kwalifikowanej T nazwy typu jako kategorii:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

Aby jawnie określić kategorię, wywołaj metodę ILoggerFactory.CreateLogger:

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }

Wywoływanie CreateLogger przy użyciu stałej nazwy może być przydatne w przypadku użycia w wielu metodach, dzięki czemu zdarzenia mogą być zorganizowane według kategorii.

ILogger<T> jest odpowiednikiem wywołania CreateLogger z w pełni kwalifikowaną nazwą Ttypu .

Poziom dziennika

W poniższej tabeli wymieniono LogLevel wartości, metodę rozszerzenia wygody Log{LogLevel} i sugerowane użycie:

LogLevel Wartość Metoda Opis
Trace 0 LogTrace Zawiera najbardziej szczegółowe komunikaty. Te komunikaty mogą zawierać poufne dane aplikacji. Te komunikaty są domyślnie wyłączone i nie powinny być włączone w środowisku produkcyjnym.
Debug 1 LogDebug Do debugowania i programowania. Należy zachować ostrożność w środowisku produkcyjnym ze względu na dużą ilość.
Information 2 LogInformation Śledzi ogólny przepływ aplikacji. Może mieć wartość długoterminową.
Warning 3 LogWarning W przypadku nietypowych lub nieoczekiwanych zdarzeń. Zazwyczaj obejmuje błędy lub warunki, które nie powodują niepowodzenia aplikacji.
Error 4 LogError W przypadku błędów i wyjątków, których nie można obsłużyć. Te komunikaty wskazują błąd w bieżącej operacji lub żądaniu, a nie awarii dla całej aplikacji.
Critical 5 LogCritical W przypadku awarii wymagających natychmiastowej uwagi. Przykłady: scenariusze utraty danych, brak miejsca na dysku.
None 6 Określa, że kategoria rejestrowania nie powinna zapisywać komunikatów.

W poprzedniej tabeli LogLevel element jest wymieniony z najniższej do najwyższej ważności.

Pierwszy Log parametr metody wskazuje LogLevelważność dziennika. Zamiast wywoływać Log(LogLevel, ...)metodę , większość deweloperów wywołuje Log{LOG LEVEL} metody rozszerzenia, gdzie {LOG LEVEL} symbol zastępczy jest poziomem dziennika. Na przykład następujące dwa wywołania rejestrowania są funkcjonalnie równoważne i tworzą ten sam dziennik:

[HttpGet]
public IActionResult Test1(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);

    _logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    return ControllerContext.MyDisplayRouteInfo();
}

MyLogEvents.TestItem to identyfikator zdarzenia. MyLogEvents jest częścią przykładowej aplikacji i jest wyświetlana w sekcji Identyfikator zdarzenia dziennika .

Polecenia MyDisplayRouteInfo i ToCtxString są dostarczane przez pakiet NuGet Rick.Docs.Samples.RouteInfo . Metody wyświetlają Controller i Razor Page kierują informacje.

Poniższy kod tworzy dzienniki i Warning je tworzyInformation:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

W poprzednim kodzie pierwszym Log{LOG LEVEL} parametremMyLogEvents.GetItem jest identyfikator zdarzenia dziennika. Drugi parametr to szablon komunikatu z symbolami zastępczymi dla wartości argumentów dostarczonych przez pozostałe parametry metody. Parametry metody zostały wyjaśnione w sekcji szablonu komunikatu w dalszej części tego dokumentu.

Wywołaj odpowiednią Log{LOG LEVEL} metodę, aby kontrolować ilość danych wyjściowych dziennika zapisywanych na określonym nośniku magazynu. Przykład:

  • W środowisku produkcyjnym:
    • Rejestrowanie na poziomach Trace lub Information generuje dużą ilość szczegółowych komunikatów dziennika. Aby kontrolować koszty i nie przekraczać limitów magazynowania danych, dzienników Trace i Information komunikatów na poziomie do magazynu danych o dużym koszcie. Rozważ ograniczenie Trace i Information określone kategorie.
    • Rejestrowanie na Warning poziomach Critical powinno spowodować wygenerowanie kilku komunikatów dziennika.
      • Koszty i limity magazynu zwykle nie są problemem.
      • Niewiele dzienników zapewnia większą elastyczność wyboru magazynu danych.
  • W rozwoju:
    • Ustaw wartość Warning.
    • Dodawanie Trace lub Information komunikaty podczas rozwiązywania problemów. Aby ograniczyć dane wyjściowe, ustaw Trace lub Information tylko dla kategorii objętych badaniem.

ASP.NET Core zapisuje dzienniki zdarzeń struktury. Rozważmy na przykład dane wyjściowe dziennika dla:

  • Aplikacja Pages utworzona Razor przy użyciu szablonów ASP.NET Core.
  • Ustawienie rejestrowania na wartość Logging:Console:LogLevel:Microsoft:Information.
  • Nawigacja Privacy do strony:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:5001/Privacy
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Privacy'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      Route matched with {page = "/Privacy"}. Executing page /Privacy
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]
      Executing handler method DefaultRP.Pages.PrivacyModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      Executed page /Privacy in 74.5188ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Privacy'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 149.3023ms 200 text/html; charset=utf-8

Następujące JSzestawy Logging:Console:LogLevel:Microsoft:InformationON:

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

Identyfikator zdarzenia dziennika

Każdy dziennik może określić identyfikator zdarzenia. Przykładowa aplikacja używa MyLogEvents klasy do definiowania identyfikatorów zdarzeń:

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Identyfikator zdarzenia kojarzy zestaw zdarzeń. Na przykład wszystkie dzienniki związane z wyświetlaniem listy elementów na stronie mogą mieć wartość 1001.

Dostawca rejestrowania może przechowywać identyfikator zdarzenia w polu identyfikatora, w komunikacie rejestrowania lub w ogóle nie. Dostawca debugowania nie wyświetla identyfikatorów zdarzeń. Dostawca konsoli wyświetla identyfikatory zdarzeń w nawiasach kwadratowych po kategorii:

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

Niektórzy dostawcy rejestrowania przechowują identyfikator zdarzenia w polu, co umożliwia filtrowanie identyfikatora.

Szablon komunikatu dziennika

Każdy interfejs API dziennika używa szablonu komunikatu. Szablon wiadomości może zawierać symbole zastępcze, dla których podano argumenty. Użyj nazw symboli zastępczych, a nie liczb.

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Kolejność parametrów, a nie ich nazwy zastępcze, określa, które parametry są używane do udostępniania wartości symboli zastępczych w komunikatach dziennika. W poniższym kodzie nazwy parametrów są poza sekwencyjne w symbolach zastępczych szablonu komunikatu:

string apples = 1;
string pears = 2;
string bananas = 3;

_logger.LogInformation("Parameters: {pears}, {bananas}, {apples}", apples, pears, bananas);

Parametry są jednak przypisywane do symboli zastępczych w kolejności: apples, , pearsbananas. Komunikat dziennika odzwierciedla kolejność parametrów:

Parameters: 1, 2, 3

Takie podejście umożliwia dostawcom rejestrowania zaimplementowanie semantycznego lub strukturalnego rejestrowania. Same argumenty są przekazywane do systemu rejestrowania, a nie tylko do sformatowanego szablonu komunikatu. Dzięki temu dostawcy rejestrowania mogą przechowywać wartości parametrów jako pola. Rozważmy na przykład następującą metodę rejestratora:

_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);

Na przykład podczas rejestrowania w usłudze Azure Table Storage:

  • Każda jednostka tabeli platformy Azure może mieć ID właściwości i RequestTime .
  • Tabele z właściwościami upraszczają zapytania dotyczące zarejestrowanych danych. Na przykład zapytanie może znaleźć wszystkie dzienniki w określonym RequestTime zakresie bez konieczności analizowania limitu czasu wiadomości SMS.

Rejestrowanie wyjątków

Metody rejestratora mają przeciążenia, które przyjmują parametr wyjątku:

[HttpGet("{id}")]
public IActionResult TestExp(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    try
    {
        if (id == 3)
        {
            throw new Exception("Test exception");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, ex, "TestExp({Id})", id);
        return NotFound();
    }

    return ControllerContext.MyDisplayRouteInfo();
}

Polecenia MyDisplayRouteInfo i ToCtxString są dostarczane przez pakiet NuGet Rick.Docs.Samples.RouteInfo . Metody wyświetlają Controller i Razor Page kierują informacje.

Rejestrowanie wyjątków jest specyficzne dla dostawcy.

Domyślny poziom dziennika

Jeśli domyślny poziom dziennika nie jest ustawiony, domyślną wartością poziomu dziennika jest Information.

Rozważmy na przykład następującą aplikację internetową:

  • Utworzono przy użyciu szablonów aplikacji internetowej ASP.NET.
  • appsettings.json i appsettings.Development.json zostały usunięte lub zmienione.

Po poprzedniej konfiguracji przejście do strony prywatności lub strony głównej powoduje wygenerowanie wielu Tracekomunikatów , Debugi Information w Microsoft nazwie kategorii.

Poniższy kod ustawia domyślny poziom dziennika, gdy domyślny poziom dziennika nie jest ustawiony w konfiguracji:

var builder = WebApplication.CreateBuilder();
builder.Logging.SetMinimumLevel(LogLevel.Warning);

Ogólnie rzecz biorąc, poziomy dziennika powinny być określone w konfiguracji, a nie w kodzie.

Funkcja Filter

Funkcja filtru jest wywoływana dla wszystkich dostawców i kategorii, które nie mają przypisanych do nich reguł przez konfigurację lub kod:

var builder = WebApplication.CreateBuilder();
builder.Logging.AddFilter((provider, category, logLevel) =>
{
    if (provider.Contains("ConsoleLoggerProvider")
        && category.Contains("Controller")
        && logLevel >= LogLevel.Information)
    {
        return true;
    }
    else if (provider.Contains("ConsoleLoggerProvider")
        && category.Contains("Microsoft")
        && logLevel >= LogLevel.Information)
    {
        return true;
    }
    else
    {
        return false;
    }
});

Powyższy kod wyświetla dzienniki konsoli, gdy kategoria zawiera Controller lub Microsoft i poziom dziennika jest Information lub wyższy.

Ogólnie rzecz biorąc, poziomy dziennika powinny być określone w konfiguracji, a nie w kodzie.

kategorie ASP.NET Core i EF Core

Poniższa tabela zawiera niektóre kategorie używane przez ASP.NET Core i Entity Framework Core z uwagami dotyczącymi dzienników:

Kategoria Uwagi
Microsoft.AspNetCore Ogólna diagnostyka ASP.NET Core.
Microsoft.AspNetCore.DataProtection Które klucze zostały uznane, znalezione i użyte.
Microsoft.AspNetCore.HostFiltering Dozwolone hosty.
Microsoft.AspNetCore.Hosting Czas ukończenia żądań HTTP i czas ich rozpoczęcia. Które zestawy uruchamiania zostały załadowane.
Microsoft.AspNetCore.Mvc MVC i Razor diagnostyka. Powiązanie modelu, wykonywanie filtru, kompilacja widoku, wybór akcji.
Microsoft.AspNetCore.Routing Informacje dotyczące dopasowywania tras.
Microsoft.AspNetCore.Server Nawiązywanie połączenia, zatrzymywanie i utrzymywanie aktywności odpowiedzi. Informacje o certyfikacie HTTPS.
Microsoft.AspNetCore.StaticFiles Pliki są obsługiwane.
Microsoft.EntityFrameworkCore Ogólna diagnostyka platformy Entity Framework Core. Aktywność i konfiguracja bazy danych, wykrywanie zmian, migracje.

Aby wyświetlić więcej kategorii w oknie konsoli, ustaw appsettings.Development.json następujące ustawienia:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Trace",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Zakresy dziennika

Zakres może grupować zestaw operacji logicznych. To grupowanie może służyć do dołączania tych samych danych do każdego dziennika utworzonego w ramach zestawu. Na przykład każdy dziennik utworzony w ramach przetwarzania transakcji może zawierać identyfikator transakcji.

Zakres:

Następujący dostawcy obsługują zakresy:

Użyj zakresu przez zawijanie wywołań rejestratora using w bloku:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;

    using (_logger.BeginScope("using block message"))
    {
        _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

        todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            _logger.LogWarning(MyLogEvents.GetItemNotFound, 
                "Get({Id}) NOT FOUND", id);
            return NotFound();
        }
    }

    return ItemToDTO(todoItem);
}

Wbudowani dostawcy rejestrowania

ASP.NET Core obejmuje następujących dostawców rejestrowania w ramach struktury udostępnionej:

Następujący dostawcy rejestrowania są dostarczani przez firmę Microsoft, ale nie jako część struktury udostępnionej. Muszą być zainstalowane jako dodatkowe pakiety nuget.

ASP.NET Core nie zawiera dostawcy rejestrowania do zapisywania dzienników w plikach. Aby zapisywać dzienniki w plikach z aplikacji ASP.NET Core, rozważ użycie dostawcy rejestrowania innej firmy.

Aby uzyskać informacje na stdout temat rejestrowania i debugowania przy użyciu modułu ASP.NET Core, zobacz Rozwiązywanie problemów z ASP.NET Core w usługach Azure App Service i IIS orazmodule ASP.NET Core (ANCM) dla usług IIS.

Konsola

Dostawca Console rejestruje dane wyjściowe w konsoli. Aby uzyskać więcej informacji na temat wyświetlania Console dzienników w programowania, zobacz Rejestrowanie danych wyjściowych z polecenia dotnet run i Visual Studio.

Debugowanie

Dostawca Debug zapisuje dane wyjściowe dziennika przy użyciu System.Diagnostics.Debug klasy . Wywołuje metodę zapisu System.Diagnostics.Debug.WriteLine do dostawcy Debug .

W systemie Linux Debug lokalizacja dziennika dostawcy jest zależna od dystrybucji i może być jedną z następujących wartości:

  • /var/log/message
  • /var/log/syslog

Źródło zdarzeń

EventSource Dostawca zapisuje dane w źródle zdarzeń dla wielu platform o nazwie Microsoft-Extensions-Logging. W systemie Windows dostawca używa funkcji ETW.

dotnet trace tooling (narzędzia do śledzenia dotnet)

To dotnet-trace narzędzie jest wieloplatformowym narzędziem globalnym interfejsu wiersza polecenia, które umożliwia zbieranie śladów platformy .NET Core uruchomionego procesu. Narzędzie zbiera dane dostawcy Microsoft.Extensions.Logging.EventSource przy użyciu elementu LoggingEventSource.

Aby uzyskać instrukcje dotyczące instalacji, zobacz dotnet-trace.

Użyj narzędzi, dotnet trace aby zebrać ślad z aplikacji:

  1. Uruchom aplikację za dotnet run pomocą polecenia .

  2. Określ identyfikator procesu (PID) aplikacji .NET Core:

    dotnet trace ps
    

    Znajdź identyfikator PID dla procesu, który ma taką samą nazwę jak zestaw aplikacji.

  3. dotnet trace Wykonaj polecenie .

    Ogólna składnia polecenia:

    dotnet trace collect -p {PID} 
        --providers Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"
    

    W przypadku korzystania z powłoki poleceń programu PowerShell należy ująć --providers wartość w apostrofy ('):

    dotnet trace collect -p {PID} 
        --providers 'Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"'
    

    Na platformach innych niż Windows dodaj -f speedscope opcję zmiany formatu pliku śledzenia danych wyjściowych na speedscope.

    W poniższej tabeli zdefiniowano słowo kluczowe:

    Słowo kluczowe Opis
    1 Rejestruj zdarzenia meta dotyczące elementu LoggingEventSource. Nie rejestruje zdarzeń z elementu ILogger.
    2 Message Włącza zdarzenie po ILogger.Log() wywołaniu. Dostarcza informacje w sposób programowy (nie sformatowany).
    4 FormatMessage Włącza zdarzenie po ILogger.Log() wywołaniu. Zawiera sformatowaną wersję ciągu informacji.
    8 MessageJson Włącza zdarzenie po ILogger.Log() wywołaniu. Zawiera reprezentację JSargumentów w funkcji ON.

    W poniższej tabeli wymieniono poziomy dostawcy:

    Poziom dostawcy Opis
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    Analizowanie poziomu kategorii może być ciągiem lub liczbą:

    Nazwana wartość kategorii Wartość liczbowa
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    Poziom dostawcy i poziom kategorii:

    • Są w odwrotnej kolejności.
    • Stałe ciągu nie są identyczne.

    Jeśli nie FilterSpecs zostanie określony, implementacja EventSourceLogger próbuje przekonwertować poziom dostawcy na poziom kategorii i stosuje go do wszystkich kategorii.

    Poziom dostawcy Poziom kategorii
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    Jeśli FilterSpecs zostanie podana, każda kategoria, która znajduje się na liście, używa tam zakodowanego poziomu kategorii, wszystkie inne kategorie są filtrowane.

    W poniższych przykładach przyjęto założenie:

    • Aplikacja jest uruchomiona i wywołuje funkcję logger.LogDebug("12345").
    • Identyfikator procesu (PID) został ustawiony za pośrednictwem set PID=12345elementu , gdzie 12345 jest rzeczywistym identyfikatorem PID.

    Spójrzmy na następujące polecenie:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    Powyższe polecenie ma następujące działanie:

    • Przechwytuje komunikaty debugowania.
    • Nie stosuje .FilterSpecs
    • Określa poziom 5, który mapuje kategorię Debug.

    Spójrzmy na następujące polecenie:

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    Powyższe polecenie ma następujące działanie:

    • Nie przechwytuje komunikatów debugowania, ponieważ poziom kategorii 5 to Critical.
    • Udostępnia element FilterSpecs.

    Następujące polecenie przechwytuje komunikaty debugowania, ponieważ poziom kategorii 1 określa Debugwartość .

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    Następujące polecenie przechwytuje komunikaty debugowania, ponieważ kategoria określa Debugwartość .

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    FilterSpecs wpisy dla {Logger Category} i {Category Level} reprezentują dodatkowe warunki filtrowania dzienników. Oddziel FilterSpecs wpisy znakiem ; średnika.

    Przykład użycia powłoki poleceń systemu Windows:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:2:FilterSpecs=\"Microsoft.AspNetCore.Hosting*:4\"
    

    Poprzednie polecenie aktywuje:

    • Rejestrator źródła zdarzeń do tworzenia sformatowanych ciągów (4) dla błędów (2).
    • Microsoft.AspNetCore.Hosting rejestrowanie na poziomie rejestrowania Informational (4).
  4. Zatrzymaj narzędzia śledzenia dotnet, naciskając klawisz Enter lub Ctrl+C.

    Ślad jest zapisywany z nazwą trace.nettrace w folderze, w którym dotnet trace jest wykonywane polecenie.

  5. Otwórz ślad za pomocą narzędzia Perfview. trace.nettrace Otwórz plik i zapoznaj się ze zdarzeniami śledzenia.

Jeśli aplikacja nie skompiluje hosta za pomocą WebApplication.CreateBuilderpolecenia , dodaj dostawcę źródła zdarzeń do konfiguracji rejestrowania aplikacji.

Aby uzyskać więcej informacji, zobacz:

Perfview

Użyj narzędzia PerfView , aby zbierać i wyświetlać dzienniki. Istnieją inne narzędzia do wyświetlania dzienników ETW, ale narzędzie PerfView zapewnia najlepsze środowisko pracy ze zdarzeniami ETW emitowanych przez ASP.NET Core.

Aby skonfigurować element PerfView do zbierania zdarzeń rejestrowanych przez tego dostawcę, dodaj ciąg *Microsoft-Extensions-Logging do listy Dodatkowych dostawców . Nie przegap wartości * na początku ciągu.

Dziennik zdarzeń systemu Windows

Dostawca EventLog wysyła dane wyjściowe dziennika do dziennika zdarzeń systemu Windows. W przeciwieństwie do innych dostawców EventLog dostawca nie dziedziczy domyślnych ustawień innych niż dostawcy. Jeśli EventLog ustawienia dziennika nie są określone, domyślnie mają wartość LogLevel.Warning.

Aby rejestrować zdarzenia niższe niż LogLevel.Warning, jawnie ustaw poziom dziennika. W poniższym przykładzie ustawiono domyślny poziom dziennika zdarzeń na LogLevel.Information:

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

AddEventLog przeciążenia mogą przechodzić w elemecie EventLogSettings. W przypadku null określenia lub nie są używane następujące ustawienia domyślne:

  • LogName: "Aplikacja"
  • SourceName: .NET Runtime"
  • MachineName: używana jest nazwa komputera lokalnego.

Poniższy kod zmienia SourceName wartość z wartości domyślnej ".NET Runtime" na MyLogs:


var builder = WebApplication.CreateBuilder();
builder.Logging.AddEventLog(eventLogSettings =>
{
    eventLogSettings.SourceName = "MyLogs";
});

Azure App Service

Pakiet Microsoft.Extensions.Logging.AzureAppServices dostawcy zapisuje dzienniki w plikach tekstowych w systemie plików aplikacji Azure App Service i w magazynie obiektów blob na koncie usługi Azure Storage.

Pakiet dostawcy nie jest uwzględniony w strukturze udostępnionej. Aby użyć dostawcy, dodaj pakiet dostawcy do projektu.

Aby skonfigurować ustawienia dostawcy, użyj elementów AzureFileLoggerOptions i AzureBlobLoggerOptions, jak pokazano w poniższym przykładzie:

using Microsoft.Extensions.Logging.AzureAppServices;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddAzureWebAppDiagnostics();
builder.Services.Configure<AzureFileLoggerOptions>(options =>
{
    options.FileName = "azure-diagnostics-";
    options.FileSizeLimit = 50 * 1024;
    options.RetainedFileCountLimit = 5;
});
builder.Services.Configure<AzureBlobLoggerOptions>(options =>
{
    options.BlobName = "log.txt";
});

Po wdrożeniu w Azure App Service aplikacja używa ustawień w sekcji dzienników App Service strony App Service Azure Portal. Po zaktualizowaniu następujących ustawień zmiany zostaną zastosowane natychmiast bez konieczności ponownego uruchamiania lub ponownego wdrażania aplikacji.

  • Rejestrowanie aplikacji (system plików)
  • Rejestrowanie aplikacji (obiekt blob)

Domyślna lokalizacja plików dziennika znajduje się w folderze D:\\home\\LogFiles\\Application , a domyślna nazwa pliku to diagnostics-yyyymmdd.txt. Domyślny limit rozmiaru pliku wynosi 10 MB, a domyślna maksymalna liczba zachowywanych plików to 2. Domyślna nazwa obiektu blob to {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt.

Ten dostawca rejestruje tylko wtedy, gdy projekt działa w środowisku platformy Azure.

Przesyłanie strumieniowe dzienników platformy Azure

Przesyłanie strumieniowe dzienników platformy Azure obsługuje wyświetlanie aktywności dziennika w czasie rzeczywistym z:

  • Serwer aplikacji
  • Serwer internetowy
  • Śledzenie żądań, które zakończyło się niepowodzeniem

Aby skonfigurować przesyłanie strumieniowe dzienników platformy Azure:

  • Przejdź do strony dzienników App Service na stronie portalu aplikacji.
  • Ustaw opcję Rejestrowanie aplikacji (system plików) na .
  • Wybierz poziom dziennika. To ustawienie dotyczy tylko przesyłania strumieniowego dzienników platformy Azure.

Przejdź do strony Strumienia dzienników , aby wyświetlić dzienniki. Zarejestrowane komunikaty są rejestrowane za pomocą interfejsu ILogger .

Azure Application Insights

Pakiet Microsoft.Extensions.Logging.ApplicationInsights dostawcy zapisuje dzienniki w usłudze aplikacja systemu Azure Insights. Application Insights to usługa, która monitoruje aplikację internetową i udostępnia narzędzia do wykonywania zapytań i analizowania danych telemetrycznych. Jeśli używasz tego dostawcy, możesz wykonywać zapytania i analizować dzienniki przy użyciu narzędzi usługi Application Insights.

Dostawca rejestrowania jest dołączany jako zależność Microsoft.ApplicationInsights.AspNetCoreelementu , czyli pakiet, który zapewnia wszystkie dostępne dane telemetryczne dla ASP.NET Core. Jeśli używasz tego pakietu, nie musisz instalować pakietu dostawcy.

Pakiet Microsoft.ApplicationInsights.Web jest przeznaczony dla ASP.NET 4.x, a nie ASP.NET Core.

Więcej informacji można znaleźć w następujących zasobach:

Zewnętrzni dostawcy rejestrowania

Struktury rejestrowania innych firm, które współpracują z ASP.NET Core:

Niektóre struktury innych firm mogą wykonywać rejestrowanie semantyczne, znane również jako rejestrowanie strukturalne.

Korzystanie z platformy innej firmy jest podobne do korzystania z jednego z wbudowanych dostawców:

  1. Dodaj pakiet NuGet do projektu.
  2. Wywołaj metodę rozszerzenia dostarczaną ILoggerFactory przez strukturę rejestrowania.

Aby uzyskać więcej informacji, zobacz dokumentację każdego dostawcy. Zewnętrzni dostawcy rejestrowania nie są obsługiwani przez firmę Microsoft.

Brak metod asynchronicznego rejestratora

Rejestrowanie powinno być tak szybkie, że nie jest warte kosztu wydajności kodu asynchronicznego. Jeśli magazyn danych rejestrowania działa wolno, nie zapisuj go bezpośrednio. Rozważ zapisanie komunikatów dziennika w szybkim magazynie początkowo, a następnie przeniesienie ich do powolnego magazynu później. Na przykład podczas rejestrowania w SQL Server nie rób tego bezpośrednio w metodzieLog, ponieważ Log metody są synchroniczne. Zamiast tego synchronicznie dodaj komunikaty dziennika do kolejki w pamięci i ma proces roboczy w tle ściągnąć komunikaty z kolejki, aby wykonać asynchroniczną pracę wypychania danych do SQL Server. Aby uzyskać więcej informacji, zobacz Wskazówki dotyczące rejestrowania się w kolejce komunikatów dla powolnych magazynów danych (dotnet/AspNetCore.Docs #11801).

Zmienianie poziomów dziennika w uruchomionej aplikacji

Interfejs API rejestrowania nie zawiera scenariusza zmiany poziomów dziennika podczas działania aplikacji. Jednak niektórzy dostawcy konfiguracji mogą ponownie ładować konfigurację, która ma natychmiastowy wpływ na konfigurację rejestrowania. Na przykład dostawca konfiguracji plików domyślnie ponownie ładuje konfigurację rejestrowania. Jeśli konfiguracja zostanie zmieniona w kodzie podczas działania aplikacji, aplikacja może wywołać IConfigurationRoot.Reload metodę w celu zaktualizowania konfiguracji rejestrowania aplikacji.

ILogger i ILoggerFactory

Interfejsy ILogger<TCategoryName> i ILoggerFactory i implementacje są uwzględniane w zestawie SDK platformy .NET Core. Są one również dostępne w następujących pakietach NuGet:

Stosowanie reguł filtru dziennika w kodzie

Preferowane podejście do ustawiania reguł filtrowania dzienników odbywa się przy użyciu konfiguracji.

W poniższym przykładzie pokazano, jak zarejestrować reguły filtrowania w kodzie:

using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Logging.Debug;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddFilter("System", LogLevel.Debug);
builder.Logging.AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information);
builder.Logging.AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace);

logging.AddFilter("System", LogLevel.Debug) określa kategorię System i poziom Debugdziennika . Filtr jest stosowany do wszystkich dostawców, ponieważ nie skonfigurowano określonego dostawcy.

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) Określa:

  • Dostawca rejestrowania Debug .
  • Poziom Information dziennika i wyższy.
  • Wszystkie kategorie rozpoczynające się od "Microsoft".

Automatycznie rejestruj zakres za pomocą SpanId, , TraceIdParentId, Baggagei Tags.

Biblioteki rejestrowania niejawnie tworzą obiekt zakresu z elementami SpanId, TraceId, ParentIdBaggagei Tags. To zachowanie jest konfigurowane za pomocą polecenia ActivityTrackingOptions.

  var loggerFactory = LoggerFactory.Create(logging =>
  {
      logging.Configure(options =>
      {
          options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                              | ActivityTrackingOptions.TraceId
                                              | ActivityTrackingOptions.ParentId
                                              | ActivityTrackingOptions.Baggage
                                              | ActivityTrackingOptions.Tags;
      }).AddSimpleConsole(options =>
      {
          options.IncludeScopes = true;
      });
  });

traceparent Jeśli nagłówek żądania HTTP jest ustawiony, ParentId zakres w dzienniku pokazuje W3C parent-id z nagłówka powiązanegotraceparent, a SpanId w zakresie dziennika jest wyświetlany zaktualizowany parent-id dla następnego kroku/zakresu powiązanego. Aby uzyskać więcej informacji, zobacz Mutating the traceparent Field (Mutowanie pola śledzenia).

Tworzenie niestandardowego rejestratora

Aby utworzyć niestandardowy rejestrator, zobacz Implementowanie niestandardowego dostawcy rejestrowania na platformie .NET.

Dodatkowe zasoby

Kirk Larkin, Juergen Gutsch i Rick Anderson

W tym temacie opisano rejestrowanie na platformie .NET, ponieważ dotyczy to aplikacji ASP.NET Core. Aby uzyskać szczegółowe informacje na temat rejestrowania na platformie .NET, zobacz Rejestrowanie na platformie .NET. Aby uzyskać więcej informacji na temat rejestrowania w Blazor aplikacjach, zobacz ASP.NET Core Blazor rejestrowania.

Wyświetl lub pobierz przykładowy kod (jak pobrać).

Dostawcy rejestrowania

Dostawcy rejestrowania przechowują Console dzienniki z wyjątkiem dostawcy, który wyświetla dzienniki. Na przykład dostawca aplikacja systemu Azure Insights przechowuje dzienniki w usłudze aplikacja systemu Azure Insights. Można włączyć wielu dostawców.

Domyślne szablony aplikacji internetowej ASP.NET Core:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Powyższy kod przedstawia klasę Program utworzoną przy użyciu szablonów aplikacji internetowej ASP.NET Core. W następnych kilku sekcjach przedstawiono przykłady oparte na szablonach aplikacji internetowej ASP.NET Core, które korzystają z hosta ogólnego. Aplikacje konsolowe nienależące do hosta zostały omówione w dalszej części tego dokumentu.

Aby zastąpić domyślny zestaw dostawców rejestrowania dodany przez Host.CreateDefaultBuilderusługę , wywołaj ClearProviders i dodaj wymaganych dostawców rejestrowania. Na przykład następujący kod:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Aby uzyskać dodatkowych dostawców, zobacz:

Tworzenie dzienników

Aby utworzyć dzienniki, użyj ILogger<TCategoryName> obiektu z iniekcji zależności (DI).

Poniższy przykład:

  • Tworzy rejestrator , ILogger<AboutModel>który używa kategorii dziennika w pełni kwalifikowanej nazwy typu AboutModel. Kategoria dziennika jest ciągiem skojarzonym z każdym dziennikiem.
  • Wywołania LogInformation do rejestrowania Information na poziomie. Poziom dziennika wskazuje ważność zarejestrowanego zdarzenia.
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }
    public string Message { get; set; }

    public void OnGet()
    {
        Message = $"About page visited at {DateTime.UtcNow.ToLongTimeString()}";
        _logger.LogInformation(Message);
    }
}

Poziomy i kategorie zostały szczegółowo wyjaśnione w dalszej części tego dokumentu.

Aby uzyskać informacje na Blazortemat programu , zobacz rejestrowanie ASP.NET CoreBlazor.

Tworzenie dzienników w obszarze Main (Główne) i Startup (Uruchamianie ) pokazuje, jak tworzyć dzienniki w Main plikach i Startup.

Konfigurowanie rejestrowania

Konfiguracja rejestrowania jest często udostępniana przez sekcję Loggingappsettings.{Environment}.json plików. Następujący appsettings.Development.json plik jest generowany przez szablony aplikacji internetowej ASP.NET Core:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

W poprzedniej sekcji JSWŁĄCZONE:

  • "Default"Określono kategorie , "Microsoft"i "Microsoft.Hosting.Lifetime" .
  • Kategoria "Microsoft" ma zastosowanie do wszystkich kategorii rozpoczynających się od "Microsoft". Na przykład to ustawienie dotyczy "Microsoft.AspNetCore.Routing.EndpointMiddleware" kategorii.
  • Kategoria "Microsoft" rejestruje się na poziomie Warning dziennika i wyższym.
  • Kategoria jest bardziej specyficzna "Microsoft.Hosting.Lifetime" niż "Microsoft" kategoria, więc "Microsoft.Hosting.Lifetime" dzienniki kategorii na poziomie dziennika "Informacje" i wyższe.
  • Nie określono określonego dostawcy dziennika, dlatego LogLevel dotyczy wszystkich dostawców rejestrowania z włączoną obsługą z wyjątkiem dziennika zdarzeń systemu Windows.

Właściwość Logging może mieć LogLevel właściwości dostawcy dziennika i . Parametr LogLevel określa minimalny poziom rejestrowania dla wybranych kategorii. W poprzednich poziomach JSWŁ Information . i Warning rejestrowania są określone. LogLevel wskazuje ważność dziennika i zakresy od 0 do 6:

Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5 i None = 6.

Po określeniu LogLevel elementu rejestrowanie jest włączone dla komunikatów na określonym poziomie i wyższym. W poprzedniej JSsekcji WŁ. kategoria jest rejestrowana Default dla Information i wyższa. Na przykład rejestrowane Informationsą komunikaty , Warning, Errori Critical . Jeśli nie LogLevel zostanie określony, ustawienie domyślne rejestrowania zostanie ustawione na Information poziomie . Aby uzyskać więcej informacji, zobacz Poziomy dziennika.

Właściwość dostawcy może określać LogLevel właściwość. LogLevel w obszarze dostawcy określa poziomy rejestrowania dla tego dostawcy i zastępuje ustawienia dziennika bez dostawcy. Rozważ następujący appsettings.json plik:

{
  "Logging": {
    "LogLevel": { // All providers, LogLevel applies to all the enabled providers.
      "Default": "Error", // Default logging, Error and higher.
      "Microsoft": "Warning" // All Microsoft* categories, Warning and higher.
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information", // Overrides preceding LogLevel:Default setting.
        "Microsoft.Hosting": "Trace" // Debug:Microsoft.Hosting category.
      }
    },
    "EventSource": { // EventSource provider
      "LogLevel": {
        "Default": "Warning" // All categories of EventSource provider.
      }
    }
  }
}

Ustawienia w Logging.{providername}.LogLevel zastąpić ustawienia w pliku Logging.LogLevel. W poprzednim włDebug. JSdomyślny poziom dziennika dostawcy jest ustawiony na Information:

Logging:Debug:LogLevel:Default:Information

Poprzednie ustawienie określa Information poziom dziennika dla każdej Logging:Debug: kategorii z wyjątkiem Microsoft.Hosting. Gdy zostanie wyświetlona określona kategoria, określona kategoria zastępuje kategorię domyślną. W poprzedniej sekcji JSWŁ Logging:Debug:LogLevel . kategorie "Microsoft.Hosting" i "Default" przesłaniają ustawienia w Logging:LogLevel

Minimalny poziom dziennika można określić dla dowolnego z następujących elementów:

  • Konkretni dostawcy: na przykład Logging:EventSource:LogLevel:Default:Information
  • Określone kategorie: na przykład: Logging:LogLevel:Microsoft:Warning
  • Wszyscy dostawcy i wszystkie kategorie: Logging:LogLevel:Default:Warning

Wszystkie dzienniki poniżej minimalnego poziomu nie są następujące:

  • Przekazano do dostawcy.
  • Zarejestrowane lub wyświetlane.

Aby pominąć wszystkie dzienniki, określ wartość LogLevel.None. LogLevel.None ma wartość 6, która jest wyższa niż LogLevel.Critical (5).

Jeśli dostawca obsługuje zakresy dzienników, wskazuje, IncludeScopes czy są one włączone. Aby uzyskać więcej informacji, zobacz zakresy dzienników

appsettings.json Poniższy plik zawiera wszystkich dostawców, którzy są domyślnie włączeni:

{
  "Logging": {
    "LogLevel": { // No provider, LogLevel applies to all the enabled providers.
      "Default": "Error",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information" // Overrides preceding LogLevel:Default setting.
      }
    },
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "Default": "Information"
      }
    },
    "EventSource": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "EventLog": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "AzureAppServicesFile": {
      "IncludeScopes": true,
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "AzureAppServicesBlob": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "ApplicationInsights": {
      "LogLevel": {
        "Default": "Information"
      }
    }
  }
}

W poprzednim przykładzie:

  • Kategorie i poziomy nie są sugerowane wartości. Przykład jest udostępniany w celu wyświetlenia wszystkich dostawców domyślnych.
  • Ustawienia w Logging.{providername}.LogLevel zastąpić ustawienia w pliku Logging.LogLevel. Na przykład poziom w Debug.LogLevel.Default poleceniu zastępuje poziom w LogLevel.Defaultpliku .
  • Każdy domyślny alias dostawcy jest używany. Każdy dostawca definiuje alias , który może być używany w konfiguracji zamiast w pełni kwalifikowanej nazwy typu. Wbudowane aliasy dostawców to:
    • Konsola
    • Debugowanie
    • EventSource
    • Eventlog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

Ustawianie poziomu dziennika według wiersza polecenia, zmiennych środowiskowych i inną konfigurację

Poziom dziennika można ustawić przez dowolnego dostawcę konfiguracji.

Separator : nie działa z kluczami hierarchicznymi zmiennych środowiskowych na wszystkich platformach. __, podwójne podkreślenie, to:

  • Obsługiwane przez wszystkie platformy. Na przykład separator nie jest obsługiwany przez powłokę :Bash, ale __ jest.
  • Automatycznie zastąpione przez :

Następujące polecenia:

  • Ustaw klucz Logging:LogLevel:Microsoft środowiska na wartość Information w systemie Windows.
  • Przetestuj ustawienia podczas korzystania z aplikacji utworzonej przy użyciu szablonów aplikacji internetowych ASP.NET Core. Polecenie dotnet run musi zostać uruchomione w katalogu projektu po użyciu polecenia set.
set Logging__LogLevel__Microsoft=Information
dotnet run

Poprzednie ustawienie środowiska:

  • Jest ustawiana tylko w procesach uruchamianych z okna poleceń, w których zostały ustawione.
  • Nie jest odczytywany przez przeglądarki uruchamiane za pomocą programu Visual Studio.

Następujące polecenie setx ustawia również klucz środowiska i wartość w systemie Windows. W przeciwieństwie do setelementu setx ustawienia są utrwalane. Przełącznik /M ustawia zmienną w środowisku systemowym. Jeśli /M nie jest używana, zostanie ustawiona zmienna środowiskowa użytkownika.

setx Logging__LogLevel__Microsoft Information /M

Rozważ następujący appsettings.json plik:

"Logging": {
    "Console": {
      "LogLevel": {
        "Microsoft.Hosting.Lifetime": "Trace"
      }
    }
}

Następujące polecenie ustawia poprzednią konfigurację w środowisku:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

Na Azure App Service wybierz pozycję Nowe ustawienie aplikacji na stronie Konfiguracja ustawień>. Azure App Service ustawienia aplikacji są następujące:

  • Szyfrowane w spoczynku i przesyłane za pośrednictwem zaszyfrowanego kanału.
  • Uwidocznione jako zmienne środowiskowe.

Aby uzyskać więcej informacji, zobacz Azure Apps: Zastępowanie konfiguracji aplikacji przy użyciu witryny Azure Portal.

Aby uzyskać więcej informacji na temat ustawiania wartości konfiguracji ASP.NET Core przy użyciu zmiennych środowiskowych, zobacz zmienne środowiskowe. Aby uzyskać informacje na temat korzystania z innych źródeł konfiguracji, w tym wiersza polecenia, usługi Azure Key Vault, Azure App Configuration, innych formatów plików i nie tylko, zobacz Konfiguracja w ASP.NET Core.

Jak są stosowane reguły filtrowania

Po utworzeniu ILogger<TCategoryName> obiektu obiekt wybiera jedną regułę dla każdego dostawcy, ILoggerFactory która ma być stosowana do tego rejestratora. Wszystkie komunikaty zapisywane przez ILogger wystąpienie są filtrowane na podstawie wybranych reguł. Najbardziej konkretna reguła dla każdego dostawcy i pary kategorii jest wybierana z dostępnych reguł.

Następujący algorytm jest używany dla każdego dostawcy podczas ILogger tworzenia elementu dla danej kategorii:

  • Wybierz wszystkie reguły zgodne z dostawcą lub jego aliasem. Jeśli nie zostanie znalezione dopasowanie, wybierz wszystkie reguły z pustym dostawcą.
  • W wyniku poprzedniego kroku wybierz reguły z najdłuższym pasującym prefiksem kategorii. Jeśli nie zostanie znalezione dopasowanie, wybierz wszystkie reguły, które nie określają kategorii.
  • Jeśli wybrano wiele reguł, weź ostatni .
  • Jeśli nie wybrano żadnych reguł, użyj polecenia MinimumLevel.

Rejestrowanie danych wyjściowych z polecenia dotnet run i programu Visual Studio

Zostaną wyświetlone dzienniki utworzone przy użyciu domyślnych dostawców rejestrowania :

  • W programie Visual Studio
    • W oknie Debugowanie danych wyjściowych podczas debugowania.
    • W oknie ASP.NET Core Serwera sieci Web.
  • W oknie konsoli po uruchomieniu aplikacji za pomocą dotnet runpolecenia .

Dzienniki rozpoczynające się od kategorii "Microsoft" pochodzą z kodu platformy ASP.NET Core. ASP.NET Core i kod aplikacji używają tego samego interfejsu API rejestrowania i dostawców.

Kategoria dziennika

Po utworzeniu ILogger obiektu zostanie określona kategoria . Ta kategoria jest dołączona do każdego komunikatu dziennika utworzonego przez to wystąpienie klasy ILogger. Ciąg kategorii jest dowolny, ale konwencja polega na użyciu nazwy klasy. Na przykład w kontrolerze nazwą może być "TodoApi.Controllers.TodoController". Aplikacje internetowe ASP.NET Core automatycznie ILogger<T> pobierają ILogger wystąpienie, które używa w pełni kwalifikowanej T nazwy typu jako kategorii:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

Aby jawnie określić kategorię, wywołaj metodę ILoggerFactory.CreateLogger:

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }

Wywoływanie CreateLogger przy użyciu stałej nazwy może być przydatne w przypadku użycia w wielu metodach, dzięki czemu zdarzenia mogą być zorganizowane według kategorii.

ILogger<T> jest odpowiednikiem wywołania CreateLogger z w pełni kwalifikowaną nazwą Ttypu .

Poziom dziennika

W poniższej tabeli wymieniono LogLevel wartości, metodę rozszerzenia wygody Log{LogLevel} i sugerowane użycie:

LogLevel Wartość Metoda Opis
Ślad 0 LogTrace Zawiera najbardziej szczegółowe komunikaty. Te komunikaty mogą zawierać poufne dane aplikacji. Te komunikaty są domyślnie wyłączone i nie powinny być włączone w środowisku produkcyjnym.
Debugowania 1 LogDebug Do debugowania i programowania. Należy zachować ostrożność w środowisku produkcyjnym ze względu na dużą ilość.
Informacje 2 LogInformation Śledzi ogólny przepływ aplikacji. Może mieć wartość długoterminową.
Ostrzeżenie 3 LogWarning W przypadku nietypowych lub nieoczekiwanych zdarzeń. Zazwyczaj obejmuje błędy lub warunki, które nie powodują niepowodzenia aplikacji.
Błąd 4 LogError W przypadku błędów i wyjątków, których nie można obsłużyć. Te komunikaty wskazują błąd w bieżącej operacji lub żądaniu, a nie awarii dla całej aplikacji.
Krytyczne 5 LogCritical W przypadku awarii wymagających natychmiastowej uwagi. Przykłady: scenariusze utraty danych, brak miejsca na dysku.
Brak 6 Określa, że kategoria rejestrowania nie powinna zapisywać żadnych komunikatów.

W poprzedniej tabeli LogLevel element jest wymieniony z najniższej do najwyższej ważności.

Pierwszy parametr LogLevelmetody Log wskazuje ważność dziennika. Zamiast wywoływać Log(LogLevel, ...)metodę rozszerzenia Log{LogLevel}, większość deweloperów wywołuje metody rozszerzenia Log{LogLevel} . Metody Log{LogLevel} rozszerzenia wywołają metodę Log i określ wartość LogLevel. Na przykład następujące dwa wywołania rejestrowania są funkcjonalnie równoważne i tworzą ten sam dziennik:

[HttpGet]
public IActionResult Test1(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);

    _logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    return ControllerContext.MyDisplayRouteInfo();
}

MyLogEvents.TestItem to identyfikator zdarzenia. MyLogEvents jest częścią przykładowej aplikacji i jest wyświetlana w sekcji Identyfikator zdarzenia dziennika .

Polecenia MyDisplayRouteInfo i ToCtxString są dostarczane przez pakiet NuGet Rick.Docs.Samples.RouteInfo . Metody wyświetlają Controller i Razor Page kierują informacje.

Poniższy kod tworzy dzienniki i Warning je tworzyInformation:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

W poprzednim kodzie pierwszym Log{LogLevel} parametremMyLogEvents.GetItem jest identyfikator zdarzenia dziennika. Drugi parametr to szablon komunikatu z symbolami zastępczymi dla wartości argumentów dostarczonych przez pozostałe parametry metody. Parametry metody zostały wyjaśnione w sekcji szablonu komunikatu w dalszej części tego dokumentu.

Wywołaj odpowiednią Log{LogLevel} metodę, aby kontrolować ilość danych wyjściowych dziennika zapisywanych na określonym nośniku magazynu. Przykład:

  • W środowisku produkcyjnym:
    • Rejestrowanie na poziomach Trace lub Information generuje dużą ilość szczegółowych komunikatów dziennika. Aby kontrolować koszty i nie przekraczać limitów magazynowania danych, dzienników Trace i Information komunikatów na poziomie do magazynu danych o dużym koszcie. Rozważ ograniczenie Trace i Information określone kategorie.
    • Rejestrowanie na Warning poziomach Critical powinno spowodować wygenerowanie kilku komunikatów dziennika.
      • Koszty i limity magazynu zwykle nie są problemem.
      • Niewiele dzienników zapewnia większą elastyczność wyboru magazynu danych.
  • W rozwoju:
    • Ustaw wartość Warning.
    • Dodawanie Trace lub Information komunikaty podczas rozwiązywania problemów. Aby ograniczyć dane wyjściowe, ustaw Trace lub Information tylko dla kategorii objętych badaniem.

ASP.NET Core zapisuje dzienniki zdarzeń struktury. Rozważmy na przykład dane wyjściowe dziennika dla:

  • Aplikacja Pages utworzona Razor przy użyciu szablonów ASP.NET Core.
  • Ustawienie rejestrowania na wartość Logging:Console:LogLevel:Microsoft:Information
  • Nawigacja Privacy do strony:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:5001/Privacy
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Privacy'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      Route matched with {page = "/Privacy"}. Executing page /Privacy
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]
      Executing handler method DefaultRP.Pages.PrivacyModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      Executed page /Privacy in 74.5188ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Privacy'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 149.3023ms 200 text/html; charset=utf-8

Następujące JSzestawy Logging:Console:LogLevel:Microsoft:InformationON:

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

Identyfikator zdarzenia dziennika

Każdy dziennik może określić identyfikator zdarzenia. Przykładowa aplikacja używa MyLogEvents klasy do definiowania identyfikatorów zdarzeń:

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Identyfikator zdarzenia kojarzy zestaw zdarzeń. Na przykład wszystkie dzienniki związane z wyświetlaniem listy elementów na stronie mogą mieć wartość 1001.

Dostawca rejestrowania może przechowywać identyfikator zdarzenia w polu identyfikatora, w komunikacie rejestrowania lub w ogóle nie. Dostawca debugowania nie wyświetla identyfikatorów zdarzeń. Dostawca konsoli wyświetla identyfikatory zdarzeń w nawiasach kwadratowych po kategorii:

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

Niektórzy dostawcy rejestrowania przechowują identyfikator zdarzenia w polu, co umożliwia filtrowanie identyfikatora.

Szablon komunikatu dziennika

Każdy interfejs API dziennika używa szablonu komunikatu. Szablon wiadomości może zawierać symbole zastępcze, dla których podano argumenty. Użyj nazw symboli zastępczych, a nie liczb.

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Kolejność parametrów, a nie ich nazwy zastępcze, określa, które parametry są używane do udostępniania wartości symboli zastępczych w komunikatach dziennika. W poniższym kodzie nazwy parametrów są poza sekwencyjne w symbolach zastępczych szablonu komunikatu:

string apples = 1;
string pears = 2;
string bananas = 3;

_logger.LogInformation("Parameters: {pears}, {bananas}, {apples}", apples, pears, bananas);

Parametry są jednak przypisywane do symboli zastępczych w kolejności: apples, , pearsbananas. Komunikat dziennika odzwierciedla kolejność parametrów:

Parameters: 1, 2, 3

Takie podejście umożliwia dostawcom rejestrowania zaimplementowanie semantycznego lub strukturalnego rejestrowania. Same argumenty są przekazywane do systemu rejestrowania, a nie tylko do sformatowanego szablonu komunikatu. Dzięki temu dostawcy rejestrowania mogą przechowywać wartości parametrów jako pola. Rozważmy na przykład następującą metodę rejestratora:

_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);

Na przykład podczas rejestrowania w usłudze Azure Table Storage:

  • Każda jednostka tabeli platformy Azure może mieć ID właściwości i RequestTime .
  • Tabele z właściwościami upraszczają zapytania dotyczące zarejestrowanych danych. Na przykład zapytanie może znaleźć wszystkie dzienniki w określonym RequestTime zakresie bez konieczności analizowania limitu czasu wiadomości SMS.

Rejestrowanie wyjątków

Metody rejestratora mają przeciążenia, które przyjmują parametr wyjątku:

[HttpGet("{id}")]
public IActionResult TestExp(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    try
    {
        if (id == 3)
        {
            throw new Exception("Test exception");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, ex, "TestExp({Id})", id);
        return NotFound();
    }

    return ControllerContext.MyDisplayRouteInfo();
}

Polecenia MyDisplayRouteInfo i ToCtxString są dostarczane przez pakiet NuGet Rick.Docs.Samples.RouteInfo . Metody wyświetlają Controller i Razor Page kierują informacje.

Rejestrowanie wyjątków jest specyficzne dla dostawcy.

Domyślny poziom dziennika

Jeśli domyślny poziom dziennika nie jest ustawiony, domyślną wartością poziomu dziennika jest Information.

Rozważmy na przykład następującą aplikację internetową:

  • Utworzono przy użyciu szablonów aplikacji internetowej ASP.NET.
  • appsettings.json i appsettings.Development.json zostały usunięte lub zmienione.

Po poprzedniej konfiguracji przejście do strony prywatności lub strony głównej powoduje wygenerowanie wielu Tracekomunikatów , Debugi Information w Microsoft nazwie kategorii.

Poniższy kod ustawia domyślny poziom dziennika, gdy domyślny poziom dziennika nie jest ustawiony w konfiguracji:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Warning))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Ogólnie rzecz biorąc, poziomy dziennika powinny być określone w konfiguracji, a nie w kodzie.

Funkcja Filter

Funkcja filtru jest wywoływana dla wszystkich dostawców i kategorii, które nie mają przypisanych do nich reguł przez konfigurację lub kod:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddFilter((provider, category, logLevel) =>
                {
                    if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Controller")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Microsoft")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Powyższy kod wyświetla dzienniki konsoli, gdy kategoria zawiera Controller lub Microsoft i poziom dziennika jest Information lub wyższy.

Ogólnie rzecz biorąc, poziomy dziennika powinny być określone w konfiguracji, a nie w kodzie.

kategorie ASP.NET Core i EF Core

Poniższa tabela zawiera niektóre kategorie używane przez ASP.NET Core i Entity Framework Core z uwagami dotyczącymi dzienników:

Kategoria Uwagi
Microsoft.AspNetCore Ogólna diagnostyka ASP.NET Core.
Microsoft.AspNetCore.DataProtection Które klucze zostały uznane, znalezione i użyte.
Microsoft.AspNetCore.HostFiltering Dozwolone hosty.
Microsoft.AspNetCore.Hosting Czas ukończenia żądań HTTP i czas ich rozpoczęcia. Które zestawy uruchamiania zostały załadowane.
Microsoft.AspNetCore.Mvc MVC i Razor diagnostyka. Powiązanie modelu, wykonywanie filtru, kompilacja widoku, wybór akcji.
Microsoft.AspNetCore.Routing Informacje dotyczące dopasowywania tras.
Microsoft.AspNetCore.Server Nawiązywanie połączenia, zatrzymywanie i utrzymywanie aktywności odpowiedzi. Informacje o certyfikacie HTTPS.
Microsoft.AspNetCore.StaticFiles Pliki są obsługiwane.
Microsoft.EntityFrameworkCore Ogólna diagnostyka platformy Entity Framework Core. Aktywność i konfiguracja bazy danych, wykrywanie zmian, migracje.

Aby wyświetlić więcej kategorii w oknie konsoli, ustaw appsettings.Development.json następujące ustawienia:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Trace",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Zakresy dziennika

Zakres może grupować zestaw operacji logicznych. To grupowanie może służyć do dołączania tych samych danych do każdego dziennika utworzonego w ramach zestawu. Na przykład każdy dziennik utworzony w ramach przetwarzania transakcji może zawierać identyfikator transakcji.

Zakres:

Następujący dostawcy obsługują zakresy:

Użyj zakresu przez zawijanie wywołań rejestratora using w bloku:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;

    using (_logger.BeginScope("using block message"))
    {
        _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

        todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            _logger.LogWarning(MyLogEvents.GetItemNotFound, 
                "Get({Id}) NOT FOUND", id);
            return NotFound();
        }
    }

    return ItemToDTO(todoItem);
}

Wbudowani dostawcy rejestrowania

ASP.NET Core obejmuje następujących dostawców rejestrowania w ramach struktury udostępnionej:

Następujący dostawcy rejestrowania są dostarczani przez firmę Microsoft, ale nie jako część struktury udostępnionej. Muszą być zainstalowane jako dodatkowe pakiety nuget.

ASP.NET Core nie zawiera dostawcy rejestrowania do zapisywania dzienników w plikach. Aby zapisywać dzienniki w plikach z aplikacji ASP.NET Core, rozważ użycie dostawcy rejestrowania innej firmy.

Aby uzyskać informacje na stdout temat rejestrowania i debugowania przy użyciu modułu ASP.NET Core, zobacz Rozwiązywanie problemów z ASP.NET Core w usługach Azure App Service i IIS orazmodule ASP.NET Core (ANCM) dla usług IIS.

Konsola

Dostawca Console rejestruje dane wyjściowe w konsoli. Aby uzyskać więcej informacji na temat wyświetlania Console dzienników w programowania, zobacz Rejestrowanie danych wyjściowych z polecenia dotnet run i Visual Studio.

Debugowanie

Dostawca Debug zapisuje dane wyjściowe dziennika przy użyciu System.Diagnostics.Debug klasy . Wywołuje metodę zapisu System.Diagnostics.Debug.WriteLine do dostawcy Debug .

W systemie Linux Debug lokalizacja dziennika dostawcy jest zależna od dystrybucji i może być jedną z następujących:

  • /var/log/message
  • /var/log/syslog

Źródło zdarzeń

EventSource Dostawca zapisuje w źródle zdarzeń międzyplatformowych o nazwie Microsoft-Extensions-Logging. W systemie Windows dostawca korzysta z funkcji ETW.

narzędzie dotnet trace

Narzędzie dotnet-trace to wieloplatformowe narzędzie globalne interfejsu wiersza polecenia, które umożliwia zbieranie śladów platformy .NET Core uruchomionego procesu. Narzędzie zbiera dane dostawcy Microsoft.Extensions.Logging.EventSource przy użyciu elementu LoggingEventSource.

Aby uzyskać instrukcje instalacji, zobacz dotnet-trace .

Użyj narzędzia dotnet trace, aby zebrać ślad z aplikacji:

  1. Uruchom aplikację za dotnet run pomocą polecenia .

  2. Określ identyfikator procesu (PID) aplikacji .NET Core:

    dotnet trace ps
    

    Znajdź identyfikator PID dla procesu, który ma taką samą nazwę jak zestaw aplikacji.

  3. dotnet trace Wykonaj polecenie.

    Ogólna składnia poleceń:

    dotnet trace collect -p {PID} 
        --providers Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"
    

    W przypadku korzystania z powłoki poleceń programu PowerShell należy ująć --providers wartość w cudzysłowy ('):

    dotnet trace collect -p {PID} 
        --providers 'Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"'
    

    Na platformach innych niż Windows dodaj -f speedscope opcję zmiany formatu pliku śledzenia danych wyjściowych na speedscope.

    Poniższa tabela definiuje słowo kluczowe:

    Słowo kluczowe Opis
    1 Rejestruje zdarzenia meta dotyczące elementu LoggingEventSource. Nie rejestruje zdarzeń z ILoggerpliku .
    2 Włącza zdarzenie po ILogger.Log() wywołaniuMessage. Zawiera informacje w sposób programowy (nie sformatowany).
    4 Włącza zdarzenie po ILogger.Log() wywołaniuFormatMessage. Udostępnia sformatowaną wersję ciągu informacji.
    8 Włącza zdarzenie po ILogger.Log() wywołaniuMessageJson. Zawiera reprezentację JSON argumentów.

    W poniższej tabeli wymieniono poziomy dostawcy:

    Poziom dostawcy Opis
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    Analizowanie poziomu kategorii może być ciągiem lub liczbą:

    Kategoria o nazwie value Wartość liczbowa
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    Poziom dostawcy i poziom kategorii:

    • Są w odwrotnej kolejności.
    • Stałe ciągów nie są identyczne.

    Jeśli nie FilterSpecs określono, implementacja EventSourceLogger próbuje przekonwertować poziom dostawcy na poziom kategorii i zastosuje go do wszystkich kategorii.

    Poziom dostawcy Poziom kategorii
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    Jeśli FilterSpecs zostanie podana, każda kategoria uwzględniona na liście używa zakodowanego tam poziomu kategorii, wszystkie inne kategorie są filtrowane.

    W poniższych przykładach przyjęto założenie:

    • Aplikacja jest uruchomiona i wywołuje polecenie logger.LogDebug("12345").
    • Identyfikator procesu (PID) został ustawiony za pośrednictwem set PID=12345metody , gdzie 12345 jest rzeczywistym identyfikatorem PID.

    Spójrzmy na następujące polecenie:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    Powyższe polecenie ma następujące działanie:

    • Przechwytuje komunikaty debugowania.
    • Nie stosuje pliku FilterSpecs.
    • Określa poziom 5, który mapuje kategorię Debug.

    Spójrzmy na następujące polecenie:

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    Powyższe polecenie ma następujące działanie:

    • Nie przechwytuje komunikatów debugowania, ponieważ poziom kategorii 5 to Critical.
    • Udostępnia element FilterSpecs.

    Następujące polecenie przechwytuje komunikaty debugowania, ponieważ poziom kategorii 1 określa Debugwartość .

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    Następujące polecenie przechwytuje komunikaty debugowania, ponieważ kategoria określa Debugwartość .

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    FilterSpecs wpisy i {Logger Category}{Category Level} reprezentują dodatkowe warunki filtrowania dzienników. Rozdziel FilterSpecs wpisy znakiem ; średnika.

    Przykład użycia powłoki poleceń systemu Windows:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:2:FilterSpecs=\"Microsoft.AspNetCore.Hosting*:4\"
    

    Poprzednie polecenie aktywuje:

    • Rejestrator źródła zdarzeń do tworzenia sformatowanych ciągów (4) dla błędów (2).
    • Microsoft.AspNetCore.Hosting Rejestrowanie na poziomie rejestrowania Informational (4).
  4. Zatrzymaj narzędzie dotnet trace, naciskając klawisz Enter lub Ctrl+C.

    Ślad jest zapisywany przy użyciu nazwy trace.nettrace w folderze, w którym dotnet trace jest wykonywane polecenie.

  5. Otwórz ślad za pomocą narzędzia Perfview. Otwórz plik trace.nettrace i zbadaj zdarzenia śledzenia.

Jeśli aplikacja nie skompiluje hosta za pomocą polecenia CreateDefaultBuilder, dodaj dostawcę źródła zdarzeń do konfiguracji rejestrowania aplikacji.

Aby uzyskać więcej informacji, zobacz:

Perfview

Użyj narzędzia PerfView , aby zbierać i wyświetlać dzienniki. Istnieją inne narzędzia do wyświetlania dzienników ETW, ale program PerfView zapewnia najlepsze środowisko pracy z zdarzeniami ETW emitowanych przez ASP.NET Core.

Aby skonfigurować program PerfView do zbierania zdarzeń zarejestrowanych przez tego dostawcę, dodaj ciąg *Microsoft-Extensions-Logging do listy Dodatkowych dostawców . Nie przegap * wartości na początku ciągu.

Dziennik zdarzeń systemu Windows

EventLog Dostawca wysyła dane wyjściowe dziennika do dziennika zdarzeń systemu Windows. W przeciwieństwie do innych dostawców EventLog dostawca nie dziedziczy domyślnych ustawień innych niż dostawca. Jeśli EventLog ustawienia dziennika nie są określone, domyślnie mają wartość LogLevel.Warning.

Aby rejestrować zdarzenia niższe niż LogLevel.Warning, jawnie ustaw poziom dziennika. Poniższy przykład ustawia domyślny poziom dziennika zdarzeń na LogLevel.Information:

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

Przeciążenia addEventLog mogą przekazać element EventLogSettings. W przypadku null określenia lub nie określono następujących ustawień domyślnych:

  • LogName: "Aplikacja"
  • SourceName: Środowisko uruchomieniowe platformy .NET"
  • MachineName: używana jest nazwa komputera lokalnego.

Poniższy kod zmienia SourceName wartość z domyślnej wartości ".NET Runtime" na MyLogs:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddEventLog(eventLogSettings =>
                {
                    eventLogSettings.SourceName = "MyLogs"; 
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Azure App Service

Pakiet dostawcy Microsoft.Extensions.Logging.AzureAppServices zapisuje dzienniki w plikach tekstowych w systemie plików Azure App Service aplikacji i w magazynie obiektów blob na koncie usługi Azure Storage.

Pakiet dostawcy nie jest uwzględniony w strukturze udostępnionej. Aby użyć dostawcy, dodaj pakiet dostawcy do projektu.

Aby skonfigurować ustawienia dostawcy, użyj polecenia AzureFileLoggerOptions i AzureBlobLoggerOptions, jak pokazano w poniższym przykładzie:

public class Scopes
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging => logging.AddAzureWebAppDiagnostics())
                .ConfigureServices(serviceCollection => serviceCollection
                    .Configure<AzureFileLoggerOptions>(options =>
                    {
                        options.FileName = "azure-diagnostics-";
                        options.FileSizeLimit = 50 * 1024;
                        options.RetainedFileCountLimit = 5;
                    })
                    .Configure<AzureBlobLoggerOptions>(options =>
                    {
                        options.BlobName = "log.txt";
                    }))
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

Po wdrożeniu w Azure App Service aplikacja używa ustawień w sekcji dzienników App Service na stronie App Service Azure Portal. Po zaktualizowaniu następujących ustawień zmiany zostaną zastosowane natychmiast bez konieczności ponownego uruchamiania lub ponownego wdrażania aplikacji.

  • Rejestrowanie aplikacji (system plików)
  • Rejestrowanie aplikacji (obiekt blob)

Domyślną lokalizacją plików dziennika jest folder D:\home\LogFiles\Application , a domyślna nazwa pliku to diagnostics-yyyymmdd.txt. Domyślny limit rozmiaru pliku to 10 MB, a domyślna maksymalna liczba przechowywanych plików to 2. Domyślna nazwa obiektu blob to {app-name}{timestamp}/rrrr/mm/dd/hh/{guid}-applicationLog.txt.

Ten dostawca rejestruje tylko wtedy, gdy projekt działa w środowisku platformy Azure.

Przesyłanie strumieniowe dzienników platformy Azure

Przesyłanie strumieniowe dzienników platformy Azure obsługuje wyświetlanie aktywności dziennika w czasie rzeczywistym z:

  • Serwer aplikacji
  • Serwer internetowy
  • Śledzenie żądań, które zakończyło się niepowodzeniem

Aby skonfigurować przesyłanie strumieniowe dzienników platformy Azure:

  • Przejdź do strony dzienników App Service na stronie portalu aplikacji.
  • Ustaw pozycję Rejestrowanie aplikacji (system plików) na wartość Włączone.
  • Wybierz poziom dziennika. To ustawienie dotyczy tylko przesyłania strumieniowego dzienników platformy Azure.

Przejdź do strony Strumień dzienników , aby wyświetlić dzienniki. Zarejestrowane komunikaty są rejestrowane za pomocą interfejsu ILogger .

Azure Application Insights

Pakiet dostawcy Microsoft.Extensions.Logging.ApplicationInsights zapisuje dzienniki w usłudze aplikacja systemu Azure Insights. Application Insights to usługa, która monitoruje aplikację internetową i udostępnia narzędzia do wykonywania zapytań i analizowania danych telemetrycznych. Jeśli używasz tego dostawcy, możesz wykonywać zapytania i analizować dzienniki przy użyciu narzędzi usługi Application Insights.

Dostawca rejestrowania jest dołączany jako zależność microsoft.ApplicationInsights.AspNetCore, czyli pakiet, który udostępnia wszystkie dostępne dane telemetryczne dla ASP.NET Core. Jeśli używasz tego pakietu, nie musisz instalować pakietu dostawcy.

Pakiet Microsoft.ApplicationInsights.Web jest przeznaczony dla ASP.NET 4.x, a nie ASP.NET Core.

Więcej informacji można znaleźć w następujących zasobach:

Dostawcy rejestrowania innych firm

Struktury rejestrowania innych firm, które współpracują z ASP.NET Core:

Niektóre struktury innych firm mogą wykonywać rejestrowanie semantyczne, nazywane również rejestrowaniem ze strukturą.

Korzystanie z platformy innej firmy jest podobne do korzystania z jednego z wbudowanych dostawców:

  1. Dodaj pakiet NuGet do projektu.
  2. Wywołaj metodę rozszerzenia udostępnioną przez platformę ILoggerFactory rejestrowania.

Aby uzyskać więcej informacji, zobacz dokumentację każdego dostawcy. Dostawcy rejestrowania innych firm nie są obsługiwani przez firmę Microsoft.

Aplikacja konsolowa nienależącą do hosta

Przykład użycia hosta ogólnego w aplikacji konsolowej innej niż internetowa można znaleźć w Program.cs pliku przykładowej aplikacji Zadania w tle (zadania w tle z hostowanymi usługami w ASP.NET Core).

Kod rejestrowania aplikacji bez hosta ogólnego różni się w sposobie dodawania dostawców i tworzenia rejestratorów.

Dostawcy rejestrowania

W aplikacji konsoli innej niż host wywołaj metodę rozszerzenia dostawcy Add{provider name} podczas tworzenia elementu LoggerFactory:

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

Tworzenie dzienników

Aby utworzyć dzienniki, użyj ILogger<TCategoryName> obiektu. Użyj polecenia LoggerFactory , aby utworzyć element ILogger.

Poniższy przykład tworzy rejestrator z LoggingConsoleApp.Program jako kategorią.

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

W poniższym przykładzie rejestrator służy do tworzenia dzienników z Information poziomem . Poziom dziennika wskazuje ważność zarejestrowanego zdarzenia.

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

Poziomy i kategorie zostały szczegółowo wyjaśnione w tym dokumencie.

Dziennik podczas budowy hosta

Rejestrowanie podczas budowy hosta nie jest obsługiwane bezpośrednio. Można jednak użyć oddzielnego rejestratora. W poniższym przykładzie rejestrator serilog służy do logowania się.CreateHostBuilder AddSerilog używa konfiguracji statycznej określonej w pliku Log.Logger:

using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var builtConfig = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddCommandLine(args)
            .Build();

        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .WriteTo.File(builtConfig["Logging:FilePath"])
            .CreateLogger();

        try
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureServices((context, services) =>
                {
                    services.AddRazorPages();
                })
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddConfiguration(builtConfig);
                })
                .ConfigureLogging(logging =>
                {   
                    logging.AddSerilog();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host builder error");

            throw;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}

Konfigurowanie usługi, która zależy od usługi ILogger

Iniekcja konstruktora rejestratora działa Startup we wcześniejszych wersjach ASP.NET Core, ponieważ dla hosta sieci Web jest tworzony oddzielny kontener DI. Aby uzyskać informacje o tym, dlaczego dla hosta ogólnego jest tworzony tylko jeden kontener, zobacz ogłoszenie o zmianie powodującej niezgodność.

Aby skonfigurować usługę, która zależy od ILogger<T>metody , użyj iniekcji konstruktora lub podaj metodę fabryki. Metoda fabryki jest zalecana tylko wtedy, gdy nie ma innej opcji. Rozważmy na przykład usługę, która wymaga wystąpienia dostarczonego ILogger<T> przez di:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddRazorPages();

    services.AddSingleton<IMyService>((container) =>
    {
        var logger = container.GetRequiredService<ILogger<MyService>>();
        return new MyService() { Logger = logger };
    });
}

Powyższy wyróżniony kod jest Func<T,TResult> uruchamiany po raz pierwszy kontener DI musi skonstruować wystąpienie klasy MyService. W ten sposób możesz uzyskać dostęp do dowolnych zarejestrowanych usług.

Tworzenie dzienników w programie Main

Następujący kod rejestruje się, Main uzyskując ILogger wystąpienie z di po utworzeniu hosta:

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    var logger = host.Services.GetRequiredService<ILogger<Program>>();
    logger.LogInformation("Host created.");

    host.Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Tworzenie dzienników w uruchamianiu

Poniższy kod zapisuje dzienniki w pliku Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
                      ILogger<Startup> logger)
{
    if (env.IsDevelopment())
    {
        logger.LogInformation("In Development.");
        app.UseDeveloperExceptionPage();
    }
    else
    {
        logger.LogInformation("Not Development.");
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapRazorPages();
    });
}

Zapisywanie dzienników przed ukończeniem konfiguracji kontenera DI w metodzie Startup.ConfigureServices nie jest obsługiwane:

  • Wstrzykiwanie rejestratora do konstruktora Startup nie jest obsługiwane.
  • Wstrzykiwanie rejestratora Startup.ConfigureServices do podpisu metody nie jest obsługiwane

Przyczyną tego ograniczenia jest to, że rejestrowanie zależy od di i konfiguracji, co z kolei zależy od di. Kontener DI nie jest konfigurowany do ConfigureServices momentu zakończenia.

Aby uzyskać informacje na temat konfigurowania usługi, która zależy od ILogger<T> tego, czy wstrzykiwanie konstruktora rejestratora Startup działało we wcześniejszych wersjach, zobacz Konfigurowanie usługi, która zależy od protokołu ILogger.

Brak metod asynchronicznego rejestratora

Rejestrowanie powinno być tak szybkie, że nie jest warte kosztu wydajności kodu asynchronicznego. Jeśli magazyn danych rejestrowania działa wolno, nie zapisuj go bezpośrednio. Rozważ zapisanie komunikatów dziennika w szybkim magazynie początkowo, a następnie przeniesienie ich do powolnego magazynu później. Na przykład podczas rejestrowania w SQL Server nie rób tego bezpośrednio w metodzieLog, ponieważ Log metody są synchroniczne. Zamiast tego synchronicznie dodaj komunikaty dziennika do kolejki w pamięci i ma proces roboczy w tle ściągnąć komunikaty z kolejki, aby wykonać asynchroniczną pracę wypychania danych do SQL Server. Aby uzyskać więcej informacji, zobacz ten problem z usługą GitHub.

Zmienianie poziomów dziennika w uruchomionej aplikacji

Interfejs API rejestrowania nie zawiera scenariusza zmiany poziomów dziennika podczas działania aplikacji. Jednak niektórzy dostawcy konfiguracji mogą ponownie ładować konfigurację, która ma natychmiastowy wpływ na konfigurację rejestrowania. Na przykład dostawca konfiguracji plików domyślnie ponownie ładuje konfigurację rejestrowania. Jeśli konfiguracja zostanie zmieniona w kodzie podczas działania aplikacji, aplikacja może wywołać IConfigurationRoot.Reload metodę w celu zaktualizowania konfiguracji rejestrowania aplikacji.

ILogger i ILoggerFactory

Interfejsy ILogger<TCategoryName> i ILoggerFactory i implementacje są uwzględniane w zestawie SDK platformy .NET Core. Są one również dostępne w następujących pakietach NuGet:

Stosowanie reguł filtru dziennika w kodzie

Preferowane podejście do ustawiania reguł filtrowania dzienników odbywa się przy użyciu konfiguracji.

W poniższym przykładzie pokazano, jak zarejestrować reguły filtrowania w kodzie:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
               logging.AddFilter("System", LogLevel.Debug)
                  .AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information)
                  .AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

logging.AddFilter("System", LogLevel.Debug) określa kategorię System i poziom Debugdziennika . Filtr jest stosowany do wszystkich dostawców, ponieważ nie skonfigurowano określonego dostawcy.

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) Określa:

  • Dostawca rejestrowania Debug .
  • Poziom Information dziennika i wyższy.
  • Wszystkie kategorie rozpoczynające się od "Microsoft".

Automatyczne rejestrowanie zakresu za pomocą właściwości SpanId, TraceId i ParentId

Biblioteki rejestrowania niejawnie tworzą obiekt zakresu z elementami SpanId, TraceIdi ParentId. To zachowanie jest konfigurowane za pomocą polecenia ActivityTrackingOptions.

  var loggerFactory = LoggerFactory.Create(logging =>
  {
      logging.Configure(options =>
      {
          options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                              | ActivityTrackingOptions.TraceId
                                              | ActivityTrackingOptions.ParentId;
      }).AddSimpleConsole(options =>
      {
          options.IncludeScopes = true;
      });
  });

traceparent Jeśli nagłówek żądania HTTP jest ustawiony, ParentId zakres w dzienniku pokazuje W3C parent-id z nagłówka powiązanegotraceparent, a SpanId w zakresie dziennika jest wyświetlany zaktualizowany parent-id dla następnego kroku/zakresu powiązanego. Aby uzyskać więcej informacji, zobacz Mutating the traceparent Field (Mutowanie pola śledzenia).

Tworzenie niestandardowego rejestratora

Aby utworzyć niestandardowy rejestrator, zobacz Implementowanie niestandardowego dostawcy rejestrowania na platformie .NET.

Dodatkowe zasoby