Rejestrowanie na platformie .NET Core i ASP.NET Core
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.
Ostrzeżenie
Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz .NET i .NET Core Support Policy (Zasady obsługi platformy .NET Core). Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.
Autorzy: Kirk Larkin, Juergen Gutsch i Rick Anderson
W tym artykule opisano rejestrowanie na platformie .NET, ponieważ ma zastosowanie do aplikacji platformy ASP.NET Core. Aby uzyskać szczegółowe informacje na temat rejestrowania na platformie .NET, zobacz Rejestrowanie na platformie .NET.
Aby uzyskać Blazor wskazówki dotyczące rejestrowania, które dodaje lub zastępuje wskazówki w tym węźle, zobacz ASP.NET Core logging ( Rejestrowanie podstawoweBlazor).
Dostawcy rejestrowania
Dostawcy rejestrowania przechowują dzienniki, z wyjątkiem dostawcy Console
, który wyświetla dzienniki. Na przykład dostawca usługi Azure Application Insights przechowuje dzienniki w usłudze Azure Application Insights. Można włączyć wielu dostawców.
Domyślne szablony aplikacji internetowych ASP.NET Core wywołają metodę WebApplication.CreateBuilder, która dodaje następujących dostawców rejestrowania:
- Konsola
- Debug
- EventSource
- EventLog: tylko system Windows
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 plik Program.cs
utworzony przy użyciu szablonów aplikacji internetowych platformy ASP.NET Core. W następnych kilku sekcjach znajdują się przykłady oparte na szablonach aplikacji internetowych platformy ASP.NET Core.
Poniższy kod zastępuje domyślny zestaw dostawców rejestrowania dodanych przez metodę 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ć informacje o dodatkowych dostawcach, zobacz:
Tworzenie dzienników
Aby utworzyć dzienniki, użyj obiektu ILogger<TCategoryName> z wstrzykiwania zależności (DI).
Poniższy przykład:
- Tworzy rejestrator,
ILogger<AboutModel>
, który używa kategorii dziennika w pełni kwalifikowanej nazwy typuAboutModel
. Kategoria dziennika to ciąg skojarzony z każdym dziennikiem. - Wywołuje metodę LogInformation w celu rejestrowania na poziomie Information. 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 omówione bardziej szczegółowo w dalszej części tego dokumentu.
Aby uzyskać informacje na temat struktury Blazor, zobacz Rejestrowanie aplikacji Blazor platformy ASP.NET Core.
Konfigurowanie rejestrowania
Konfiguracja rejestrowania jest na ogół udostępniana przez sekcję Logging
plików appsettings.{ENVIRONMENT}.json
, gdzie symbol zastępczy {ENVIRONMENT}
oznacza środowisko. Poniższy plik appsettings.Development.json
jest generowany przez szablony aplikacji internetowych platformy ASP.NET Core:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
W powyższym pliku JSON:
- Określono kategorie
"Default"
i"Microsoft.AspNetCore"
. - Kategoria
"Microsoft.AspNetCore"
dotyczy wszystkich kategorii rozpoczynających się ciągiem"Microsoft.AspNetCore"
. To ustawienie na przykład dotyczy kategorii"Microsoft.AspNetCore.Routing.EndpointMiddleware"
. - Kategoria
"Microsoft.AspNetCore"
dokonuje rejestracji na poziomie dziennikaWarning
i wyższym. - Nie określono konkretnego dostawcy dziennika, więc właściwość
LogLevel
dotyczy wszystkich włączonych dostawców rejestrowania z wyjątkiem dostawcy Windows EventLog.
Właściwość Logging
może mieć wyliczenie LogLevel i właściwości dostawcy dziennika. Wyliczenie LogLevel
określa minimalny poziom rejestrowania dla wybranych kategorii. W poprzednim pliku JSON określono poziomy dziennika Information
i Warning
. Wyliczenie LogLevel
określa ważność dziennika i ma wartość z zakresu od 0 do 6:
Trace
= 0, Debug
= 1, Information
= 2, Warning
= 3, Error
= 4, Critical
= 5 i None
= 6.
Gdy wyliczenie LogLevel
jest określone, rejestrowanie jest włączone dla komunikatów na tym i wyższym poziomie. W poprzednim pliku JSON kategoria Default
jest rejestrowana na poziomie Information
i wyższym. Rejestrowane są na przykład komunikaty na poziomach Information
, Warning
, Error
i Critical
. Jeśli wyliczenie LogLevel
nie zostanie określone, dla rejestrowania stosowany jest poziom domyślny Information
. Aby uzyskać więcej informacji, zobacz Poziomy dziennika.
Właściwość dostawcy może określać właściwość LogLevel
. Właściwość LogLevel
w sekcji dostawcy określa poziomy, które mają być rejestrowane dla tego dostawcy, i zastępuje ustawienia dziennika bez określonego dostawcy. Rozważ użycie następującego pliku appsettings.json
:
{
"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 sekcji Logging.{PROVIDER NAME}.LogLevel
zastępują ustawienia w sekcji Logging.LogLevel
, gdzie symbol zastępczy {PROVIDER NAME}
jest nazwą dostawcy. W powyższym pliku JSON domyślny poziom dziennika dostawcy Debug
jest ustawiony na wartość Information
:
Logging:Debug:LogLevel:Default:Information
Poprzednie ustawienie określa poziom dziennika Information
dla każdej kategorii Logging:Debug:
z wyjątkiem kategorii Microsoft.Hosting
. Gdy jest określona konkretna kategoria, zastępuje ona kategorię domyślną. W powyższym pliku JSON kategorie "Microsoft.Hosting"
i "Default"
w sekcji Logging:Debug:LogLevel
zastępują ustawienia w sekcji Logging:LogLevel
.
Minimalny poziom dziennika można określić dla:
- określonych dostawców, na przykład
Logging:EventSource:LogLevel:Default:Information
- określonych kategorii, na przykład:
Logging:LogLevel:Microsoft:Warning
- wszystkich dostawców i wszystkich kategorii:
Logging:LogLevel:Default:Warning
Wszystkie dzienniki poniżej minimalnego poziomu nie są:
- przekazywane do dostawcy,
- rejestrowane ani wyświetlane.
Aby pominąć wszystkie dzienniki, określ poziom LogLevel.None. Poziom LogLevel.None
ma wartość 6, która jest wyższa niż w przypadku poziomu LogLevel.Critical
(5).
Jeśli dostawca obsługuje zakresy dzienników, właściwość IncludeScopes
wskazuje, czy są one włączone. Aby uzyskać więcej informacji, zobacz zakresy dzienników.
W poniższym pliku appsettings.json
wszyscy dostawcy 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 powyższym przykładzie:
- Kategorie i poziomy nie są sugerowane wartości. Przykład jest udostępniany w celu wyświetlenia wszystkich domyślnych dostawców.
- Ustawienia w sekcji
Logging.{PROVIDER NAME}.LogLevel
zastępują ustawienia w sekcjiLogging.LogLevel
, gdzie symbol zastępczy{PROVIDER NAME}
jest nazwą dostawcy. Na przykład poziom w sekcjiDebug.LogLevel.Default
zastępuje poziom w sekcjiLogLevel.Default
. - Dla każdego dostawcy domyślnego użyto aliasu. Każdy dostawca ma zdefiniowany alias, którego można używać w konfiguracji zamiast w pełni kwalifikowanej nazwy typu. Wbudowane aliasy dostawców to:
Console
Debug
EventSource
EventLog
AzureAppServicesFile
AzureAppServicesBlob
ApplicationInsights
Rejestrowanie w pliku Program.cs
Poniższy przykład wywołuje metodę Builder.WebApplication.Logger w pliku Program.cs
i 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();
Poniższy przykład wywołuje metodę AddConsole w pliku Program.cs
i rejestruje punkt końcowy /Test
:
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddConsole();
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
logger.LogInformation("Testing logging in Program.cs");
await response.WriteAsync("Testing");
});
app.Run();
Poniższy przykład wywołuje metodę AddSimpleConsole w pliku Program.cs
, wyłącza kolory dla danych wyjściowych i rejestruje punkt końcowy /Test
:
using Microsoft.Extensions.Logging.Console;
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddSimpleConsole(i => i.ColorBehavior = LoggerColorBehavior.Disabled);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
logger.LogInformation("Testing logging in Program.cs");
await response.WriteAsync("Testing");
});
app.Run();
Ustawianie poziomu dziennika za pośrednictwem wiersza polecenia, zmiennych środowiskowych i innej konfiguracji
Poziom dziennika można ustawić za pośrednictwem dowolnego dostawcy konfiguracji.
Separator :
nie współdziała z kluczami hierarchicznymi zmiennych środowiskowych na wszystkich platformach. Na przykład separator nie jest obsługiwany przez powłokę :
Bash. Podwójne podkreślenie, __
, to:
- Jest obsługiwany przez wszystkie platformy.
- Automatycznie zamieniono dwukropek na
:
.
Poniższe polecenia:
- Ustawiają klucz środowiska
Logging:LogLevel:Microsoft
na wartośćInformation
w systemie Windows. - Testują ustawienia w przypadku używania aplikacji utworzonej przy użyciu szablonów aplikacji internetowych platformy ASP.NET Core. Polecenie
dotnet run
należy uruchomić w katalogu projektu po użyciu poleceniaset
.
set Logging__LogLevel__Microsoft=Information
dotnet run
Poprzednie ustawienia środowiska:
- są ustawiane tylko w procesach uruchamianych z poziomu okna poleceń, w którym zostały ustawione;
- nie są odczytywane przez przeglądarki uruchamiane za pomocą programu Visual Studio.
Poniższe polecenie setx również ustawia klucz środowiska i wartość w systemie Windows. W przeciwieństwie do polecenia set
, ustawienia polecenia setx
są trwałe. Przełącznik /M
ustawia zmienną w środowisku systemowym. Jeśli przełącznik /M
nie jest używany, ustawiana jest zmienna środowiskowa użytkownika.
setx Logging__LogLevel__Microsoft Information /M
Rozważ użycie następującego pliku appsettings.json
:
"Logging": {
"Console": {
"LogLevel": {
"Microsoft.Hosting.Lifetime": "Trace"
}
}
}
Poniższe polecenie ustawia powyższą konfigurację w środowisku:
setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M
Uwaga
Podczas konfigurowania zmiennych środowiskowych z nazwami zawierającymi .
(kropki) w systemach macOS i Linux należy rozważyć "Eksportowanie zmiennej z kropką (.) w nim" pytanie w witrynie Stack Exchange i odpowiadające jej zaakceptowanej odpowiedzi.
W usłudze Azure App Service wybierz pozycję Nowe ustawienie aplikacji na stronie Ustawienia > Konfiguracja. Ustawienia aplikacji usługi Azure App Service są:
- szyfrowane podczas przechowywania i przesyłane za pośrednictwem zaszyfrowanego kanału,
- Uwidaczniane jako zmienne środowiskowe.
Aby uzyskać więcej informacji, zobacz aplikacja systemu Azure: Zastępowanie konfiguracji aplikacji przy użyciu witryny Azure Portal.
Aby uzyskać więcej informacji na temat ustawiania wartości konfiguracji platformy 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, usługi Azure App Configuration, innych formatów plików i nie tylko, zobacz Konfiguracja na platformie ASP.NET Core.
Jak są stosowane reguły filtrowania
Po utworzeniu obiektu ILogger<TCategoryName> obiekt ILoggerFactory wybiera jedną regułę dla każdego dostawcy, która ma być stosowana do tego rejestratora. Wszystkie komunikaty zapisywane przez wystąpienie ILogger
są filtrowane na podstawie wybranych reguł. Z dostępnych reguł wybierana jest najbardziej konkretna reguła dla każdej pary dostawcy i kategorii.
Następujący algorytm jest używany dla każdego dostawcy podczas tworzenia obiektu ILogger
dla danej kategorii:
- Wybierz wszystkie reguły zgodne z dostawcą lub jego aliasem. Jeśli nie zostanie znalezione żadne dopasowanie, wybierz wszystkie reguły z pustym dostawcą.
- Z wyników poprzedniego kroku wybierz reguły z najdłuższym pasującym prefiksem kategorii. Jeśli nie zostanie znalezione żadne dopasowanie, wybierz wszystkie reguły, które nie określają kategorii.
- Jeśli wybrano wiele reguł, użyj ostatniej.
- Jeśli nie wybrano żadnych reguł, użyj
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 danych wyjściowych debugowania podczas debugowania.
- W oknie serwera internetowego platformy ASP.NET Core.
- W oknie konsoli w przypadku uruchomieniu aplikacji za pomocą polecenia
dotnet run
.
Dzienniki rozpoczynające się od kategorii "Microsoft" pochodzą z platformy .NET. Platforma .NET i kod aplikacji używają tego samego interfejsu API rejestrowania i dostawców.
Kategoria dziennika
Po utworzeniu obiektu ILogger
jest określana kategoria. Ta kategoria jest uwzględniania w każdym komunikacie dziennika utworzonym przez to wystąpienie ILogger
. Ciąg kategorii jest dowolny, ale konwencja polega na użyciu w pełni kwalifikowanej nazwy klasy. Na przykład w kontrolerze nazwa może mieć postać "TodoApi.Controllers.TodoController"
. Aplikacje internetowe platformy ASP.NET Core używają ILogger<T>
, aby automatycznie pobierać wystąpienie ILogger
, które używa w pełni kwalifikowanej nazwy typu T
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.");
}
}
Jeśli wymagana jest dalsza kategoryzacja, konwencja polega na użyciu nazwy hierarchicznej przez dołączenie podkategorii do w pełni kwalifikowanej nazwy klasy i jawne określenie kategorii przy użyciu polecenia ILoggerFactory.CreateLogger
:
public class ContactModel : PageModel
{
private readonly ILogger _logger;
public ContactModel(ILoggerFactory logger)
{
_logger = logger.CreateLogger("TodoApi.Pages.ContactModel.MyCategory");
}
public void OnGet()
{
_logger.LogInformation("GET Pages.ContactModel called.");
}
Wywoływanie metody CreateLogger
ze stałą nazwą może być przydatne w przypadku użycia w wielu metodach, dzięki czemu zdarzenia mogą być zorganizowane według kategorii.
ILogger<T>
jest równoważne wywołaniu metody CreateLogger
z w pełni kwalifikowaną nazwą typu T
.
Poziom dziennika
Poniższa tabela zawiera wartości LogLevel, wygodną metodę rozszerzenia Log{LogLevel}
i sugerowane użycie:
PoziomRejestrowania | Wartość | Metoda | opis |
---|---|---|---|
Trace | 0 | LogTrace | Obejmuje najbardziej szczegółowe komunikaty. Te komunikaty mogą zawierać poufne dane aplikacji. Komunikaty są domyślnie wyłączone i nie powinny być włączane w środowisku produkcyjnym. |
Debug | 1 | LogDebug | Na potrzeby debugowania i programowania. Należy zachować ostrożność w środowisku produkcyjnym ze względu na dużą pojemność. |
Information | 2 | LogInformation | Śledzi ogólny przepływ aplikacji. Może mieć wartość długoterminową. |
Warning | 3 | LogWarning | Na potrzeby nietypowych lub nieoczekiwanych zdarzeń. Zazwyczaj obejmuje błędy lub warunki, które nie powodują awarii aplikacji. |
Error | 100 | LogError | Na potrzeby błędów i wyjątków, których nie można obsłużyć. Te komunikaty wskazują na błąd w bieżącej operacji lub żądaniu, a nie awarię całej aplikacji. |
Critical | 5 | LogCritical | Na potrzeby 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 powyższej tabeli obiekty LogLevel
uporządkowano w kolejności od najniższej do najwyższej ważności.
Pierwszy parametr metody Log, LogLevel, wskazuje ważność dziennika. Zamiast wywoływać metodę Log(LogLevel, ...)
, większość deweloperów wywołuje metody rozszerzenia Log{LOG LEVEL}
, gdzie symbol zastępczy {LOG LEVEL}
jest poziomem dziennika. Na przykład dwa poniższe wywołania rejestrowania działają tak samo 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świetlany w sekcji Identyfikator zdarzenia dziennika.
Metody MyDisplayRouteInfo i ToCtxString są dostarczane przez pakiet NuGet Rick.Docs.Samples.RouteInfo. Metody te wyświetlają informacje o trasie Controller
i Razor Page
.
Poniższy kod tworzy dzienniki Information
i Warning
:
[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 powyższym kodzie pierwszym parametrem metody Log{LOG LEVEL}
, MyLogEvents.GetItem
, jest identyfikator zdarzenia dziennika. Drugi parametr to szablon komunikatu z symbolami zastępczymi dla wartości argumentów dostarczanych przez pozostałe parametry metody. Parametry metody zostały omówione w sekcji dotyczące szablonu komunikatu w dalszej części tego dokumentu.
Wywołaj odpowiednią metodę Log{LOG LEVEL}
, aby kontrolować ilość danych wyjściowych dziennika zapisywanych na określonym nośniku magazynu. Na przykład:
- W środowisku produkcyjnym:
- Rejestrowanie na poziomach
Trace
,Debug
lubInformation
generuje dużą ilość szczegółowych komunikatów dziennika. Aby kontrolować koszty i nie przekraczać limitów magazynu danych, dziennikówTrace
,Debug
lubInformation
komunikatów na poziomie do magazynu danych o wysokim poziomie. Rozważ ograniczenieTrace
wartości ,Debug
lubInformation
do określonych kategorii. - Rejestrowanie na poziomach od
Warning
doCritical
powinno generować kilka komunikatów dziennika.- Koszty i limity magazynu zwykle nie są tu problemem.
- Niewielka liczba dzienników zapewnia większą swobodę wyboru magazynu danych.
- Rejestrowanie na poziomach
- W programowania:
- Ustaw wartość
Warning
. - Dodaj
Trace
komunikaty ,Debug
lubInformation
podczas rozwiązywania problemów. Aby ograniczyć dane wyjściowe, ustawTrace
wartości ,Debug
lubInformation
tylko dla kategorii objętych badaniem.
- Ustaw wartość
Platforma ASP.NET Core zapisuje dzienniki dla zdarzeń struktury. Rozważmy na przykład dane wyjściowe dziennika dla:
- Aplikacji Razor Pages utworzonej przy użyciu szablonów platformy ASP.NET Core.
- Dla rejestrowania ustawiono wartość
Logging:Console:LogLevel:Microsoft:Information
. - Nawigacja do strony Privacy:
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
Poniższy plik JSON ustawia Logging:Console:LogLevel:Microsoft:Information
:
{
"Logging": { // Default, all providers.
"LogLevel": {
"Microsoft": "Warning"
},
"Console": { // Console provider.
"LogLevel": {
"Microsoft": "Information"
}
}
}
}
Identyfikator zdarzenia dziennika
Każdy dziennik może określać identyfikator zdarzenia. Przykładowa aplikacja używa klasy MyLogEvents
, aby definiować identyfikatory 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 wcale. Dostawca debugowania nie pokazuje 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 po identyfikatorze.
Szablon komunikatu dziennika
Każdy interfejs API dziennika używa szablonu komunikatu. Szablon komunikatu może zawierać symbole zastępcze, dla których są podawane argumenty. Dla symboli zastępczych należy używać nazw, 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);
}
To, które parametry są używane w celu podania wartości symboli zastępczych w komunikatach dziennika jest określane przez kolejność parametrów, a nie nazwy ich symboli zastępczych. W poniższym kodzie nazwy parametrów w symbolach zastępczych szablonu komunikatu są niezgodne z kolejnością:
var apples = 1;
var pears = 2;
var bananas = 3;
_logger.LogInformation("Parameters: {Pears}, {Bananas}, {Apples}", apples, pears, bananas);
Parametry są jednak przypisywane do symboli zastępczych w kolejności: apples
, pears
, bananas
. Komunikat dziennika odzwierciedla kolejność parametrów:
Parameters: 1, 2, 3
Takie podejście umożliwia dostawcom rejestrowania zaimplementowanie rejestrowania semantycznego lub strukturalnego. 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ć właściwości
ID
iRequestTime
. - Tabele z właściwościami upraszczają wykonywanie zapytań dotyczących zarejestrowanych danych. Na przykład zapytanie może znaleźć wszystkie dzienniki w określonym zakresie
RequestTime
bez konieczności analizowania czasu z komunikatu tekstowego.
Wyjątki dziennikó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();
}
Metody MyDisplayRouteInfo i ToCtxString są dostarczane przez pakiet NuGet Rick.Docs.Samples.RouteInfo. Metody te wyświetlają informacje o trasie Controller
i Razor Page
.
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ą:
- Utworzona przy użyciu szablonów aplikacji internetowej platformy ASP.NET.
- Pliki
appsettings.json
iappsettings.Development.json
zostały usunięte lub zmienione.
W przypadku poprzedniej konfiguracji przejście do strony prywatności lub strony głównej powoduje wygenerowanie wielu komunikatów Trace
, Debug
i Information
z ciągiem Microsoft
w nazwie kategorii.
Poniższy kod ustawia domyślny poziom dziennika, kiedy 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ślane w konfiguracji, a nie w kodzie.
Funkcja filtru
Funkcja filtru jest wywoływana dla wszystkich dostawców i kategorii, dla których nie przypisano reguł za pomocą konfiguracji lub kodu:
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 parametr Controller
lub Microsoft
, a poziom dziennika ma wartość Information
lub wyższą.
Ogólnie rzecz biorąc, poziomy dziennika powinny być określane w konfiguracji, a nie w kodzie.
kategorie ASP.NET Core
Poniższa tabela zawiera niektóre kategorie używane przez platformę ASP.NET Core.
Kategoria | Uwagi |
---|---|
Microsoft.AspNetCore |
Ogólna diagnostyka platformy ASP.NET Core. |
Microsoft.AspNetCore.DataProtection |
Które klucze były rozważane, znalezione i użyte. |
Microsoft.AspNetCore.HostFiltering |
Dozwolone hosty. |
Microsoft.AspNetCore.Hosting |
Jak długo trwało wykonywanie żądań HTTP oraz czas ich rozpoczęcia. Które zestawy startowe hostingu zostały załadowane. |
Microsoft.AspNetCore.Mvc |
Diagnostyka MVC i Razor. Powiązanie modelu, wykonywanie filtru, kompilacja widoku, wybór akcji. |
Microsoft.AspNetCore.Routing |
Kierowanie zgodnych informacji. |
Microsoft.AspNetCore.Server |
Odpowiedzi dotyczące uruchomienia i zatrzymania połączenia oraz utrzymania aktywności. Informacje o certyfikacie HTTPS. |
Microsoft.AspNetCore.StaticFiles |
Obsłużone pliki. |
Aby wyświetlić więcej kategorii w oknie konsoli, w pliku appsettings.Development.json
wprowadź następujące ustawienia:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Trace",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
Aby uzyskać listę kategorii platformy Entity Framework, zobacz Kategorie komunikatów EF.
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:
- jest typem IDisposable zwracanym przez metodę BeginScope,
- trwa do momentu usunięcia.
Następujący dostawcy obsługują zakresy:
Użyj zakresu, opakowując wywołania rejestratora za pomocą bloku using
:
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
TodoItem todoItem;
var transactionId = Guid.NewGuid().ToString();
using (_logger.BeginScope(new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("TransactionId", transactionId),
}))
{
_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
Platforma 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 w ramach struktury udostępnionej. Należy ich zainstalować jako dodatkowe pakiety nuget.
Platforma ASP.NET Core nie zawiera dostawcy rejestrowania na potrzeby zapisywania dzienników w plikach. Aby zapisywać dzienniki w plikach z aplikacji platformy ASP.NET Core, rozważ użycie dostawcy rejestrowania innej firmy.
Aby uzyskać informacje na temat właściwości stdout
i rejestrowania debugowania przy użyciu modułu ASP.NET Core Module, zobacz Rozwiązywanie problemów z platformą ASP.NET Core w usługach Azure App Service oraz IIS, a także Moduł ASP.NET Core Module (ANCM) dla usług IIS.
Konsola
Dostawca Console
rejestruje dane wyjściowe w konsoli. Aby uzyskać więcej informacji na temat wyświetlania dzienników dostawcy Console
w środowisku programistycznym, zobacz Rejestrowanie danych wyjściowych z polecenia dotnet run i programu Visual Studio.
Debugowanie
Dostawca Debug
zapisuje dane wyjściowe dziennika przy użyciu klasy System.Diagnostics.Debug. Wywołania metody System.Diagnostics.Debug.WriteLine
zapisują do dostawcy Debug
.
W systemie Linux lokalizacja dziennika dostawcy Debug
jest zależna od dystrybucji i może być jedną z następujących:
/var/log/message
/var/log/syslog
Źródło zdarzenia
Dostawca EventSource
zapisuje w międzyplatformowym źródle zdarzeń o nazwie Microsoft-Extensions-Logging
. W systemie Windows dostawca używa funkcji ETW.
dotnet-trace tooling
Narzędzie dotnet-trace
jest międzyplatformowym globalnym narzędziem interfejsu wiersza polecenia, które umożliwia zbieranie śladów platformy .NET Core uruchomionego procesu. Narzędzie to zbiera dane dostawcy Microsoft.Extensions.Logging.EventSource przy użyciu klasy LoggingEventSource.
Aby uzyskać instrukcje instalacji, zobacz dotnet-trace
.
Użyj narzędzi dotnet-trace
, aby zebrać ślad z aplikacji:
Uruchom aplikację za pomocą polecenia
dotnet run
.Określ identyfikator procesu (PID) aplikacji platformy .NET Core:
dotnet-trace ps
Znajdź identyfikator PID dla procesu, który ma taką samą nazwę, jak zestaw aplikacji.
Wykonaj polecenie
dotnet-trace
.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ąć wartość
--providers
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}\"'
W przypadku platform innych niż system Windows dodaj opcję
-f speedscope
, aby zmienić format wyjściowego pliku śledzenia naspeedscope
.W poniższej tabeli zdefiniowano słowo kluczowe:
Słowo kluczowe opis 1 Rejestruje zdarzenia meta dotyczące obiektu LoggingEventSource
. Nie rejestruje zdarzeń zILogger
.2 Włącza zdarzenie Message
po wywołaniu metodyILogger.Log()
. Dostarcza informacje w sposób programowy (nie sformatowany).100 Włącza zdarzenie FormatMessage
po wywołaniu metodyILogger.Log()
. Dostarcza sformatowaną wersję ciągu informacji.8 Włącza zdarzenie MessageJson
po wywołaniu metodyILogger.Log()
. Dostarcza 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ą:
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 zostaną określone żadne elementy
FilterSpecs
, implementacjaEventSourceLogger
podejmie próbę przekonwertowania poziomu dostawcy na poziom kategorii i zastosuje to 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
zostaną określone, każda kategoria, która znajduje się na liście, będzie używać zakodowanego tam poziomu kategorii, a wszystkie inne kategorie zostaną odfiltrowane.W poniższych przykładach przyjęto następujące założenia:
- Aplikacja jest uruchomiona i wywołuje metodę
logger.LogDebug("12345")
. - Identyfikator procesu (PID) został ustawiony za pośrednictwem polecenia
set PID=12345
, gdzie12345
jest rzeczywistym identyfikatorem PID.
Spójrzmy na następujące polecenie:
dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
Poprzednie polecenie:
- Przechwytuje komunikaty debugowania.
- Nie stosuje elementów
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\"
Poprzednie polecenie:
- Nie przechwytuje komunikatów debugowania, ponieważ poziom kategorii 5 ma wartość
Critical
. - Dostarcza elementy
FilterSpecs
.
Następujące polecenie przechwytuje komunikaty debugowania, ponieważ poziom kategorii 1 określa element
Debug
.dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
Następujące polecenie przechwytuje komunikaty debugowania, ponieważ kategoria określa element
Debug
.dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
Wpisy
FilterSpecs
dla{Logger Category}
i{Category Level}
reprezentują dodatkowe warunki filtrowania dzienników. Oddziel wpisyFilterSpecs
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\"
Powyższe polecenie aktywuje:
- Rejestrator źródła zdarzenia w celu utworzenia sformatowanych ciągów (
4
) dla błędów (2
). - Rejestrowanie
Microsoft.AspNetCore.Hosting
na poziomie rejestrowaniaInformational
(4
).
Zatrzymaj
dotnet-trace
narzędzia, naciskając Enter lub Ctrl+C.Ślad jest zapisywany z nazwą
trace.nettrace
w folderze, w którym jest wykonywane poleceniedotnet-trace
.Otwórz ślad za pomocą narzędzia Perfview. Otwórz plik
trace.nettrace
i zapoznaj się ze zdarzeniami śledzenia.
Jeśli aplikacja nie skompiluje hosta za pomocą metody WebApplication.CreateBuilder, dodaj dostawcę źródła zdarzeń do konfiguracji rejestrowania aplikacji.
Aby uzyskać więcej informacji, zobacz:
- Ślad dla narzędzia do analizy wydajności (
dotnet-trace
) (dokumentacja platformy.NET Core) - Ślad dla narzędzia do analizy wydajności (
dotnet-trace
) (dokumentacja repozytorium GitHub narzędzia dotnet/diagnostyki) - LoggingEventSource
- EventLevel
- Perfview: przydatne do wyświetlania śladów źródła zdarzeń.
Perfview
Przy użyciu narzędzia PerfView można zbierać i wyświetlać dzienniki. Istnieją inne narzędzia do wyświetlania dzienników ETW, ale narzędzie PerfView zapewnia najlepsze środowisko do pracy ze zdarzeniami ETW emitowanymi przez platformę ASP.NET Core.
Aby skonfigurować narzędzie PerfView do zbierania zdarzeń rejestrowanych przez tego dostawcę, dodaj ciąg *Microsoft-Extensions-Logging
do listy Dodatkowi dostawcy. Nie zapomnij o znaku *
na początku ciągu.
Windows EventLog
Dostawca EventLog
wysyła dane wyjściowe dziennika do dziennika zdarzeń systemu Windows. W przeciwieństwie do innych dostawców dostawca EventLog
nie dziedziczy domyślnych ustawień innych niż dostawcy. Jeśli ustawienia dziennika EventLog
nie są określone, przyjmowana jest wartość domyślna LogLevel.Warning.
Aby rejestrować zdarzenia o poziomie niższym niż LogLevel.Warning należy jawnie ustawić poziom dziennika. W poniższym przykładzie domyślny poziom dziennika dla dziennika zdarzeń jest ustawiony na LogLevel.Information:
"Logging": {
"EventLog": {
"LogLevel": {
"Default": "Information"
}
}
}
Przeciążenia metody AddEventLog mogą przekazywać klasę EventLogSettings. Jeśli wartość wynosi null
lub nie jest określona, używane są następujące ustawienia domyślne:
LogName
: „Application”SourceName
: „.NET Runtime”MachineName
: używana jest nazwa komputera lokalnego.
Poniższy kod zmienia wartość parametru SourceName
z wartości domyślnej ".NET Runtime"
na wartość MyLogs
:
var builder = WebApplication.CreateBuilder();
builder.Logging.AddEventLog(eventLogSettings =>
{
eventLogSettings.SourceName = "MyLogs";
});
Azure App Service
Pakiet dostawcy Microsoft.Extensions.Logging.AzureAppServices
zapisuje dzienniki w plikach tekstowych w systemie plików aplikacji usługi 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ć tego dostawcy, należy dodać pakiet dostawcy do projektu.
Aby skonfigurować ustawienia dostawcy, użyj klas 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 usłudze Azure App Service aplikacja używa ustawień z sekcji Dzienniki usługi App Service na stronie usługi App Service w witrynie Azure Portal. Po zaktualizowaniu następujących ustawień zmiany są stosowane natychmiast bez konieczności ponownego uruchamiania lub ponownego wdrażania aplikacji.
- Rejestrowanie aplikacji (system plików)
- Rejestrowanie aplikacji (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 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 jest uruchomiony 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:
- serwera aplikacji
- serwera internetowego
- śledzenia żądań zakończonego niepowodzeniem
Aby skonfigurować przesyłanie strumieniowe dzienników platformy Azure:
- Przejdź do strony Dzienniki usługi App Service na stronie portalu aplikacji.
- Dla opcji Rejestrowanie aplikacji (system plików) ustaw wartość Włączone.
- Wybierz poziom dziennika. To ustawienie dotyczy tylko przesyłania strumieniowego dzienników platformy Azure.
Przejdź do strony Strumień dziennika, aby wyświetlić dzienniki. Komunikaty są rejestrowane za pomocą interfejsu ILogger
.
Azure Application Insights
Pakiet dostawcy Microsoft.Extensions.Logging.ApplicationInsights
zapisuje dzienniki w usłudze Azure Application 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 pakietu, który zapewnia wszystkie dostępne dane telemetryczne dla platformy ASP.NET Core. Jeśli używasz tego pakietu, nie musisz instalować pakietu dostawcy.
Pakiet Microsoft.ApplicationInsights.Web
jest przeznaczony dla platformy ASP.NET 4.x, a nie ASP.NET Core.
Aby uzyskać więcej informacji, zobacz następujące zasoby:
- Omówienie usługi Application Insights
- Usługa Application Insights dla aplikacji platformy ASP.NET Core: zacznij tutaj, jeśli chcesz zaimplementować pełny zakres danych telemetrycznych usługi Application Insights wraz z rejestrowaniem.
- Dostawca ApplicationInsightsLoggerProvider dla dzienników ILogger platformy .NET Core: zacznij tutaj, jeśli chcesz zaimplementować dostawcę rejestrowania bez pozostałej części telemetrii usługi Application Insights.
- Adaptery rejestrowania usługi Application Insights
- Interakcyjny samouczek Instalowanie, konfigurowanie i inicjowanie zestawu SDK usługi Application Insights.
Zewnętrzni dostawcy rejestrowania
Struktury rejestrowania innych firm, które współpracują z platformą ASP.NET Core:
- elmah.io (repozytorium GitHub)
- Gelf (repozytorium GitHub)
- JSNLog (repozytorium GitHub)
- KissLog.net (repozytorium GitHub)
- Log4Net (repozytorium GitHub)
- NLog (repozytorium GitHub)
- PLogger (repozytorium GitHub)
- Sentry (repozytorium GitHub)
- Serilog (repozytorium GitHub)
- Stackdriver (repozytorium GitHub)
Niektóre struktury innych firm mogą wykonywać rejestrowanie semantyczne, znane również jako rejestrowanie strukturalne.
Korzystanie ze struktury innej firmy jest podobne do korzystania z jednego z wbudowanych dostawców:
- Dodaj pakiet NuGet do projektu.
- Wywołaj metodę rozszerzenia
ILoggerFactory
dostarczaną przez strukturę rejestrowania.
Aby uzyskać więcej informacji, zapoznaj się z dokumentacją każdego z dostawców. Zewnętrzni dostawcy rejestrowania nie są obsługiwani przez firmę Microsoft.
Brak metod rejestratora asynchronicznego
Rejestrowanie powinno być tak szybkie, że nie jest warte kosztu wydajności kodu asynchronicznego. Jeśli magazyn danych rejestrowania działa wolno, nie zapisuj do niego bezpośrednio. Rozważ zapisywanie komunikatów dziennika najpierw w szybkim magazynie, a później przenoszenie ich do powolnego magazynu. Na przykład w przypadku rejestrowania w programie SQL Server nie rób tego bezpośrednio w metodzie Log
, ponieważ metody Log
są synchroniczne. Zamiast tego synchronicznie dodaj komunikaty dziennika do kolejki w pamięci, a następnie za pomocą procesu roboczego w tle ściągaj komunikaty z kolejki, aby wykonać asynchroniczne zadanie wypychania danych do programu SQL Server. Aby uzyskać więcej informacji, zobacz Wskazówki dotyczące rejestrowania w kolejce komunikatów dla powolnych magazynów danych (dotnet/AspNetCore.Docs #11801).
Zmienianie poziomów dziennika w uruchomionej aplikacji
Interfejs API rejestrowania nie obejmuje scenariusza zmieniania poziomów dziennika podczas działania aplikacji. Jednak niektórzy dostawcy konfiguracji mogą ponownie ładować konfigurację, która jest natychmiast stosowna w konfiguracji 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ć metodę IConfigurationRoot.Reload w celu zaktualizowania konfiguracji rejestrowania aplikacji.
ILogger i ILoggerFactory
Interfejsy i implementacje ILogger<TCategoryName> i ILoggerFactory są uwzględnione w zestawie SDK platformy .NET Core. Są one również dostępne w następujących pakietach NuGet:
- Interfejsy znajdują się w pakiecie
Microsoft.Extensions.Logging.Abstractions
. - Domyślne implementacje znajdują się w pakiecie
Microsoft.Extensions.Logging
.
Stosowanie reguł filtru dziennika w kodzie
Preferowanym podejściem do ustawiania reguł filtrowania dzienników jest użycie 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 dziennika Debug
. Filtr jest stosowany do wszystkich dostawców, ponieważ nie skonfigurowano żadnego konkretnego dostawcy.
AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information)
określa następujące elementy:
- Dostawca rejestrowania
Debug
. - Poziom dziennika
Information
i wyższy. - Wszystkie kategorie rozpoczynające się od ciągu
"Microsoft"
.
Automatyczne rejestrowanie zakresu za pomocą SpanId
, TraceId
, ParentId
, Baggage
i Tags
.
Biblioteki rejestrowania niejawnie tworzą obiekt zakresu z elementami SpanId
, TraceId
, ParentId
, Baggage
i Tags
. To zachowanie jest konfigurowane za pomocą właściwości ActivityTrackingOptions.
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddSimpleConsole(options =>
{
options.IncludeScopes = true;
});
builder.Logging.Configure(options =>
{
options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
| ActivityTrackingOptions.TraceId
| ActivityTrackingOptions.ParentId
| ActivityTrackingOptions.Baggage
| ActivityTrackingOptions.Tags;
});
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
Jeśli nagłówek żądania HTTP traceparent
jest ustawiony, ParentId
w zakresie dziennika pokazuje parent-id
W3C z nagłówka ruchu przychodzącego traceparent
, a SpanId
w zakresie dziennika pokazuje zaktualizowany parent-id
dla następnego kroku/zakresu ruchu wychodzącego. Aby uzyskać więcej informacji, zobacz Mutowanie pola traceparent.
Tworzenie rejestratora niestandardowego
Aby utworzyć niestandardowy rejestrator, zobacz Implementowanie niestandardowego dostawcy rejestrowania na platformie .NET.
Dodatkowe zasoby
- Zwiększanie wydajności rejestrowania za pomocą generatorów źródłowych
- Za
[LogProperties]
i nowy generator źródeł rejestrowania telemetrii - Źródło Microsoft.Extensions.Logging w witrynie GitHub
- Wyświetl lub pobierz przykładowy kod (jak pobrać).
- Rejestrowanie o wysokiej wydajności
- Błędy rejestrowania powinny być tworzone w repozytorium GitHub
dotnet/runtime
. - Rejestrowanie Blazor platformy ASP.NET Core
Autorzy: Kirk Larkin, Juergen Gutsch i Rick Anderson
W tym temacie opisano rejestrowanie na platformie .NET w odniesieniu do 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 aplikacjach Blazor, zobacz Rejestrowanie aplikacji Blazor platformy ASP.NET Core.
Wyświetl lub pobierz przykładowy kod (jak pobrać).
Dostawcy rejestrowania
Dostawcy rejestrowania przechowują dzienniki, z wyjątkiem dostawcy Console
, który wyświetla dzienniki. Na przykład dostawca usługi Azure Application Insights przechowuje dzienniki w usłudze Azure Application Insights. Można włączyć wielu dostawców.
Domyślne szablony aplikacji internetowych platformy ASP.NET Core:
- używają hosta ogólnego;
- Wywołaj metodę CreateDefaultBuilder, która dodaje następujących dostawców rejestrowania:
- Konsola
- Debug
- EventSource
- EventLog: tylko system Windows
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 internetowych platformy ASP.NET Core. W kilku następnych sekcjach przedstawiono przykłady oparte na szablonach aplikacji internetowych platformy ASP.NET Core, które korzystają z hosta ogólnego. Aplikacje konsolowe bez hosta zostały omówione w dalszej części tego dokumentu.
Aby zastąpić domyślny zestaw dostawców rejestrowania dodany przez Host.CreateDefaultBuilder
, wywołaj polecenie ClearProviders
i dodaj wymaganych dostawców rejestrowania. Na przykład następujący kod:
- wywołuje klasę ClearProviders w celu usunięcia wszystkich wystąpień ILoggerProvider z konstruktora,
- dodaje dostawcę rejestrowania Console.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
Aby uzyskać informacje o dodatkowych dostawcach, zobacz:
Tworzenie dzienników
Aby utworzyć dzienniki, użyj obiektu ILogger<TCategoryName> z wstrzykiwania zależności (DI).
Poniższy przykład:
- Tworzy rejestrator,
ILogger<AboutModel>
, który używa kategorii dziennika w pełni kwalifikowanej nazwy typuAboutModel
. Kategoria dziennika to ciąg skojarzony z każdym dziennikiem. - Wywołuje metodę LogInformation w celu rejestrowania na poziomie
Information
. 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 omówione bardziej szczegółowo w dalszej części tego dokumentu.
Aby uzyskać informacje na temat struktury Blazor, zobacz Rejestrowanie aplikacji Blazor platformy ASP.NET Core.
Tworzenie dzienników w plikach Main i Startup pokazuje, jak utworzyć dzienniki w plikach Main
i Startup
.
Konfigurowanie rejestrowania
Konfiguracja rejestrowania jest często dostarczana za pomocą sekcji Logging
plików appsettings.{Environment}.json
. Poniższy plik appsettings.Development.json
jest generowany przez szablony aplikacji internetowych platformy ASP.NET Core:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
W powyższym pliku JSON:
- Określono kategorie
"Default"
,"Microsoft"
i"Microsoft.Hosting.Lifetime"
. - Kategoria
"Microsoft"
dotyczy wszystkich kategorii rozpoczynających się ciągiem"Microsoft"
. To ustawienie na przykład dotyczy kategorii"Microsoft.AspNetCore.Routing.EndpointMiddleware"
. - Kategoria
"Microsoft"
dokonuje rejestracji na poziomie dziennikaWarning
i wyższym. - Kategoria
"Microsoft.Hosting.Lifetime"
jest bardziej określona niż kategoria"Microsoft"
, więc kategoria"Microsoft.Hosting.Lifetime"
rejestruje na poziomie dziennika „Informacje” i wyższym. - Nie określono konkretnego dostawcy dziennika, więc właściwość
LogLevel
dotyczy wszystkich włączonych dostawców rejestrowania z wyjątkiem dostawcy Windows EventLog.
Właściwość Logging
może mieć wyliczenie LogLevel i właściwości dostawcy dziennika. Wyliczenie LogLevel
określa minimalny poziom rejestrowania dla wybranych kategorii. W poprzednim pliku JSON określono poziomy dziennika Information
i Warning
. Wyliczenie LogLevel
określa ważność dziennika i ma wartość z zakresu od 0 do 6:
Trace
= 0, Debug
= 1, Information
= 2, Warning
= 3, Error
= 4, Critical
= 5 i None
= 6.
Gdy wyliczenie LogLevel
jest określone, rejestrowanie jest włączone dla komunikatów na tym i wyższym poziomie. W poprzednim pliku JSON kategoria Default
jest rejestrowana na poziomie Information
i wyższym. Rejestrowane są na przykład komunikaty na poziomach Information
, Warning
, Error
i Critical
. Jeśli wyliczenie LogLevel
nie zostanie określone, dla rejestrowania stosowany jest poziom domyślny Information
. Aby uzyskać więcej informacji, zobacz Poziomy dziennika.
Właściwość dostawcy może określać właściwość LogLevel
. Właściwość LogLevel
w sekcji dostawcy określa poziomy, które mają być rejestrowane dla tego dostawcy, i zastępuje ustawienia dziennika bez określonego dostawcy. Rozważ użycie następującego pliku appsettings.json
:
{
"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ępują ustawienia w Logging.LogLevel
. W powyższym pliku JSON domyślny poziom dziennika dostawcy Debug
jest ustawiony na wartość Information
:
Logging:Debug:LogLevel:Default:Information
Poprzednie ustawienie określa poziom dziennika Information
dla każdej kategorii Logging:Debug:
z wyjątkiem kategorii Microsoft.Hosting
. Gdy jest określona konkretna kategoria, zastępuje ona kategorię domyślną. W powyższym pliku JSON kategorie "Microsoft.Hosting"
i "Default"
w sekcji Logging:Debug:LogLevel
zastępują ustawienia w sekcji Logging:LogLevel
Minimalny poziom dziennika można określić dla:
- określonych dostawców, na przykład
Logging:EventSource:LogLevel:Default:Information
- określonych kategorii, na przykład:
Logging:LogLevel:Microsoft:Warning
- wszystkich dostawców i wszystkich kategorii:
Logging:LogLevel:Default:Warning
Wszystkie dzienniki poniżej minimalnego poziomu nie są:
- przekazywane do dostawcy,
- rejestrowane ani wyświetlane.
Aby pominąć wszystkie dzienniki, określ wartość LogLevel.None. Poziom LogLevel.None
ma wartość 6, która jest wyższa niż w przypadku poziomu LogLevel.Critical
(5).
Jeśli dostawca obsługuje zakresy dzienników, właściwość IncludeScopes
wskazuje, czy są one włączone. Aby uzyskać więcej informacji, zobacz zakresy dzienników
W poniższym pliku appsettings.json
wszyscy dostawcy 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 powyższym przykładzie:
- Kategorie i poziomy nie mają sugerowanych wartości. Przykład ma na celu pokazanie wszystkich dostawców domyślnych.
- Ustawienia w
Logging.{providername}.LogLevel
zastępują ustawienia wLogging.LogLevel
. Na przykład poziom w sekcjiDebug.LogLevel.Default
zastępuje poziom w sekcjiLogLevel.Default
. - Dla każdego dostawcy domyślnego użyto aliasu. Każdy dostawca ma zdefiniowany alias, którego można używać w konfiguracji zamiast w pełni kwalifikowanej nazwy typu. Wbudowane aliasy dostawców to:
- Konsola
- Debugowanie
- EventSource
- EventLog
- AzureAppServicesFile
- AzureAppServicesBlob
- ApplicationInsights
Ustawianie poziomu dziennika za pośrednictwem wiersza polecenia, zmiennych środowiskowych i innej konfiguracji
Poziom dziennika można ustawić za pośrednictwem dowolnego dostawcy konfiguracji.
Separator :
nie współdziała z kluczami hierarchicznymi zmiennych środowiskowych na wszystkich platformach. Na przykład separator nie jest obsługiwany przez powłokę :
Bash. Podwójne podkreślenie, __
, to:
- Jest obsługiwany przez wszystkie platformy.
- Automatycznie zamieniono dwukropek na
:
.
Poniższe polecenia:
- Ustawiają klucz środowiska
Logging:LogLevel:Microsoft
na wartośćInformation
w systemie Windows. - Testują ustawienia w przypadku używania aplikacji utworzonej przy użyciu szablonów aplikacji internetowych platformy ASP.NET Core. Polecenie
dotnet run
należy uruchomić w katalogu projektu po użyciu poleceniaset
.
set Logging__LogLevel__Microsoft=Information
dotnet run
Poprzednie ustawienia środowiska:
- są ustawiane tylko w procesach uruchamianych z poziomu okna poleceń, w którym zostały ustawione;
- nie są odczytywane przez przeglądarki uruchamiane za pomocą programu Visual Studio.
Poniższe polecenie setx również ustawia klucz środowiska i wartość w systemie Windows. W przeciwieństwie do polecenia set
, ustawienia polecenia setx
są trwałe. Przełącznik /M
ustawia zmienną w środowisku systemowym. Jeśli przełącznik /M
nie jest używany, ustawiana jest zmienna środowiskowa użytkownika.
setx Logging__LogLevel__Microsoft Information /M
Rozważ użycie następującego pliku appsettings.json
:
"Logging": {
"Console": {
"LogLevel": {
"Microsoft.Hosting.Lifetime": "Trace"
}
}
}
Poniższe polecenie ustawia powyższą konfigurację w środowisku:
setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M
W usłudze Azure App Service wybierz pozycję Nowe ustawienie aplikacji na stronie Ustawienia > Konfiguracja. Ustawienia aplikacji usługi Azure App Service są:
- szyfrowane podczas przechowywania i przesyłane za pośrednictwem zaszyfrowanego kanału,
- Uwidaczniane 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 platformy 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, usługi Azure App Configuration, innych formatów plików i nie tylko, zobacz Konfiguracja na platformie ASP.NET Core.
Jak są stosowane reguły filtrowania
Po utworzeniu obiektu ILogger<TCategoryName> obiekt ILoggerFactory wybiera jedną regułę dla każdego dostawcy, która ma być stosowana do tego rejestratora. Wszystkie komunikaty zapisywane przez wystąpienie ILogger
są filtrowane na podstawie wybranych reguł. Z dostępnych reguł wybierana jest najbardziej konkretna reguła dla każdej pary dostawcy i kategorii.
Następujący algorytm jest używany dla każdego dostawcy podczas tworzenia obiektu ILogger
dla danej kategorii:
- Wybierz wszystkie reguły zgodne z dostawcą lub jego aliasem. Jeśli nie zostanie znalezione żadne dopasowanie, wybierz wszystkie reguły z pustym dostawcą.
- Z wyników poprzedniego kroku wybierz reguły z najdłuższym pasującym prefiksem kategorii. Jeśli nie zostanie znalezione żadne dopasowanie, wybierz wszystkie reguły, które nie określają kategorii.
- Jeśli wybrano wiele reguł, użyj ostatniej.
- Jeśli nie wybrano żadnych reguł, użyj
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 danych wyjściowych debugowania podczas debugowania.
- W oknie serwera internetowego platformy ASP.NET Core.
- W oknie konsoli w przypadku uruchomieniu aplikacji za pomocą polecenia
dotnet run
.
Dzienniki rozpoczynające się od kategorii „Microsoft” pochodzą z kodu platformy ASP.NET Core. Platforma ASP.NET Core i kod aplikacji używają tego samego interfejsu API rejestrowania i tych samych dostawców.
Kategoria dziennika
Po utworzeniu obiektu ILogger
jest określana kategoria. Ta kategoria jest uwzględniania w każdym komunikacie dziennika utworzonym przez to wystąpienie ILogger
. Ciąg kategorii jest dowolny, ale przyjęto konwencję używania nazwy klasy. Na przykład w kontrolerze nazwa może mieć postać "TodoApi.Controllers.TodoController"
. Aplikacje internetowe platformy ASP.NET Core używają ILogger<T>
, aby automatycznie pobierać wystąpienie ILogger
, które używa w pełni kwalifikowanej nazwy typu T
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("TodoApi.Pages.ContactModel.MyCategory");
}
public void OnGet()
{
_logger.LogInformation("GET Pages.ContactModel called.");
}
Wywoływanie metody CreateLogger
ze stałą nazwą może być przydatne w przypadku użycia w wielu metodach, dzięki czemu zdarzenia mogą być zorganizowane według kategorii.
ILogger<T>
jest równoważne wywołaniu metody CreateLogger
z w pełni kwalifikowaną nazwą typu T
.
Poziom dziennika
Poniższa tabela zawiera wartości LogLevel, wygodną metodę rozszerzenia Log{LogLevel}
i sugerowane użycie:
PoziomRejestrowania | Wartość | Metoda | opis |
---|---|---|---|
Śledzenie | 0 | LogTrace | Obejmuje najbardziej szczegółowe komunikaty. Te komunikaty mogą zawierać poufne dane aplikacji. Komunikaty są domyślnie wyłączone i nie powinny być włączane w środowisku produkcyjnym. |
Debug | 1 | LogDebug | Na potrzeby debugowania i programowania. Należy zachować ostrożność w środowisku produkcyjnym ze względu na dużą pojemność. |
Informacje | 2 | LogInformation | Śledzi ogólny przepływ aplikacji. Może mieć wartość długoterminową. |
Ostrzeżenie | 3 | LogWarning | Na potrzeby nietypowych lub nieoczekiwanych zdarzeń. Zazwyczaj obejmuje błędy lub warunki, które nie powodują awarii aplikacji. |
Błąd | 100 | LogError | Na potrzeby błędów i wyjątków, których nie można obsłużyć. Te komunikaty wskazują na błąd w bieżącej operacji lub żądaniu, a nie awarię całej aplikacji. |
Krytyczne | 5 | LogCritical | Na potrzeby 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 powyższej tabeli obiekty LogLevel
uporządkowano w kolejności od najniższej do najwyższej ważności.
Pierwszy parametr metody Log, LogLevel, wskazuje ważność dziennika. Zamiast wywoływać metodę Log(LogLevel, ...)
, większość deweloperów wywołuje metody rozszerzenia Log{LogLevel}. Metody rozszerzenia Log{LogLevel}
wywołają metodę Log i określają wartość elementu LogLevel. Na przykład dwa poniższe wywołania rejestrowania działają tak samo 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świetlany w sekcji Identyfikator zdarzenia dziennika.
Metody MyDisplayRouteInfo i ToCtxString są dostarczane przez pakiet NuGet Rick.Docs.Samples.RouteInfo. Metody te wyświetlają informacje o trasie Controller
i Razor Page
.
Poniższy kod tworzy dzienniki Information
i Warning
:
[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 powyższym kodzie pierwszym parametrem metody Log{LogLevel}
, MyLogEvents.GetItem
, jest identyfikator zdarzenia dziennika. Drugi parametr to szablon komunikatu z symbolami zastępczymi dla wartości argumentów dostarczanych przez pozostałe parametry metody. Parametry metody zostały omówione w sekcji dotyczące szablonu komunikatu w dalszej części tego dokumentu.
Wywołaj odpowiednią metodę Log{LogLevel}
, aby kontrolować ilość danych wyjściowych dziennika zapisywanych na określonym nośniku magazynu. Na przykład:
- W środowisku produkcyjnym:
- Rejestrowanie na poziomach
Trace
iInformation
generuje dużą ilość szczegółowych komunikatów dziennika. Aby kontrolować koszty i nie przekraczać limitów magazynowania danych, rejestruj komunikaty dziennika na poziomieTrace
iInformation
w magazynie danych o dużej pojemności i niskiej cenie. Rozważ ograniczenie dziennikówTrace
iInformation
do określonych kategorii. - Rejestrowanie na poziomach od
Warning
doCritical
powinno generować kilka komunikatów dziennika.- Koszty i limity magazynu zwykle nie są tu problemem.
- Niewielka liczba dzienników zapewnia większą swobodę wyboru magazynu danych.
- Rejestrowanie na poziomach
- W programowania:
- Ustaw wartość
Warning
. - Dodaj komunikaty
Trace
lubInformation
podczas rozwiązywania problemów. Aby ograniczyć ilość danych wyjściowych, poziomTrace
lubInformation
ustawiaj tylko dla kategorii, które są badane.
- Ustaw wartość
Platforma ASP.NET Core zapisuje dzienniki dla zdarzeń struktury. Rozważmy na przykład dane wyjściowe dziennika dla:
- Aplikacji Razor Pages utworzonej przy użyciu szablonów platformy ASP.NET Core.
- Dla rejestrowania ustawiono wartość
Logging:Console:LogLevel:Microsoft:Information
- Nawigacja do strony Privacy:
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
Poniższy plik JSON ustawia Logging:Console:LogLevel:Microsoft:Information
:
{
"Logging": { // Default, all providers.
"LogLevel": {
"Microsoft": "Warning"
},
"Console": { // Console provider.
"LogLevel": {
"Microsoft": "Information"
}
}
}
}
Identyfikator zdarzenia dziennika
Każdy dziennik może określać identyfikator zdarzenia. Przykładowa aplikacja używa klasy MyLogEvents
, aby definiować identyfikatory 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 wcale. Dostawca debugowania nie pokazuje 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 po identyfikatorze.
Szablon komunikatu dziennika
Każdy interfejs API dziennika używa szablonu komunikatu. Szablon komunikatu może zawierać symbole zastępcze, dla których są podawane argumenty. Dla symboli zastępczych należy używać nazw, 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);
}
To, które parametry są używane w celu podania wartości symboli zastępczych w komunikatach dziennika jest określane przez kolejność parametrów, a nie nazwy ich symboli zastępczych. W poniższym kodzie nazwy parametrów w symbolach zastępczych szablonu komunikatu są niezgodne z kolejnością:
var apples = 1;
var pears = 2;
var bananas = 3;
_logger.LogInformation("Parameters: {pears}, {bananas}, {apples}", apples, pears, bananas);
Parametry są jednak przypisywane do symboli zastępczych w kolejności: apples
, pears
, bananas
. Komunikat dziennika odzwierciedla kolejność parametrów:
Parameters: 1, 2, 3
Takie podejście umożliwia dostawcom rejestrowania zaimplementowanie rejestrowania semantycznego lub strukturalnego. 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ć właściwości
ID
iRequestTime
. - Tabele z właściwościami upraszczają wykonywanie zapytań dotyczących zarejestrowanych danych. Na przykład zapytanie może znaleźć wszystkie dzienniki w określonym zakresie
RequestTime
bez konieczności analizowania czasu z komunikatu tekstowego.
Wyjątki dziennikó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();
}
Metody MyDisplayRouteInfo i ToCtxString są dostarczane przez pakiet NuGet Rick.Docs.Samples.RouteInfo. Metody te wyświetlają informacje o trasie Controller
i Razor Page
.
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ą:
- Utworzona przy użyciu szablonów aplikacji internetowej platformy ASP.NET.
- Pliki
appsettings.json
iappsettings.Development.json
zostały usunięte lub zmienione.
W przypadku poprzedniej konfiguracji przejście do strony prywatności lub strony głównej powoduje wygenerowanie wielu komunikatów Trace
, Debug
i Information
z ciągiem Microsoft
w nazwie kategorii.
Poniższy kod ustawia domyślny poziom dziennika, kiedy 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ślane w konfiguracji, a nie w kodzie.
Funkcja filtru
Funkcja filtru jest wywoływana dla wszystkich dostawców i kategorii, dla których nie przypisano reguł za pomocą konfiguracji lub kodu:
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 parametr Controller
lub Microsoft
, a poziom dziennika ma wartość Information
lub wyższą.
Ogólnie rzecz biorąc, poziomy dziennika powinny być określane w konfiguracji, a nie w kodzie.
ASP.NET Core i EF Core kategorie
Poniższa tabela zawiera niektóre kategorie używane przez platformy ASP.NET Core i Entity Framework Core wraz z uwagami dotyczącymi dzienników:
Kategoria | Uwagi |
---|---|
Microsoft.AspNetCore | Ogólna diagnostyka platformy ASP.NET Core. |
Microsoft.AspNetCore.DataProtection | Które klucze były rozważane, znalezione i użyte. |
Microsoft.AspNetCore.HostFiltering | Dozwolone hosty. |
Microsoft.AspNetCore.Hosting | Jak długo trwało wykonywanie żądań HTTP oraz czas ich rozpoczęcia. Które zestawy startowe hostingu zostały załadowane. |
Microsoft.AspNetCore.Mvc | Diagnostyka MVC i Razor. Powiązanie modelu, wykonywanie filtru, kompilacja widoku, wybór akcji. |
Microsoft.AspNetCore.Routing | Kierowanie zgodnych informacji. |
Microsoft.AspNetCore.Server | Odpowiedzi dotyczące uruchomienia i zatrzymania połączenia oraz utrzymania aktywności. Informacje o certyfikacie HTTPS. |
Microsoft.AspNetCore.StaticFiles | Obsłużone pliki. |
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, w pliku appsettings.Development.json
wprowadź 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:
- jest typem IDisposable zwracanym przez metodę BeginScope,
- trwa do momentu usunięcia.
Następujący dostawcy obsługują zakresy:
Użyj zakresu, opakowując wywołania rejestratora za pomocą bloku using
:
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
TodoItem todoItem;
var transactionId = Guid.NewGuid().ToString();
using (_logger.BeginScope(new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("TransactionId", transactionId),
}))
{
_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
Platforma 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 w ramach struktury udostępnionej. Należy ich zainstalować jako dodatkowe pakiety nuget.
Platforma ASP.NET Core nie zawiera dostawcy rejestrowania na potrzeby zapisywania dzienników w plikach. Aby zapisywać dzienniki w plikach z aplikacji platformy ASP.NET Core, rozważ użycie dostawcy rejestrowania innej firmy.
Aby uzyskać informacje na temat właściwości stdout
i rejestrowania debugowania przy użyciu modułu ASP.NET Core Module, zobacz Rozwiązywanie problemów z platformą ASP.NET Core w usługach Azure App Service oraz IIS, a także Moduł ASP.NET Core Module (ANCM) dla usług IIS.
Konsola
Dostawca Console
rejestruje dane wyjściowe w konsoli. Aby uzyskać więcej informacji na temat wyświetlania dzienników dostawcy Console
w środowisku programistycznym, zobacz Rejestrowanie danych wyjściowych z polecenia dotnet run i programu Visual Studio.
Debugowanie
Dostawca Debug
zapisuje dane wyjściowe dziennika przy użyciu klasy System.Diagnostics.Debug. Wywołania metody System.Diagnostics.Debug.WriteLine
zapisują do dostawcy Debug
.
W systemie Linux lokalizacja dziennika dostawcy Debug
jest zależna od dystrybucji i może być jedną z następujących:
- /var/log/message
- /var/log/syslog
Źródło zdarzenia
Dostawca EventSource
zapisuje w międzyplatformowym źródle zdarzeń o nazwie Microsoft-Extensions-Logging
. W systemie Windows dostawca używa funkcji ETW.
Narzędzia dotnet trace
Narzędzie dotnet-trace jest międzyplatformowym globalnym narzędziem interfejsu wiersza polecenia, które umożliwia zbieranie śladów platformy .NET Core uruchomionego procesu. Narzędzie to zbiera dane dostawcy Microsoft.Extensions.Logging.EventSource przy użyciu klasy LoggingEventSource.
Aby uzyskać instrukcje instalacji, zobacz dotnet-trace.
Użyj narzędzi dotnet trace, aby zebrać ślad z aplikacji:
Uruchom aplikację za pomocą polecenia
dotnet run
.Określ identyfikator procesu (PID) aplikacji platformy .NET Core:
dotnet trace ps
Znajdź identyfikator PID dla procesu, który ma taką samą nazwę, jak zestaw aplikacji.
Wykonaj polecenie
dotnet trace
.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ąć wartość
--providers
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}\"'
W przypadku platform innych niż system Windows dodaj opcję
-f speedscope
, aby zmienić format wyjściowego pliku śledzenia naspeedscope
.W poniższej tabeli zdefiniowano słowo kluczowe:
Słowo kluczowe opis 1 Rejestruje zdarzenia meta dotyczące obiektu LoggingEventSource
. Nie rejestruje zdarzeń zILogger
.2 Włącza zdarzenie Message
po wywołaniu metodyILogger.Log()
. Dostarcza informacje w sposób programowy (nie sformatowany).100 Włącza zdarzenie FormatMessage
po wywołaniu metodyILogger.Log()
. Dostarcza sformatowaną wersję ciągu informacji.8 Włącza zdarzenie MessageJson
po wywołaniu metodyILogger.Log()
. Dostarcza 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ą:
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 zostaną określone żadne elementy
FilterSpecs
, implementacjaEventSourceLogger
podejmie próbę przekonwertowania poziomu dostawcy na poziom kategorii i zastosuje to 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
zostaną określone, każda kategoria, która znajduje się na liście, będzie używać zakodowanego tam poziomu kategorii, a wszystkie inne kategorie zostaną odfiltrowane.W poniższych przykładach przyjęto następujące założenia:
- Aplikacja jest uruchomiona i wywołuje metodę
logger.LogDebug("12345")
. - Identyfikator procesu (PID) został ustawiony za pośrednictwem polecenia
set PID=12345
, gdzie12345
jest rzeczywistym identyfikatorem PID.
Spójrzmy na następujące polecenie:
dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
Poprzednie polecenie:
- Przechwytuje komunikaty debugowania.
- Nie stosuje elementów
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\"
Poprzednie polecenie:
- Nie przechwytuje komunikatów debugowania, ponieważ poziom kategorii 5 ma wartość
Critical
. - Dostarcza elementy
FilterSpecs
.
Następujące polecenie przechwytuje komunikaty debugowania, ponieważ poziom kategorii 1 określa element
Debug
.dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
Następujące polecenie przechwytuje komunikaty debugowania, ponieważ kategoria określa element
Debug
.dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
Wpisy
FilterSpecs
dla{Logger Category}
i{Category Level}
reprezentują dodatkowe warunki filtrowania dzienników. Oddziel wpisyFilterSpecs
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\"
Powyższe polecenie aktywuje:
- Rejestrator źródła zdarzenia w celu utworzenia sformatowanych ciągów (
4
) dla błędów (2
). - Rejestrowanie
Microsoft.AspNetCore.Hosting
na poziomie rejestrowaniaInformational
(4
).
Zatrzymaj narzędzie dotnet trace, naciskając klawisz Enter lub klawisze Ctrl+C.
Ślad jest zapisywany z nazwą trace.nettrace w folderze, w którym jest wykonywane polecenie
dotnet trace
.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ą metody CreateDefaultBuilder
, dodaj dostawcę źródła zdarzeń do konfiguracji rejestrowania aplikacji.
Aby uzyskać więcej informacji, zobacz:
- Ślad dla narzędzia do analizy wydajności (dotnet-trace) (dokumentacja platformy.NET Core)
- Ślad dla narzędzia do analizy wydajności (dotnet-trace) (dokumentacja repozytorium GitHub narzędzia dotnet/diagnostyki)
- Klasa LoggingEventSource (przeglądarka interfejsu API na platformie .NET)
- EventLevel
- Źródło odwołania LoggingEventSource (3.0): aby uzyskać źródło odwołania dla innej wersji, zmień gałąź na
release/{Version}
, gdzie{Version}
jest żądaną wersją platformy ASP.NET Core. - Perfview: przydatne do wyświetlania śladów źródła zdarzeń.
Perfview
Przy użyciu narzędzia PerfView można zbierać i wyświetlać dzienniki. Istnieją inne narzędzia do wyświetlania dzienników ETW, ale narzędzie PerfView zapewnia najlepsze środowisko do pracy ze zdarzeniami ETW emitowanymi przez platformę ASP.NET Core.
Aby skonfigurować narzędzie PerfView do zbierania zdarzeń rejestrowanych przez tego dostawcę, dodaj ciąg *Microsoft-Extensions-Logging
do listy Dodatkowi dostawcy. Nie zapomnij o znaku *
na początku ciągu.
Windows EventLog
Dostawca EventLog
wysyła dane wyjściowe dziennika do dziennika zdarzeń systemu Windows. W przeciwieństwie do innych dostawców dostawca EventLog
nie dziedziczy domyślnych ustawień innych niż dostawcy. Jeśli ustawienia dziennika EventLog
nie są określone, przyjmowana jest wartość domyślna LogLevel.Warning.
Aby rejestrować zdarzenia o poziomie niższym niż LogLevel.Warning należy jawnie ustawić poziom dziennika. W poniższym przykładzie domyślny poziom dziennika dla dziennika zdarzeń jest ustawiony na LogLevel.Information:
"Logging": {
"EventLog": {
"LogLevel": {
"Default": "Information"
}
}
}
Przeciążenia AddEventLog mogą przekazywać element EventLogSettings. Jeśli wartość wynosi null
lub nie jest określona, używane są następujące ustawienia domyślne:
LogName
: „Application”SourceName
: „.NET Runtime”MachineName
: używana jest nazwa komputera lokalnego.
Poniższy kod zmienia wartość parametru SourceName
z wartości domyślnej ".NET Runtime"
na wartość 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 aplikacji usługi 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ć tego dostawcy, należy dodać pakiet dostawcy do projektu.
Aby skonfigurować ustawienia dostawcy, użyj klas 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 usłudze Azure App Service aplikacja używa ustawień z sekcji Dzienniki usługi App Service na stronie usługi App Service w witrynie Azure Portal. Po zaktualizowaniu następujących ustawień zmiany są stosowane natychmiast bez konieczności ponownego uruchamiania lub ponownego wdrażania aplikacji.
- Rejestrowanie aplikacji (system plików)
- Rejestrowanie aplikacji (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 wynosi 10 MB, a domyślna maksymalna liczba zachowywanych 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 jest uruchomiony 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:
- serwera aplikacji
- serwera internetowego
- śledzenia żądań zakończonego niepowodzeniem
Aby skonfigurować przesyłanie strumieniowe dzienników platformy Azure:
- Przejdź do strony Dzienniki usługi App Service na stronie portalu aplikacji.
- Dla opcji Rejestrowanie aplikacji (system plików) ustaw wartość Włączone.
- Wybierz poziom dziennika. To ustawienie dotyczy tylko przesyłania strumieniowego dzienników platformy Azure.
Przejdź do strony Strumień dziennika, aby wyświetlić dzienniki. Komunikaty są rejestrowane za pomocą interfejsu ILogger
.
Azure Application Insights
Pakiet dostawcy Microsoft.Extensions.Logging.ApplicationInsights zapisuje dzienniki w usłudze Azure Application 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 pakietu, który zapewnia wszystkie dostępne dane telemetryczne dla platformy ASP.NET Core. Jeśli używasz tego pakietu, nie musisz instalować pakietu dostawcy.
Pakiet Microsoft.ApplicationInsights.Web jest przeznaczony dla platformy ASP.NET 4.x, a nie ASP.NET Core.
Aby uzyskać więcej informacji, zobacz następujące zasoby:
- Omówienie usługi Application Insights
- Usługa Application Insights dla aplikacji platformy ASP.NET Core — zacznij tutaj, jeśli chcesz zaimplementować pełny zakres danych telemetrycznych usługi Application Insights wraz z rejestrowaniem.
- Dostawca ApplicationInsightsLoggerProvider dla dzienników ILogger platformy .NET Core — zacznij tutaj, jeśli chcesz zaimplementować dostawcę rejestrowania bez pozostałej części telemetrii usługi Application Insights.
- Adaptery rejestrowania usługi Application Insights.
- Interakcyjny samouczek Instalowanie, konfigurowanie i inicjowanie zestawu SDK usługi Application Insights.
Zewnętrzni dostawcy rejestrowania
Struktury rejestrowania innych firm, które współpracują z platformą ASP.NET Core:
- elmah.io (repozytorium GitHub)
- Gelf (repozytorium GitHub)
- JSNLog (repozytorium GitHub)
- KissLog.net (repozytorium GitHub)
- Log4Net (repozytorium GitHub)
- NLog (repozytorium GitHub)
- PLogger (repozytorium GitHub)
- Sentry (repozytorium GitHub)
- Serilog (repozytorium GitHub)
- Stackdriver (repozytorium GitHub)
Niektóre struktury innych firm mogą wykonywać rejestrowanie semantyczne, znane również jako rejestrowanie strukturalne.
Korzystanie ze struktury innej firmy jest podobne do korzystania z jednego z wbudowanych dostawców:
- Dodaj pakiet NuGet do projektu.
- Wywołaj metodę rozszerzenia
ILoggerFactory
dostarczaną przez strukturę rejestrowania.
Aby uzyskać więcej informacji, zapoznaj się z dokumentacją każdego z dostawców. Zewnętrzni dostawcy rejestrowania nie są obsługiwani przez firmę Microsoft.
Aplikacja konsolowa bez hosta
Aby zapoznać się z przykładem użycia hosta ogólnego w aplikacji konsolowej innej niż internetowa, zobacz plik Program.cs
przykładowej aplikacji zadań w tle (Zadania w tle z usługami hostowanymi na platformie ASP.NET Core).
Kod rejestrowania dla aplikacji bez hosta ogólnego różni się sposobem dodawania dostawców i tworzenia rejestratorów.
Dostawcy rejestrowania
W aplikacji konsolowej bez hosta wywołaj metodę rozszerzenia Add{provider name}
dostawcy 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 obiektu ILogger<TCategoryName>. Użyj elementu 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 jest używany do tworzenia dzienników z poziomem Information
. 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 omówione bardziej szczegółowo w tym dokumencie.
Rejestrowanie podczas konstrukcji hosta
Rejestrowanie podczas konstrukcji hosta nie jest obsługiwane bezpośrednio. Można jednak użyć oddzielnego rejestratora. W poniższym przykładzie rejestrator Serilog jest używany do rejestrowania w CreateHostBuilder
. AddSerilog
używa konfiguracji statycznej określonej w 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 rejestratora ILogger
Wstrzykiwanie konstruktora rejestratora do Startup
działa we wcześniejszych wersjach platformy ASP.NET Core, ponieważ dla hosta internetowego jest tworzony oddzielny kontener DI. Aby dowiedzieć się, dlaczego dla hosta ogólnego tworzony jest tylko jeden kontener, zobacz ogłoszenie o zmianie powodującej niezgodność.
Aby skonfigurować usługę zależną od ILogger<T>
, użyj wstrzykiwania konstruktora lub podaj metodę tworzącą. Metoda tworząca jest zalecana tylko wtedy, gdy nie ma innej opcji. Rozważmy na przykład usługę, która wymaga wystąpienia ILogger<T>
dostarczanego 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 to funkcja Func<T,TResult>, która jest uruchamiana po raz pierwszy, gdy kontener DI musi skonstruować wystąpienie MyService
. W ten sposób możesz uzyskać dostęp do dowolnych zarejestrowanych usług.
Tworzenie dzienników w pliku Main
Poniższy kod rejestruje w pliku Main
, uzyskując wystąpienie ILogger
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 pliku Startup
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 do podpisu metody
Startup.ConfigureServices
nie jest obsługiwane
Przyczyną tego ograniczenia jest to, że rejestrowanie zależy od DI i konfiguracji, która z kolei zależy od DI. Kontener DI nie jest skonfigurowany dopóki funkcja ConfigureServices
nie ukończy działania.
Aby uzyskać informacje na temat konfigurowania usługi, która zależy od obiektu ILogger<T>
, lub aby dowiedzieć się, dlaczego wstrzykiwanie konstruktora rejestratora do Startup
działało we wcześniejszych wersjach, zobacz Konfigurowanie usługi, która zależy od obiektu ILogger
Brak metod rejestratora asynchronicznego
Rejestrowanie powinno być tak szybkie, że nie jest warte kosztu wydajności kodu asynchronicznego. Jeśli magazyn danych rejestrowania działa wolno, nie zapisuj do niego bezpośrednio. Rozważ zapisywanie komunikatów dziennika najpierw w szybkim magazynie, a później przenoszenie ich do powolnego magazynu. Na przykład w przypadku rejestrowania w programie SQL Server nie rób tego bezpośrednio w metodzie Log
, ponieważ metody Log
są synchroniczne. Zamiast tego synchronicznie dodaj komunikaty dziennika do kolejki w pamięci, a następnie za pomocą procesu roboczego w tle ściągaj komunikaty z kolejki, aby wykonać asynchroniczne zadanie wypychania danych do programu SQL Server. Aby uzyskać więcej informacji, zobacz ten problem w serwisie GitHub.
Zmienianie poziomów dziennika w uruchomionej aplikacji
Interfejs API rejestrowania nie obejmuje scenariusza zmieniania poziomów dziennika podczas działania aplikacji. Jednak niektórzy dostawcy konfiguracji mogą ponownie ładować konfigurację, która jest natychmiast stosowna w konfiguracji 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ć metodę IConfigurationRoot.Reload w celu zaktualizowania konfiguracji rejestrowania aplikacji.
ILogger i ILoggerFactory
Interfejsy i implementacje ILogger<TCategoryName> i ILoggerFactory są uwzględnione w zestawie SDK platformy .NET Core. Są one również dostępne w następujących pakietach NuGet:
- Interfejsy znajdują się w pliku Microsoft.Extensions.Logging.Abstractions.
- Domyślne implementacje znajdują się w pliku Microsoft.Extensions.Logging.
Stosowanie reguł filtru dziennika w kodzie
Preferowanym podejściem do ustawiania reguł filtrowania dzienników jest użycie 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 dziennika Debug
. Filtr jest stosowany do wszystkich dostawców, ponieważ nie skonfigurowano żadnego konkretnego dostawcy.
AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information)
określa następujące elementy:
- Dostawca rejestrowania
Debug
. - Poziom dziennika
Information
i wyższy. - Wszystkie kategorie rozpoczynające się od ciągu
"Microsoft"
.
Automatyczne rejestrowanie zakresu za pomocą właściwości SpanId, TraceId i ParentId
Biblioteki rejestrowania niejawnie tworzą obiekt zakresu za pomocą właściwości SpanId
, TraceId
i ParentId
. To zachowanie jest konfigurowane za pomocą właściwości ActivityTrackingOptions.
var loggerFactory = LoggerFactory.Create(logging =>
{
logging.Configure(options =>
{
options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
| ActivityTrackingOptions.TraceId
| ActivityTrackingOptions.ParentId;
}).AddSimpleConsole(options =>
{
options.IncludeScopes = true;
});
});
Jeśli nagłówek żądania HTTP traceparent
jest ustawiony, ParentId
w zakresie dziennika pokazuje parent-id
W3C z nagłówka ruchu przychodzącego traceparent
, a SpanId
w zakresie dziennika pokazuje zaktualizowany parent-id
dla następnego kroku/zakresu ruchu wychodzącego. Aby uzyskać więcej informacji, zobacz Mutowanie pola traceparent.
Tworzenie rejestratora niestandardowego
Aby utworzyć niestandardowy rejestrator, zobacz Implementowanie niestandardowego dostawcy rejestrowania na platformie .NET.
Dodatkowe zasoby
- Rejestrowanie o wysokiej wydajności
- Błędy rejestrowania powinny być tworzone w repozytorium github.com/dotnet/runtime/.
- Rejestrowanie Blazor platformy ASP.NET Core