Protokollieren in .NET Core und ASP.NET Core

Von Kirk Larkin, Jürgen Gutsch und Rick Anderson

In diesem Artikel wird die Protokollierung in .NET im Hinblick auf ASP.NET Core-Apps beschrieben. Ausführliche Informationen zur Protokollierung in .NET finden Sie unter Protokollierung in .NET. Weitere Informationen zum Protokollieren in Blazor-Apps finden Sie unter Blazor-Protokollierung in ASP.NET Core.

Protokollierungsanbieter

Protokollierungsanbieter speichern Protokolle, mit Ausnahme des Console-Anbieters, der Protokolle anzeigt. Beispielsweise speichert der Azure Application Insights-Anbieter Protokolle in Azure Application Insights. Es können mehrere Anbieter aktiviert werden.

Die ASP.NET Core-Web-App-Vorlagen rufen die Methode WebApplication.CreateBuilder auf, welche die folgenden Protokollierungsanbieter hinzufügt:

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();

Der vorstehende Code zeigt die Datei Program.cs, die mit den ASP.NET Core-Web-App-Vorlagen erstellt wurde. In den nächsten Abschnitten finden Sie Beispiele, die auf den ASP.NET Core-Web-App-Vorlagen basieren.

Der folgende Code überschreibt den Standardsatz von Protokollierungsanbietern, die von WebApplication.CreateBuilder hinzugefügt werden:

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();

Alternativ kann der vorangehende Protokollierungscode wie folgt geschrieben werden:

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

Weitere Anbieter finden Sie unter:

Erstellen von Protokollen

Um Protokolle zu erstellen, verwenden Sie ein ILogger<TCategoryName>-Objekt aus der Abhängigkeitsinjektion (DI).

Im Beispiel unten geschieht Folgendes:

  • Es wird eine Protokollierung (ILogger<AboutModel>) erstellt, die eine Protokollkategorie des vollqualifizierten Namens vom Typ AboutModel verwendet. Die Protokollkategorie ist eine Zeichenfolge, die jedem Protokoll zugeordnet ist.
  • Es wird LogInformation aufgerufen, um Protokollierung mit dem Protokolliergrad Information auszuführen. Der Protokollierungsgrad gibt den Schweregrad des protokollierten Ereignisses an.
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());
    }
}

Grade und Kategorien werden weiter unten in diesem Dokument ausführlicher erläutert.

Informationen zu Blazor finden Sie unter Blazor-Protokollierung in ASP.NET Core.

Konfigurieren der Protokollierung

Die Protokollierungskonfiguration wird üblicherweise durch den Abschnitt Logging in appsettings.{ENVIRONMENT}.json-Dateien bereitgestellt, wobei der Platzhalter {ENVIRONMENT} für die Umgebung steht. Die folgende Datei appsettings.Development.json wird von den ASP.NET Core-Web-App-Vorlagen generiert:

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

Für den JSON oben gilt:

  • Die Kategorien "Default" und "Microsoft.AspNetCore" werden angegeben.
  • Die Kategorie "Microsoft.AspNetCore" gilt für alle Kategorien, die mit "Microsoft.AspNetCore" beginnen. Diese Einstellung gilt z. B. für die Kategorie "Microsoft.AspNetCore.Routing.EndpointMiddleware".
  • Die Kategorie "Microsoft.AspNetCore" protokolliert mit Protokolliergrad Warning oder höher.
  • Ein bestimmter Protokollanbieter wird nicht angegeben, sodass LogLevel für alle aktivierten Protokollanbieter mit Ausnahme von Windows EventLog gilt.

Die Logging-Eigenschaft kann LogLevel und Protokollanbietereigenschaften beinhalten. LogLevel gibt den Mindestgrad an, der für ausgewählte Kategorien protokolliert werden soll. Im JSON-Code oben werden die Protokolliergrade Information und Warning angegeben. LogLevel gibt den Schweregrad des Protokolls an und liegt zwischen 0 und 6:

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

Wenn LogLevel angegeben wird, wird Protokollierung für Meldungen mit dem angegebenen Protokolliergrad oder höher aktiviert. Im JSON-Code oben wird die Kategorie Default für Information oder höher protokolliert. Beispielsweise werden Information-, Warning-, Error- und Critical-Meldungen protokolliert. Wenn kein LogLevel angegeben wird, wird Protokollierung standardmäßig mit dem Protokolliergrad Information verwendet. Weitere Informationen finden Sie unter Protokolliergrade.

Eine Anbietereigenschaft kann eine LogLevel-Eigenschaft angeben. LogLevel unter einem Anbieter gibt die Protokolliergrade an, die für diesen Anbieter protokolliert werden sollen, und überschreibt die Nicht-Anbieterprotokolleinstellungen. Betrachten Sie die folgende appsettings.json -Datei:

{
  "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.
      }
    }
  }
}

Einstellungen in Logging.{PROVIDER NAME}.LogLevel setzen die Einstellungen in Logging.LogLevel außer Kraft, wobei der Platzhalter {PROVIDER NAME} für den Anbieternamen steht. Im JSON-Code oben wird der Standardprotokolliergrad Debug des Anbieters auf Information festgelegt:

Logging:Debug:LogLevel:Default:Information

Die Einstellung oben gibt den Protokolliergrad Information für jede Logging:Debug:-Kategorie mit Ausnahme von Microsoft.Hosting an. Wenn eine bestimmte Kategorie aufgelistet wird, überschreibt die jeweilige Kategorie die Standardkategorie. Im JSON-Code oben überschreiben die Logging:Debug:LogLevel-Kategorien "Microsoft.Hosting" und "Default" die Einstellungen in Logging:LogLevel.

Der Mindestprotokolliergrad kann für Folgendes angegeben werden:

  • Bestimmte Anbieter: Beispiel: Logging:EventSource:LogLevel:Default:Information
  • Bestimmte Kategorien: Beispiel: Logging:LogLevel:Microsoft:Warning
  • Alle Anbieter und alle Kategorien: Logging:LogLevel:Default:Warning

Alle Protokolle unterhalb des Mindestprotokolliergrads werden nicht:

  • An den Anbieter übergeben.
  • Protokolliert oder angezeigt.

Um alle Protokolle zu unterdrücken, geben Sie LogLevel.None an. LogLevel.None hat den Wert 6, der höher als LogLevel.Critical (5) ist.

Wenn ein Anbieter Protokollbereiche unterstützt, gibt IncludeScopes an, ob sie aktiviert sind. Weitere Informationen finden Sie unter Protokollbereiche.

Die folgende Datei appsettings.json enthält alle Anbieter, die standardmäßig aktiviert sind:

{
  "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"
      }
    }
  }
}

Im vorgehenden Beispiel:

  • Die Kategorien und Protokolliergrade sind keine vorgeschlagenen Werte. Das Beispiel wird bereitgestellt, um alle Standardanbieter zu zeigen.
  • Einstellungen in Logging.{PROVIDER NAME}.LogLevel setzen die Einstellungen in Logging.LogLevel außer Kraft, wobei der Platzhalter {PROVIDER NAME} für den Anbieternamen steht. Beispielsweise überschreibt der Protokolliergrad in Debug.LogLevel.Default den Protokolliergrad in LogLevel.Default.
  • Jeder Standardanbieteralias wird verwendet. Jeder Anbieter definiert einen Alias, der in der Konfiguration anstelle des vollqualifizierten Typnamens verwendet werden kann. Die folgenden Anbieteraliase sind integriert:
    • Console
    • Debug
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

Protokoll in Program.cs

Das folgende Beispiel ruft Builder.WebApplication.Logger in Program.cs auf und protokolliert Informationsnachrichten:

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();

Im folgenden Beispiel wird AddConsole in Program.cs aufgerufen und der Endpunkt /Test protokolliert:

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();

Im folgenden Beispiel wird AddSimpleConsole in Program.cs aufgerufen, die Farbausgabe deaktiviert und der Endpunkt /Test protokolliert:

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();

Festlegen des Protokolliergrads über die Befehlszeile, Umgebungsvariablen und andere Konfigurationen

Der Protokolliergrad kann von einem beliebigen Konfigurationsanbieter festgelegt werden.

Das Trennzeichen : funktioniert nicht auf allen Plattformen mit den hierarchischen Schlüsseln von Umgebungsvariablen. Der doppelte Unterstrich __:

  • wird auf allen Plattformen unterstützt. Das Trennzeichen : wird beispielsweise nicht von Bash unterstützt, __ hingegen schon.
  • automatisch durch : ersetzt.

Die folgenden Befehle:

  • Legen den Umgebungsschlüssel Logging:LogLevel:Microsoft auf den Wert Information unter Windows fest.
  • Testen die Einstellungen, wenn eine App verwendet wird, die mit den ASP.NET Core-Webanwendungsvorlagen erstellt wurde. Der dotnet run-Befehl muss im Projektverzeichnis nach der Verwendung von set ausgeführt werden.
set Logging__LogLevel__Microsoft=Information
dotnet run

Die oben gezeigte Umgebungseinstellungen:

  • Werden nur in Prozessen festgelegt, die über das Befehlsfenster gestartet werden, in dem sie festgelegt wurden.
  • Werden nicht von Browsern gelesen, die mit Visual Studio gestartet wurden.

Mit dem folgenden setx-Befehl werden auch der Umgebungsschlüssel und der Wert unter Windows festgelegt. Anders als set werden setx-Einstellungen beibehalten. Der Schalter /M legt die Variable in der Systemumgebung fest. Wenn /M nicht verwendet wird, wird eine Benutzerumgebungsvariable festgelegt.

setx Logging__LogLevel__Microsoft Information /M

Betrachten Sie die folgende appsettings.json -Datei:

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

Der folgende Befehl legt die obige Konfiguration in der Umgebung fest:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

Hinweis

Wenn Sie Umgebungsvariablen mit Namen konfigurieren, die . (Punkte) in macOS und Linux enthalten, sollten Sie in Stack Exchange die Frage zum Exportieren einer Variablen mit einem Punkt (.) lesen und die entsprechende akzeptierte Antwort beachten.

Klicken Sie in Azure App Service auf der Seite Einstellungen > Konfiguration auf Neue Anwendungseinstellung. Anwendungseinstellungen von Azure App Service werden:

  • Im Ruhezustand verschlüsselt und über einen verschlüsselten Kanal übermittelt.
  • Als Umgebungsvariablen verfügbar gemacht.

Weitere Informationen finden Sie unter Azure Apps: Überschreiben der App-Konfiguration mit dem Azure-Portal.

Weitere Informationen zum Festlegen von ASP.NET Core-Konfigurationswerten mithilfe von Umgebungsvariablen finden Sie unter Umgebungsvariablen. Informationen zur Verwendung anderer Konfigurationsquellen, beispielsweise der Befehlszeile, Azure Key Vault, Azure App Configuration oder anderer Dateiformate, finden Sie unter Konfiguration in ASP.NET Core.

Anwendung von Filterregeln

Wenn ein ILogger<TCategoryName>-Objekt erstellt wird, wählt das ILoggerFactory-Objekt eine einzige Regel pro Anbieter aus, die auf diese Protokollierung angewendet wird. Alle von einer ILogger-Instanz geschriebenen Meldungen werden auf Grundlage der ausgewählten Regeln gefiltert. Aus den verfügbaren Regeln wird die für jeden Anbieter und jedes Kategoriepaar spezifischste Regel ausgewählt.

Beim Erstellen von ILogger für eine vorgegebene Kategorie wird für jeden Anbieter der folgende Algorithmus verwendet:

  • Es werden alle Regeln ausgewählt, die dem Anbieter oder dem zugehörigen Alias entsprechen. Wenn keine Übereinstimmung gefunden wird, werden alle Regeln mit einem leeren Anbieter ausgewählt.
  • Aus dem Ergebnis des vorherigen Schritts werden die Regeln mit dem längsten übereinstimmenden Kategoriepräfix ausgewählt. Wenn keine Übereinstimmung gefunden wird, werden alle Regeln ohne Angabe einer Kategorie ausgewählt.
  • Wenn mehrere Regeln ausgewählt sind, wird die letzte Regel verwendet.
  • Wenn keine Regel ausgewählt ist, wird MinimumLevel verwendet.

Protokollieren der Ausgabe von dotnet run und Visual Studio

Protokolle, die mit den Standardprotokollierungsanbietern erstellt werden, werden angezeigt:

  • In Visual Studio
    • Im Ausgabefenster „Debuggen“ beim Debuggen.
    • Im ASP.NET Core Web Server-Fenster.
  • Im Konsolenfenster, wenn die App mit dotnet run ausgeführt wird.

Protokolle, die mit „Microsoft“-Kategorien beginnen, stammen aus ASP.NET Core-Frameworkcode. ASP.NET Core und Anwendungscode verwenden dieselbe Protokollierungs-API und dieselben Protokollierungsanbieter.

Protokollkategorie

Wenn ein ILogger-Objekt erstellt wird, wird eine Kategorie angegeben. Diese Kategorie ist in jeder Protokollmeldung enthalten, die von dieser Instanz von ILogger erstellt wird. Die Kategoriezeichenfolge ist beliebig, aber die Konvention ist, den vollständig qualifizierten Klassennamen zu verwenden. Beispielsweise kann in einem Controller der Name "TodoApi.Controllers.TodoController" lauten. Die ASP.NET Core-Web-Apps verwenden ILogger<T> zum automatischen Abrufen einer ILogger-Instanz, die den vollqualifizierten Typnamen von T als Kategorie verwendet:

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.");
    }
}

Wenn eine weitere Kategorisierung erwünscht ist, besteht die Konvention darin, einen hierarchischen Namen zu verwenden, indem eine Unterkategorie an den voll qualifizierten Klassennamen angehängt und die Kategorie explizit mit ILoggerFactory.CreateLogger angegeben wird:

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.");
    }

Das Aufrufen von CreateLogger mit einem festgelegten Namen kann bei Verwendung in mehreren Methoden nützlich sein, damit die Ereignisse nach Kategorie organisiert werden können.

ILogger<T> entspricht dem Aufruf von CreateLogger mit dem vollqualifizierten Typnamen T.

Protokolliergrad

In der folgenden Tabelle werden die LogLevel-Werte, die Erweiterungsmethode Log{LogLevel} und die empfohlene Syntax aufgeführt:

LogLevel Wert Methode BESCHREIBUNG
Trace 0 LogTrace Enthält die ausführlichsten Meldungen. Diese Meldungen enthalten möglicherweise sensible App-Daten. Sie sind standardmäßig deaktiviert und sollten nicht in einer Produktionsumgebung aktiviert werden.
Debug 1 LogDebug Zum Debuggen und für die Entwicklung. Wegen des großen Volumens in der Produktion mit Vorsicht zu verwenden.
Information 2 LogInformation Verfolgt den allgemeinen Ablauf der App nach. Kann über einen langfristigen Wert verfügen.
Warning 3 LogWarning Für ungewöhnliche oder unerwartete Ereignisse. Schließt in der Regel Fehler oder Bedingungen ein, die nicht bewirken, dass die App fehlschlägt.
Error 4 LogError Für Fehler und Ausnahmen, die nicht behandelt werden können. Diese Meldungen weisen auf einen Fehler im aktuellen Vorgang oder der aktuellen Anforderung und nicht auf einen anwendungsweiten Fehler hin.
Critical 5 LogCritical Für Fehler, die sofortige Aufmerksamkeit erfordern. Beispiel: Szenarios mit Datenverlust, Speichermangel.
None 6 Gibt an, dass eine Protokollierungskategorie keine Meldungen schreiben soll.

In der Tabelle oben wird der LogLevel vom niedrigsten bis zum höchsten Schweregrad aufgelistet.

Der erste Parameter der Log-Methode (LogLevel) gibt den Schweregrad des Protokolls an. Anstatt Log(LogLevel, ...) aufzurufen, rufen die meisten Entwickler die Log{LOG LEVEL}-Erweiterungsmethoden auf. Der Platzhalter {LOG LEVEL} steht für den Protokolliergrad. Beispielsweise sind die folgenden beiden Protokollierungsaufrufe funktionell gleichwertig und generieren das gleiche Protokoll:

[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 ist die Ereignis-ID. MyLogEvents ist Teil der Beispiel-App und wird im Abschnitt Log Event ID (Protokollereignis-ID) angezeigt.

MyDisplayRouteInfo und ToCtxString werden über das NuGet-Paket Rick.Docs.Samples.RouteInfo bereitgestellt. Diese Methoden zeigen Controller- und Razor Page-Routeninformationen an.

Der folgende Code erstellt Information- und Warning-Protokolle:

[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);
}

Im Code oben ist der erste Log{LOG LEVEL}-Parameter (MyLogEvents.GetItem) die Protokollereignis-ID. Der zweite Parameter ist eine Meldungsvorlage mit Platzhaltern für Argumentwerte, die von den verbleibenden Methodenparametern bereitgestellt werden. Die Methodenparameter werden im Abschnitt „Meldungsvorlage“ weiter unten in diesem Dokument erläutert.

Rufen Sie die entsprechende Log{LOG LEVEL}-Methode auf, um die Menge an Protokollausgabedaten zu steuern, die in ein bestimmtes Speichermedium geschrieben werden. Zum Beispiel:

  • In einer Produktionsumgebung
    • Das Protokollieren mit den Protokolliergraden Trace, Debug oder Information verursacht viele detaillierte Protokollmeldungen. Um die Kosten zu kontrollieren und die Datenspeichergrenzen nicht zu überschreiten, protokollieren Sie Meldungen der Protokolliergrade Trace, Debug oder Information in einem kostengünstigen Datenspeicher mit hohem Datenvolumen. Erwägen Sie eine Beschränkung von Trace, Debug oder Information auf bestimmte Kategorien.
    • Bei der Protokollierung mit den Protokolliergraden Warning bis Critical sollten nur wenige Protokollmeldungen generiert werden.
      • Kosten und Speichergrenzwerte stellen in der Regel kein Problem dar.
      • Wenige Protokolle ermöglichen eine größere Flexibilität bei der Auswahl von Datenspeichern.
  • Bei der Entwicklung:
    • Legen Sie Warning fest.
    • Fügen Sie bei der Problembehandlung Trace-, Debug- oder Information-Meldungen hinzu. Um die Ausgabe einzuschränken, legen Sie Trace, Debug oder Information nur für die zu untersuchenden Kategorien fest.

ASP.NET Core schreibt Protokolle für Frameworkereignisse. Berücksichtigen Sie z. B. die Protokollausgabe für Folgendes:

  • Eine Razor Pages-App, die mit den ASP.NET Core-Vorlagen erstellt wurde.
  • Eine auf Logging:Console:LogLevel:Microsoft:Information festgelegte Protokollierung.
  • Die Navigation zur Seite 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

Die folgende JSON legt Logging:Console:LogLevel:Microsoft:Information fest:

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

Protokollereignis-ID

Jedes Protokoll kann eine Ereignis-ID angeben. Die Beispiel-App verwendet die MyLogEvents-Klasse zum Definieren von Ereignis-IDs:

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);
}

Eine Ereignis-ID ordnet eine Gruppe von Ereignissen zu. Beispielsweise können alle Protokolle, die sich auf die Anzeige einer Liste von Elementen auf einer Seite beziehen, 1001 sein.

Der Protokollierungsanbieter kann die Ereignis-ID in einem ID-Feld, in der Protokollierungsmeldung oder gar nicht speichern. Der Debuganbieter zeigt keine Ereignis-IDs an. Der Konsolenanbieter zeigt Ereignis-IDs in Klammern hinter der Kategorie an:

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

Einige Protokollierungsanbieter speichern die Ereignis-ID in einem Feld, das das Filtern nach der ID ermöglicht.

Protokollmeldungsvorlage

Jede Protokoll-API verwendet eine Meldungsvorlage. Die Meldungsvorlage kann Platzhalter enthalten, für die Argumente bereitgestellt werden. Verwenden Sie Namen für die Platzhalter, keine Zahlen.

[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);
}

Die Reihenfolge der Parameter, nicht die der Platzhalternamen, bestimmt, welche Parameter verwendet werden, um Platzhalterwerte in Protokollmeldungen bereitzustellen. Im folgenden Code befinden sich die Parameternamen in den Platzhaltern der Meldungsvorlage nicht in der richtigen Reihenfolge:

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

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

Die Parameter werden den Platzhaltern jedoch in der folgenden Reihenfolge zugewiesen: apples, pears, bananas. Die Protokollmeldung spiegelt die Reihenfolge der Parameter wider:

Parameters: 1, 2, 3

Dieser Ansatz ermöglicht es Protokollierungsanbietern, semantische oder strukturierte Protokollierung zu implementieren. Die Argumente selbst (nicht nur die formatierte Meldungsvorlage) werden an das Protokollierungssystem übergeben. Dies ermöglicht es Protokollierungsanbietern, die Parameterwerte als Felder zu speichern. Sehen Sie sich z. B. die folgende Protokollierungsmethode an:

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

Beispielsweise bei der Protokollierung in Azure Table Storage:

  • Jede Azure Table-Entität kann über ID- und RequestTime-Eigenschaften verfügen.
  • Tabellen mit Eigenschaften vereinfachen Abfragen für protokollierte Daten. Beispielsweise kann eine Abfrage alle Protokolle innerhalb eines bestimmten RequestTime-Bereichs ermitteln, ohne die Zeitangabe aus der Textnachricht analysieren zu müssen.

Protokollieren von Ausnahmen

Die Protokollierungsmethoden verfügen über Überladungen, die einen Ausnahmeparameter annehmen:

[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();
}

MyDisplayRouteInfo und ToCtxString werden über das NuGet-Paket Rick.Docs.Samples.RouteInfo bereitgestellt. Diese Methoden zeigen Controller- und Razor Page-Routeninformationen an.

Ausnahmeprotokollierung ist anbieterspezifisch.

Standardprotokolliergrad

Wenn der Standardprotokolliergrad nicht festgelegt ist, ist der Standardwert des Standardprotokolliergrads Information.

Betrachten Sie z. B. die folgende Web-App:

  • Sie wurde mit den ASP.NET-Web-App-Vorlagen erstellt.
  • appsettings.json und appsettings.Development.json wurden gelöscht oder umbenannt.

Mit dem oben beschriebenen Setup generiert die Navigation zur Datenschutz- oder Homepage viele Trace-, Debug- und Information-Meldungen mit Microsoft im Kategorienamen.

Mit dem folgenden Code wird der Standardprotokolliergrad festgelegt, wenn der Standardprotokolliergrad nicht in der Konfiguration festgelegt ist:

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

Im Allgemeinen sollten Standardprotokolliergrads in der Konfiguration und nicht im Code angegeben werden.

Filterfunktion

Eine Filterfunktion wird für alle Anbieter und Kategorien aufgerufen, denen keine Regeln durch Konfiguration oder Code zugewiesen sind:

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;
    }
});

Der Code oben zeigt Konsolenprotokolle an, wenn die Kategorie Controller oder Microsoft enthält und der Protokolliergrad Information oder höher ist.

Im Allgemeinen sollten Standardprotokolliergrads in der Konfiguration und nicht im Code angegeben werden.

ASP.NET Core- und EF Core-Kategorien

Die folgende Tabelle enthält einige Kategorien, die von ASP.NET Core und Entity Framework Core verwendet werden, mit Hinweisen zu den Protokollen:

Kategorie Hinweise
Microsoft.AspNetCore Allgemeine ASP.NET Core-Diagnose.
Microsoft.AspNetCore.DataProtection Gibt an, welche Schlüssel in Betracht gezogen, gefunden und verwendet wurden.
Microsoft.AspNetCore.HostFiltering Hosts sind zulässig.
Microsoft.AspNetCore.Hosting Gibt an, wie lange es bis zum Abschluss von HTTP-Anforderungen gedauert hat und zu welcher Zeit sie gestartet wurden. Gibt an, welche Hostingstartassemblys geladen wurden.
Microsoft.AspNetCore.Mvc MVC und Razor-Diagnose Modellbindung, Filterausführung, Ansichtskompilierung, Aktionsauswahl.
Microsoft.AspNetCore.Routing Gibt Routenabgleichsinformationen an.
Microsoft.AspNetCore.Server Start-, Beendigungs- und Keep-Alive-Antworten der Verbindung. HTTPS-Zertifikatinformationen.
Microsoft.AspNetCore.StaticFiles Die bereitgestellten Dateien.
Microsoft.EntityFrameworkCore Allgemeine Entity Framework Core-Diagnose. Datenbankaktivität und -konfiguration, Änderungserkennung, Migrationen.

Wenn Sie weitere Kategorien im Konsolenfenster anzeigen möchten, legen Sie appsettings.Development.json auf Folgendes fest:

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

Protokollbereiche

Ein Bereich kann einen Satz logischer Vorgänge gruppieren. Diese Gruppierung kann verwendet werden, um an jedes Protokoll, das als Teil einer Gruppe erstellt wird, die gleichen Daten anzufügen. So kann beispielsweise jedes Protokoll, das im Rahmen der Verarbeitung einer Transaktion erstellt wird, die Transaktions-ID enthalten.

Ein Bereich:

  • Ist ein IDisposable-Typ, der von der BeginScope-Methode zurückgegeben wird.
  • Er bleibt bestehen, bis er verworfen wird.

Die folgenden Anbieter unterstützen Bereiche:

Verwenden Sie einen Bereich, indem Sie Protokollierungsaufrufe mit einem using-Block umschließen, der als Wrapper verwendet wird:

[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);
}

Integrierte Protokollierungsanbieter

ASP.NET Core enthält die folgenden Protokollierungsanbieter als Teil des freigegebenen Frameworks:

Die folgenden Protokollierungsanbieter werden von Microsoft bereitgestellt, aber nicht als Teil des freigegebenen Frameworks. Sie müssen als zusätzliche NuGet-Pakete installiert werden.

ASP.NET Core enthält keinen Protokollierungsanbieter zum Schreiben von Protokollen in Dateien. Um Protokolle aus einer ASP.NET Core-App in Dateien zu schreiben, erwägen Sie die Verwendung eines Protokollierungsdrittanbieters.

Informationen zu stdout und zum Debuggen der Protokollierung mit dem ASP.NET Core-Modul finden Sie unter Problembehandlung bei ASP.NET Core in Azure App Service und IIS und unter ASP.NET Core-Modul (ANCM) für IIS.

Konsole

Der Console-Anbieter protokolliert die Ausgabe in der Konsole. Weitere Informationen zum Anzeigen von Console-Protokollen in der Entwicklung finden Sie unter Protokollieren der Ausgabe von dotnet run und Visual Studio.

Debuggen

Der Debug-Anbieter schreibt die Protokollausgabe mithilfe der System.Diagnostics.Debug-Klasse. Aufrufe von System.Diagnostics.Debug.WriteLine schreiben in den Debug-Anbieter.

Unter Linux ist der Speicherort des Protokolls des Debug-Anbieters abhängig von der Distribution und kann wie folgt lauten:

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

Ereignisquelle

Der EventSource-Anbieter schreibt in eine plattformübergreifende Ereignisquelle mit dem Namen Microsoft-Extensions-Logging. Unter Windows verwendet der Anbieter die Ereignisablaufverfolgung für Windows (ETW).

dotnet-trace-Tool

Das Tool dotnet-trace ist ein plattformübergreifendes globales Befehlszeilenschnittstellentool zum Sammeln von .NET Core-Ablaufverfolgungen eines ausgeführten Prozesses. Das Tool sammelt Microsoft.Extensions.Logging.EventSource-Anbieterdaten mithilfe einer LoggingEventSource.

Anweisungen zur Installation finden Sie unter dotnet-trace.

Verwenden Sie das dotnet-trace-Tool, um die Ablaufverfolgung aus einer App zu erfassen:

  1. Führen Sie die App mit dem Befehl dotnet run aus.

  2. Bestimmen Sie den Prozessbezeichner der .NET Core-App:

    dotnet-trace ps
    

    Suchen Sie den Prozessbezeichner für den Prozess, der den gleichen Namen wie die App-Assembly hat.

  3. Führen Sie den dotnet-trace-Befehl aus.

    Allgemeine Befehlssyntax:

    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}\"
    

    Wenn Sie eine PowerShell-Befehlsshell verwenden, schließen Sie den --providers-Wert in einfache Anführungszeichen (') ein:

    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}\"'
    

    Auf Plattformen, die nicht unter Windows ausgeführt werden, fügen Sie die -f speedscope-Option hinzu, um das Format der Ablaufverfolgungsdatei der Ausgabe in speedscope zu ändern.

    In der folgenden Tabelle wird das Schlüsselwort definiert:

    Schlüsselwort BESCHREIBUNG
    1 Protokolliert Metaereignisse über die LoggingEventSource. Es werden keine Ereignisse von ILogger protokolliert.
    2 Aktiviert das Message-Ereignis, wenn ILogger.Log() aufgerufen wird. Die Informationen werden in einer programmgesteuerten (nicht formatierten) Weise ausgegeben.
    4 Aktiviert das FormatMessage-Ereignis, wenn ILogger.Log() aufgerufen wird. Gibt die formatierte Zeichenfolgeversion der Informationen an.
    8 Aktiviert das MessageJson-Ereignis, wenn ILogger.Log() aufgerufen wird. Stellt eine JSON-Darstellung der Argumente bereit.

    Die folgende Tabelle listet die Anbieterebenen auf:

    Anbieterebene BESCHREIBUNG
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    Die Analyse für eine Kategorieebene kann entweder eine Zeichenfolge oder eine Zahl sein:

    Benannter Wert der Kategorie Numerischer Wert
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    Für die Anbieter- und Kategorieebene gilt:

    • Sie befinden sich in umgekehrter Reihenfolge.
    • Die Zeichenfolgenkonstanten sind nicht alle identisch.

    Wenn keine FilterSpecs angegeben werden, versucht die EventSourceLogger-Implementierung, die Anbieterebene in eine Kategorieebene zu konvertieren, und wendet sie auf alle Kategorien an.

    Anbieterebene Kategorieebene
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    Wenn FilterSpecs angegeben werden, wird für jede in der Liste enthaltene Kategorie die dort codierte Kategorieebene verwendet. Alle anderen Kategorien werden herausgefiltert.

    Bei den folgenden Beispielen wird Folgendes vorausgesetzt:

    • Eine App wird ausgeführt und ruft logger.LogDebug("12345") auf.
    • Die Prozess-ID (PID) wurde über set PID=12345 festgelegt, wobei 12345 der tatsächlichen PID entspricht.

    Betrachten Sie den folgenden Befehl:

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

    Der vorherige Befehl:

    • Erfasst Debugmeldungen.
    • FilterSpecs werden nicht angewendet.
    • Gibt Ebene 5 an, wodurch die Kategorie „Debug“ zugeordnet wird.

    Betrachten Sie den folgenden Befehl:

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

    Der vorherige Befehl:

    • Erfasst keine Debugmeldungen, weil die Kategorieebene 5 Critical lautet.
    • Stellt FilterSpecs bereit.

    Der folgende Befehl erfasst Debugmeldungen, weil Kategorieebene 1 Debug angibt.

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

    Der folgende Befehl erfasst Debugmeldungen, weil die Kategorie Debug angibt.

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

    FilterSpecs-Einträge für {Logger Category} und {Category Level} stellen zusätzliche Protokollfilterbedingungen dar. Trennen Sie FilterSpecs-Einträge durch ein Semikolon (;).

    Beispiel für die Verwendung einer Windows-Befehlsshell:

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

    Mit dem vorangestellten Komma wird Folgendes aktiviert:

    • Die Ereignisquellenprotokollierung zur Erzeugung von formatierten Zeichenfolgen (4) für Fehler (2)
    • Microsoft.AspNetCore.Hosting-Protokollierung auf Informational-Protokollierungsebene (4)
  4. Beenden Sie das dotnet-trace Tool, indem Sie die EINGABETASTE oder STRG+Cdrücken.

    Die Ablaufverfolgung wird mit dem Namen trace.nettrace in dem Ordner gespeichert, in dem der dotnet-trace-Befehl ausgeführt wird.

  5. Öffnen Sie die Ablaufverfolgung mit Perfview. Öffnen Sie die Datei trace.nettrace, und untersuchen Sie die Ablaufverfolgungsereignisse.

Wenn die App den Host nicht mit WebApplication.CreateBuilder erstellt, fügen Sie den Ereignisquellenanbieter zur Protokollierungskonfiguration der App hinzu.

Weitere Informationen finden Sie unter:

PerfView

Verwenden Sie das PerfView-Hilfsprogramm zum Sammeln und Anzeigen von Protokollen. Es gibt andere Tools zur Anzeige von ETW-Protokollen, aber PerfView bietet die besten Ergebnisse bei der Arbeit mit ETW-Ereignissen, die von ASP.NET Core ausgegeben werden.

Um PerfView für das Erfassen von Ereignissen zu konfigurieren, die von diesem Anbieter protokolliert wurden, fügen Sie die Zeichenfolge *Microsoft-Extensions-Logging zur Liste Zusätzliche Anbieter hinzu. Vergessen Sie nicht das * am Anfang der Zeichenfolge.

Windows-EventLog

Der EventLog-Anbieter sendet die Protokollausgabe an das Windows-Ereignisprotokoll. Im Gegensatz zu den anderen Anbietern erbt der EventLog-Anbieter nicht die Standardeinstellungen für Nicht-Anbieter. Wenn keine EventLog-Protokolleinstellungen angegeben werden, wird LogLevel.Warning verwendet.

Legen Sie die Protokollierungsebene fest, um Ereignisse, die niedriger als LogLevel.Warning sind, zu protokollieren. Im folgenden Beispiel wird der Standardprotokolliergrad auf LogLevel.Information festgelegt:

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

AddEventLog-Überladungen können EventLogSettings übergeben. Wenn null oder nicht angegeben, werden die folgenden Standardeinstellungen verwendet:

  • LogName: „Anwendung“
  • SourceName: „.NET Runtime“
  • MachineName: Der Name des lokalen Computers wird verwendet.

Der folgende Code ändert SourceName aus dem Standardwert ".NET Runtime" in MyLogs:


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

Azure App Service

Das Anbieterpaket Microsoft.Extensions.Logging.AzureAppServices schreibt Protokolle in Textdateien in das Dateisystem einer Azure App Service-App und in Blobspeicher in einem Azure Storage-Konto.

Das Anbieterpaket ist nicht im freigegebenen Framework enthalten. Zum Verwenden des Anbieters müssen Sie das Anbieterpaket dem Projekt hinzufügen.

Verwenden Sie AzureFileLoggerOptions und AzureBlobLoggerOptions wie im folgenden Beispiel, um die Anbietereinstellungen zu konfigurieren:

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";
});

Wenn eine Bereitstellung in Azure App Service erfolgt, verwendet die App die Einstellungen im Abschnitt App Service logs (App Service-Protokolle) auf der Seite App Service im Azure-Portal. Bei einem Update der folgenden Einstellungen werden die Änderungen sofort wirksam, ohne dass ein Neustart oder eine erneute Bereitstellung der App notwendig ist.

  • Anwendungsprotokoll (Dateisystem)
  • Anwendungsprotokoll (Blob)

Der Standardspeicherort für Protokolldateien befindet sich im Ordner D:\\home\\LogFiles\\Application, und der Standarddateiname lautet diagnostics-yyyymmdd.txt. Die Dateigröße ist standardmäßig auf 10 MB beschränkt, und die maximal zulässige Anzahl beibehaltener Dateien lautet 2. Der Standardblobname lautet {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt.

Der Anbieter führt nur Protokollierung aus, wenn das Projekt in der Azure-Umgebung ausgeführt wird.

Azure-Protokollstreaming

Azure-Protokollstreaming unterstützt das Anzeigen der Protokollaktivität in Echtzeit:

  • App-Server
  • Webserver
  • Ablaufverfolgung für Anforderungsfehler

So konfigurieren Sie das Azure-Protokollstreaming

  • Navigieren Sie von der Portalseite Ihrer App zur Seite App Service-Protokolle.
  • Legen Sie Anwendungsprotokollierung (Dateisystem) auf Ein fest.
  • Wählen Sie die Protokollierungsebene. Diese Einstellung gilt nur für Azure-Protokollstreaming.

Navigieren Sie zur Seite Log Stream (Protokollstream), um Protokolle anzuzeigen. Die protokollierten Nachrichten werden mit der ILogger-Schnittstelle protokolliert.

Azure Application Insights

Das Anbieterpaket Microsoft.Extensions.Logging.ApplicationInsights schreibt Protokolle in Azure Application Insights. Application Insights ist ein Dienst, der eine Web-App überwacht und Tools für Abfragen und Analysen von Telemetriedaten zur Verfügung stellt. Wenn Sie diesen Anbieter verwenden, können Sie Ihre Protokolle mithilfe der Application Insights-Tools abfragen und analysieren.

Der Protokollierungsanbieter ist als Abhängigkeit von Microsoft.ApplicationInsights.AspNetCore enthalten, d. h. als das Paket, das alle verfügbaren Telemetriedaten für ASP.NET Core bereitstellt. Wenn Sie dieses Paket verwenden, ist nicht erforderlich, das Anbieterpaket zu installieren.

Das Paket Microsoft.ApplicationInsights.Web gilt für ASP.NET 4.x, nicht für ASP.NET Core.

Weitere Informationen finden Sie in den folgenden Ressourcen:

Protokollierungsanbieter von Drittanbietern

Protokollierungsframeworks von Drittanbietern aufgeführt, die mit ASP.NET Core funktionieren:

Einige Drittanbieterframeworks können eine semantische Protokollierung (auch als strukturierte Protokollierung bezeichnet) ausführen.

Die Verwendung eines Frameworks von Drittanbietern ist ähnlich wie die Verwendung eines integrierten Anbieters:

  1. Fügen Sie Ihrem Paket ein NuGet-Paket hinzu.
  2. Rufen Sie eine ILoggerFactory-Erweiterungsmethode auf, die vom Protokollierungsframework bereitgestellt wird.

Weitere Informationen finden Sie in der Dokumentation zum jeweiligen Anbieter. Protokollierungsanbieter von Drittanbietern werden von Microsoft nicht unterstützt.

Keine asynchronen Protokollierungsmethoden

Die Protokollierung sollte so schnell erfolgen, dass sich die Leistungskosten von asynchronem Code nicht lohnen. Wenn ein Protokollierungsdatenspeicher langsam ist, schreiben Sie nicht direkt in diesen. Erwägen Sie, die Protokollnachrichten zunächst in einen schnellen Speicher zu schreiben und sie dann später in den langsamen Speicher zu verschieben. Wenn Sie beispielsweise in SQL Server protokollieren, verwenden Sie nicht direkt eine Log-Methode, da die Log-Methoden synchron sind. Fügen Sie stattdessen die Protokollmeldungen synchron zu einer Warteschlange im Arbeitsspeicher hinzu, und rufen Sie mithilfe eines Hintergrundworkers die Nachrichten aus der Warteschlange ab, um sie dann asynchron per Pushvorgang an SQL Server zu übertragen. Weitere Informationen finden Sie unter Anleitung zum Protokollieren in einer Nachrichtenwarteschlange für langsame Datenspeicher (dotnet/AspNetCore.Docs #11801).

Ändern von Protokolliergraden in einer aktuell ausgeführten App

Die Protokollierungs-API umfasst kein Szenario zum Ändern der Protokollebene, während eine App ausgeführt wird. Einige Konfigurationsanbieter können jedoch die Konfiguration erneut laden, was sich unmittelbar auf die Protokollierungskonfiguration auswirkt. Beispielsweise lädt der Dateikonfigurationsanbieter die Protokollierungskonfiguration standardmäßig erneut. Wenn die Konfiguration im Code geändert wird, während eine App ausgeführt wird, kann die App IConfigurationRoot.Reload aufrufen, um ihre Protokollierungskonfiguration zu aktualisieren.

ILogger und ILoggerFactory

Die ILogger<TCategoryName>- und ILoggerFactory-Schnittstellen und -Implementierungen sind im .NET Core SDK enthalten. Sie sind auch in den folgenden NuGet-Paketen verfügbar:

Anwenden von Protokollfilterregeln in Code

Die bevorzugte Vorgehensweise zum Festlegen von Protokollfilterregeln ist die Verwendung von Konfiguration.

Das folgende Beispiel zeigt, wie Filterregeln im Code registriert werden:

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) gibt die System-Kategorie und den Protokolliergrad Debug an. Der Filter wird auf alle Anbieter angewendet, da kein bestimmter Anbieter konfiguriert wurde.

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) gibt Folgendes an:

  • Den Debug-Protokollanbieter.
  • Der Protokolliergrad Information oder höher.
  • Alle Kategorien, die mit "Microsoft" beginnen.

Automatisches Protokollieren des Bereichs mit SpanId, TraceId, ParentId, Baggage und Tags

Die Protokollierungsbibliotheken erstellen implizit ein Bereichsobjekt mit SpanId, TraceId, ParentId, Baggage und Tags. Dieses Verhalten wird über ActivityTrackingOptions konfiguriert.

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();

Wenn der HTTP-Anforderungsheader traceparent festgelegt ist, zeigt die ParentId im Protokollbereich die W3C-parent-id aus dem eingehenden traceparent-Header, und die SpanId im Protokollbereich zeigt die aktualisierte parent-id für den nächsten ausgehenden Schritt/Bereich. Weitere Informationen finden Sie unter Verändern des traceparent-Felds.

Erstellen einer benutzerdefinierten Protokollierung

Weitere Informationen zum Erstellen einer benutzerdefinierten Protokollierung finden Sie unter Implementieren eines benutzerdefinierten Protokollierungsanbieters in .NET.

Zusätzliche Ressourcen

Von Kirk Larkin, Jürgen Gutsch und Rick Anderson

In diesem Thema wird die Protokollierung in .NET im Hinblick auf ASP.NET Core-Apps beschrieben. Ausführliche Informationen zur Protokollierung in .NET finden Sie unter Protokollierung in .NET. Weitere Informationen zum Protokollieren in Blazor-Apps finden Sie unter Blazor-Protokollierung in ASP.NET Core.

Zeigen Sie Beispielcode an, oder laden Sie diesen herunter (Vorgehensweise zum Herunterladen).

Protokollierungsanbieter

Protokollierungsanbieter speichern Protokolle, mit Ausnahme des Console-Anbieters, der Protokolle anzeigt. Beispielsweise speichert der Azure Application Insights-Anbieter Protokolle in Azure Application Insights. Es können mehrere Anbieter aktiviert werden.

Für die ASP.NET Core-Web-App-Standardvorlagen gilt Folgendes:

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>();
            });
}

Der vorstehende Code zeigt die Program-Klasse, die mit den ASP.NET Core-Web-App-Vorlagen erstellt wurde. In den nächsten Abschnitten finden Sie Beispiele, die auf den ASP.NET Core-Web-App-Vorlagen basieren, die den generischen Host verwenden. Nicht-Hostkonsolen-Apps werden weiter unten in diesem Dokument erläutert.

Um den von Host.CreateDefaultBuilder hinzugefügten Standardsatz von Protokollierungsanbietern zu überschreiben, rufen Sie ClearProviders auf und fügen die erforderlichen Protokollierungsanbieter hinzu. Beispielsweise folgender Code:

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

Weitere Anbieter finden Sie unter:

Erstellen von Protokollen

Um Protokolle zu erstellen, verwenden Sie ein ILogger<TCategoryName>-Objekt aus der Abhängigkeitsinjektion (DI).

Im Beispiel unten geschieht Folgendes:

  • Es wird eine Protokollierung (ILogger<AboutModel>) erstellt, die eine Protokollkategorie des vollqualifizierten Namens vom Typ AboutModel verwendet. Die Protokollkategorie ist eine Zeichenfolge, die jedem Protokoll zugeordnet ist.
  • Es wird LogInformation aufgerufen, um Protokollierung mit dem Protokolliergrad Information auszuführen. Der Protokollierungsgrad gibt den Schweregrad des protokollierten Ereignisses an.
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);
    }
}

Grade und Kategorien werden weiter unten in diesem Dokument ausführlicher erläutert.

Informationen zu Blazor finden Sie unter Blazor-Protokollierung in ASP.NET Core.

Erstellen von Protokollen in „Main“ und „Startup“ zeigt, wie Protokolle in Main und Startup erstellt werden.

Konfigurieren der Protokollierung

Die Konfiguration der Protokollierung wird meistens im Abschnitt Logging der appsettings.{Environment}.json-Dateien angegeben. Die folgende Datei appsettings.Development.json wird von den ASP.NET Core-Web-App-Vorlagen generiert:

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

Für den JSON oben gilt:

  • Die Kategorien "Default", "Microsoft" und "Microsoft.Hosting.Lifetime" werden angegeben.
  • Die Kategorie "Microsoft" gilt für alle Kategorien, die mit "Microsoft" beginnen. Diese Einstellung gilt z. B. für die Kategorie "Microsoft.AspNetCore.Routing.EndpointMiddleware".
  • Die Kategorie "Microsoft" protokolliert mit Protokolliergrad Warning oder höher.
  • Die Kategorie "Microsoft.Hosting.Lifetime" ist genauer als die Kategorie "Microsoft", sodass die Kategorie "Microsoft.Hosting.Lifetime" mit dem Protokolliergrad „Information“ oder höher protokolliert.
  • Ein bestimmter Protokollanbieter wird nicht angegeben, sodass LogLevel für alle aktivierten Protokollanbieter mit Ausnahme von Windows EventLog gilt.

Die Logging-Eigenschaft kann LogLevel und Protokollanbietereigenschaften beinhalten. LogLevel gibt den Mindestgrad an, der für ausgewählte Kategorien protokolliert werden soll. Im JSON-Code oben werden die Protokolliergrade Information und Warning angegeben. LogLevel gibt den Schweregrad des Protokolls an und liegt zwischen 0 und 6:

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

Wenn LogLevel angegeben wird, wird Protokollierung für Meldungen mit dem angegebenen Protokolliergrad oder höher aktiviert. Im JSON-Code oben wird die Kategorie Default für Information oder höher protokolliert. Beispielsweise werden Information-, Warning-, Error- und Critical-Meldungen protokolliert. Wenn kein LogLevel angegeben wird, wird Protokollierung standardmäßig mit dem Protokolliergrad Information verwendet. Weitere Informationen finden Sie unter Protokolliergrade.

Eine Anbietereigenschaft kann eine LogLevel-Eigenschaft angeben. LogLevel unter einem Anbieter gibt die Protokolliergrade an, die für diesen Anbieter protokolliert werden sollen, und überschreibt die Nicht-Anbieterprotokolleinstellungen. Betrachten Sie die folgende appsettings.json -Datei:

{
  "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.
      }
    }
  }
}

Die Einstellungen in Logging.{providername}.LogLevel überschreiben die Einstellungen in Logging.LogLevel. Im JSON-Code oben wird der Standardprotokolliergrad Debug des Anbieters auf Information festgelegt:

Logging:Debug:LogLevel:Default:Information

Die Einstellung oben gibt den Protokolliergrad Information für jede Logging:Debug:-Kategorie mit Ausnahme von Microsoft.Hosting an. Wenn eine bestimmte Kategorie aufgelistet wird, überschreibt die jeweilige Kategorie die Standardkategorie. Im JSON-Code oben überschreiben die Logging:Debug:LogLevel-Kategorien "Microsoft.Hosting" und "Default" die Einstellungen in Logging:LogLevel

Der Mindestprotokolliergrad kann für Folgendes angegeben werden:

  • Bestimmte Anbieter: Beispiel: Logging:EventSource:LogLevel:Default:Information
  • Bestimmte Kategorien: Beispiel: Logging:LogLevel:Microsoft:Warning
  • Alle Anbieter und alle Kategorien: Logging:LogLevel:Default:Warning

Alle Protokolle unterhalb des Mindestprotokolliergrads werden nicht:

  • An den Anbieter übergeben.
  • Protokolliert oder angezeigt.

Um alle Protokolle zu unterdrücken, geben Sie LogLevel.None an. LogLevel.None hat den Wert 6, der höher als LogLevel.Critical (5) ist.

Wenn ein Anbieter Protokollbereiche unterstützt, gibt IncludeScopes an, ob sie aktiviert sind. Weitere Informationen finden Sie unter Protokollierbereiche.

Die folgende Datei appsettings.json enthält alle Anbieter, die standardmäßig aktiviert sind:

{
  "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"
      }
    }
  }
}

Im vorgehenden Beispiel:

  • Die Kategorien und Protokolliergrade sind keine vorgeschlagenen Werte. Das Beispiel wird bereitgestellt, um alle Standardanbieter zu zeigen.
  • Die Einstellungen in Logging.{providername}.LogLevel überschreiben die Einstellungen in Logging.LogLevel. Beispielsweise überschreibt der Protokolliergrad in Debug.LogLevel.Default den Protokolliergrad in LogLevel.Default.
  • Jeder Standardanbieteralias wird verwendet. Jeder Anbieter definiert einen Alias, der in der Konfiguration anstelle des vollqualifizierten Typnamens verwendet werden kann. Die folgenden Anbieteraliase sind integriert:
    • Konsole
    • Debuggen
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

Festlegen des Protokolliergrads über die Befehlszeile, Umgebungsvariablen und andere Konfigurationen

Der Protokolliergrad kann von einem beliebigen Konfigurationsanbieter festgelegt werden.

Das Trennzeichen : funktioniert nicht auf allen Plattformen mit den hierarchischen Schlüsseln von Umgebungsvariablen. Der doppelte Unterstrich __:

  • wird auf allen Plattformen unterstützt. Das Trennzeichen : wird beispielsweise nicht von Bash unterstützt, __ hingegen schon.
  • automatisch durch : ersetzt.

Die folgenden Befehle:

  • Legen den Umgebungsschlüssel Logging:LogLevel:Microsoft auf den Wert Information unter Windows fest.
  • Testen die Einstellungen, wenn eine App verwendet wird, die mit den ASP.NET Core-Webanwendungsvorlagen erstellt wurde. Der dotnet run-Befehl muss im Projektverzeichnis nach der Verwendung von set ausgeführt werden.
set Logging__LogLevel__Microsoft=Information
dotnet run

Die oben gezeigte Umgebungseinstellungen:

  • Werden nur in Prozessen festgelegt, die über das Befehlsfenster gestartet werden, in dem sie festgelegt wurden.
  • Werden nicht von Browsern gelesen, die mit Visual Studio gestartet wurden.

Mit dem folgenden setx-Befehl werden auch der Umgebungsschlüssel und der Wert unter Windows festgelegt. Anders als set werden setx-Einstellungen beibehalten. Der Schalter /M legt die Variable in der Systemumgebung fest. Wenn /M nicht verwendet wird, wird eine Benutzerumgebungsvariable festgelegt.

setx Logging__LogLevel__Microsoft Information /M

Betrachten Sie die folgende appsettings.json -Datei:

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

Der folgende Befehl legt die obige Konfiguration in der Umgebung fest:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

Wählen Sie in Azure App Service auf der Seite Einstellungen > Konfiguration die Option Neue Anwendungseinstellung aus. Anwendungseinstellungen von Azure App Service werden:

  • Im Ruhezustand verschlüsselt und über einen verschlüsselten Kanal übermittelt.
  • Als Umgebungsvariablen verfügbar gemacht.

Weitere Informationen finden Sie unter Azure-Apps: Überschreiben der App-Konfiguration im Azure-Portal.

Weitere Informationen zum Festlegen von ASP.NET Core-Konfigurationswerten mithilfe von Umgebungsvariablen finden Sie unter Umgebungsvariablen. Informationen zur Verwendung anderer Konfigurationsquellen, beispielsweise der Befehlszeile, Azure Key Vault, Azure App Configuration oder anderer Dateiformate, finden Sie unter Konfiguration in ASP.NET Core.

Anwendung von Filterregeln

Wenn ein ILogger<TCategoryName>-Objekt erstellt wird, wählt das ILoggerFactory-Objekt eine einzige Regel pro Anbieter aus, die auf diese Protokollierung angewendet wird. Alle von einer ILogger-Instanz geschriebenen Meldungen werden auf Grundlage der ausgewählten Regeln gefiltert. Aus den verfügbaren Regeln wird die für jeden Anbieter und jedes Kategoriepaar spezifischste Regel ausgewählt.

Beim Erstellen von ILogger für eine vorgegebene Kategorie wird für jeden Anbieter der folgende Algorithmus verwendet:

  • Es werden alle Regeln ausgewählt, die dem Anbieter oder dem zugehörigen Alias entsprechen. Wenn keine Übereinstimmung gefunden wird, werden alle Regeln mit einem leeren Anbieter ausgewählt.
  • Aus dem Ergebnis des vorherigen Schritts werden die Regeln mit dem längsten übereinstimmenden Kategoriepräfix ausgewählt. Wenn keine Übereinstimmung gefunden wird, werden alle Regeln ohne Angabe einer Kategorie ausgewählt.
  • Wenn mehrere Regeln ausgewählt sind, wird die letzte Regel verwendet.
  • Wenn keine Regel ausgewählt ist, wird MinimumLevel verwendet.

Protokollieren der Ausgabe von dotnet run und Visual Studio

Protokolle, die mit den Standardprotokollierungsanbietern erstellt werden, werden angezeigt:

  • In Visual Studio
    • Im Ausgabefenster „Debuggen“ beim Debuggen.
    • Im ASP.NET Core Web Server-Fenster.
  • Im Konsolenfenster, wenn die App mit dotnet run ausgeführt wird.

Protokolle, die mit „Microsoft“-Kategorien beginnen, stammen aus ASP.NET Core-Frameworkcode. ASP.NET Core und Anwendungscode verwenden dieselbe Protokollierungs-API und dieselben Protokollierungsanbieter.

Protokollkategorie

Wenn ein ILogger-Objekt erstellt wird, wird eine Kategorie angegeben. Diese Kategorie ist in jeder Protokollmeldung enthalten, die von dieser Instanz von ILogger erstellt wird. Die Kategoriezeichenfolge ist willkürlich, aber die Konvention besteht darin, den Klassennamen zu verwenden. Beispielsweise kann in einem Controller der Name "TodoApi.Controllers.TodoController" lauten. Die ASP.NET Core-Web-Apps verwenden ILogger<T> zum automatischen Abrufen einer ILogger-Instanz, die den vollqualifizierten Typnamen von T als Kategorie verwendet:

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.");
    }
}

Um die Kategorie explizit anzugeben, rufen Sie ILoggerFactory.CreateLogger auf:

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.");
    }

Das Aufrufen von CreateLogger mit einem festgelegten Namen kann bei Verwendung in mehreren Methoden nützlich sein, damit die Ereignisse nach Kategorie organisiert werden können.

ILogger<T> entspricht dem Aufruf von CreateLogger mit dem vollqualifizierten Typnamen T.

Protokolliergrad

In der folgenden Tabelle werden die LogLevel-Werte, die Erweiterungsmethode Log{LogLevel} und die empfohlene Syntax aufgeführt:

LogLevel Wert Methode BESCHREIBUNG
Ablaufverfolgung 0 LogTrace Enthält die ausführlichsten Meldungen. Diese Meldungen enthalten möglicherweise sensible App-Daten. Sie sind standardmäßig deaktiviert und sollten nicht in einer Produktionsumgebung aktiviert werden.
Debuggen 1 LogDebug Zum Debuggen und für die Entwicklung. Wegen des großen Volumens in der Produktion mit Vorsicht zu verwenden.
Information 2 LogInformation Verfolgt den allgemeinen Ablauf der App nach. Kann über einen langfristigen Wert verfügen.
Warnung 3 LogWarning Für ungewöhnliche oder unerwartete Ereignisse. Schließt in der Regel Fehler oder Bedingungen ein, die nicht bewirken, dass die App fehlschlägt.
Fehler 4 LogError Für Fehler und Ausnahmen, die nicht behandelt werden können. Diese Meldungen weisen auf einen Fehler im aktuellen Vorgang oder der aktuellen Anforderung und nicht auf einen anwendungsweiten Fehler hin.
Critical (Kritisch) 5 LogCritical Für Fehler, die sofortige Aufmerksamkeit erfordern. Beispiel: Szenarios mit Datenverlust, Speichermangel.
Keine 6 Gibt an, dass eine Protokollierungskategorie keine Meldungen schreiben soll.

In der Tabelle oben wird der LogLevel vom niedrigsten bis zum höchsten Schweregrad aufgelistet.

Der erste Parameter der Log-Methode (LogLevel) gibt den Schweregrad des Protokolls an. Anstatt Log(LogLevel, ...) aufzurufen, rufen die meisten Entwickler die Log{LogLevel}-Erweiterungsmethoden auf. Die Log{LogLevel}-Erweiterungsmethoden rufen die Log-Methode auf und geben den LogLevel an. Beispielsweise sind die folgenden beiden Protokollierungsaufrufe funktionell gleichwertig und generieren das gleiche Protokoll:

[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 ist die Ereignis-ID. MyLogEvents ist Teil der Beispiel-App und wird im Abschnitt Log Event ID (Protokollereignis-ID) angezeigt.

MyDisplayRouteInfo und ToCtxString werden über das NuGet-Paket Rick.Docs.Samples.RouteInfo bereitgestellt. Diese Methoden zeigen Controller- und Razor Page-Routeninformationen an.

Der folgende Code erstellt Information- und Warning-Protokolle:

[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);
}

Im Code oben ist der erste Log{LogLevel}-Parameter (MyLogEvents.GetItem) die Protokollereignis-ID. Der zweite Parameter ist eine Meldungsvorlage mit Platzhaltern für Argumentwerte, die von den verbleibenden Methodenparametern bereitgestellt werden. Die Methodenparameter werden im Abschnitt „Meldungsvorlage“ weiter unten in diesem Dokument erläutert.

Rufen Sie die entsprechende Log{LogLevel}-Methode auf, um die Menge an Protokollausgabedaten zu steuern, die in ein bestimmtes Speichermedium geschrieben werden. Zum Beispiel:

  • In einer Produktionsumgebung
    • Das Protokollieren mit den Protokolliergraden Trace oder Information verursacht viele detaillierte Protokollmeldungen. Um die Kosten zu kontrollieren und die Datenspeichergrenzen nicht zu überschreiten, protokollieren Sie Meldungen der Protokolliergrade Trace und Information in einem kostengünstigen Datenspeicher mit hohem Datenvolumen. Erwägen Sie eine Beschränkung von Trace und Information auf bestimmte Kategorien.
    • Bei der Protokollierung mit den Protokolliergraden Warning bis Critical sollten nur wenige Protokollmeldungen generiert werden.
      • Kosten und Speichergrenzwerte stellen in der Regel kein Problem dar.
      • Wenige Protokolle ermöglichen eine größere Flexibilität bei der Auswahl von Datenspeichern.
  • Bei der Entwicklung:
    • Legen Sie Warning fest.
    • Fügen Sie bei der Problembehandlung Trace- oder Information-Meldungen hinzu. Um die Ausgabe einzuschränken, legen Sie Trace oder Information nur für die zu untersuchenden Kategorien fest.

ASP.NET Core schreibt Protokolle für Frameworkereignisse. Berücksichtigen Sie z. B. die Protokollausgabe für Folgendes:

  • Eine Razor Pages-App, die mit den ASP.NET Core-Vorlagen erstellt wurde.
  • Protokollierung festgelegt auf Logging:Console:LogLevel:Microsoft:Information
  • Die Navigation zur Seite 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

Die folgende JSON legt Logging:Console:LogLevel:Microsoft:Information fest:

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

Protokollereignis-ID

Jedes Protokoll kann eine Ereignis-ID angeben. Die Beispiel-App verwendet die MyLogEvents-Klasse zum Definieren von Ereignis-IDs:

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);
}

Eine Ereignis-ID ordnet eine Gruppe von Ereignissen zu. Beispielsweise können alle Protokolle, die sich auf die Anzeige einer Liste von Elementen auf einer Seite beziehen, 1001 sein.

Der Protokollierungsanbieter kann die Ereignis-ID in einem ID-Feld, in der Protokollierungsmeldung oder gar nicht speichern. Der Debuganbieter zeigt keine Ereignis-IDs an. Der Konsolenanbieter zeigt Ereignis-IDs in Klammern hinter der Kategorie an:

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

Einige Protokollierungsanbieter speichern die Ereignis-ID in einem Feld, das das Filtern nach der ID ermöglicht.

Protokollmeldungsvorlage

Jede Protokoll-API verwendet eine Meldungsvorlage. Die Meldungsvorlage kann Platzhalter enthalten, für die Argumente bereitgestellt werden. Verwenden Sie Namen für die Platzhalter, keine Zahlen.

[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);
}

Die Reihenfolge der Parameter, nicht die der Platzhalternamen, bestimmt, welche Parameter verwendet werden, um Platzhalterwerte in Protokollmeldungen bereitzustellen. Im folgenden Code befinden sich die Parameternamen in den Platzhaltern der Meldungsvorlage nicht in der richtigen Reihenfolge:

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

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

Die Parameter werden den Platzhaltern jedoch in der folgenden Reihenfolge zugewiesen: apples, pears, bananas. Die Protokollmeldung spiegelt die Reihenfolge der Parameter wider:

Parameters: 1, 2, 3

Dieser Ansatz ermöglicht es Protokollierungsanbietern, semantische oder strukturierte Protokollierung zu implementieren. Die Argumente selbst (nicht nur die formatierte Meldungsvorlage) werden an das Protokollierungssystem übergeben. Dies ermöglicht es Protokollierungsanbietern, die Parameterwerte als Felder zu speichern. Sehen Sie sich z. B. die folgende Protokollierungsmethode an:

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

Beispielsweise bei der Protokollierung in Azure Table Storage:

  • Jede Azure Table-Entität kann über ID- und RequestTime-Eigenschaften verfügen.
  • Tabellen mit Eigenschaften vereinfachen Abfragen für protokollierte Daten. Beispielsweise kann eine Abfrage alle Protokolle innerhalb eines bestimmten RequestTime-Bereichs ermitteln, ohne die Zeitangabe aus der Textnachricht analysieren zu müssen.

Protokollieren von Ausnahmen

Die Protokollierungsmethoden verfügen über Überladungen, die einen Ausnahmeparameter annehmen:

[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();
}

MyDisplayRouteInfo und ToCtxString werden über das NuGet-Paket Rick.Docs.Samples.RouteInfo bereitgestellt. Diese Methoden zeigen Controller- und Razor Page-Routeninformationen an.

Ausnahmeprotokollierung ist anbieterspezifisch.

Standardprotokolliergrad

Wenn der Standardprotokolliergrad nicht festgelegt ist, ist der Standardwert des Standardprotokolliergrads Information.

Betrachten Sie z. B. die folgende Web-App:

  • Sie wurde mit den ASP.NET-Web-App-Vorlagen erstellt.
  • appsettings.json und appsettings.Development.json wurden gelöscht oder umbenannt.

Mit dem oben beschriebenen Setup generiert die Navigation zur Datenschutz- oder Homepage viele Trace-, Debug- und Information-Meldungen mit Microsoft im Kategorienamen.

Mit dem folgenden Code wird der Standardprotokolliergrad festgelegt, wenn der Standardprotokolliergrad nicht in der Konfiguration festgelegt ist:

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>();
            });
}

Im Allgemeinen sollten Standardprotokolliergrads in der Konfiguration und nicht im Code angegeben werden.

Filterfunktion

Eine Filterfunktion wird für alle Anbieter und Kategorien aufgerufen, denen keine Regeln durch Konfiguration oder Code zugewiesen sind:

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>();
            });
}

Der Code oben zeigt Konsolenprotokolle an, wenn die Kategorie Controller oder Microsoft enthält und der Protokolliergrad Information oder höher ist.

Im Allgemeinen sollten Standardprotokolliergrads in der Konfiguration und nicht im Code angegeben werden.

ASP.NET Core- und EF Core-Kategorien

Die folgende Tabelle enthält einige Kategorien, die von ASP.NET Core und Entity Framework Core verwendet werden, mit Hinweisen zu den Protokollen:

Kategorie Hinweise
Microsoft.AspNetCore Allgemeine ASP.NET Core-Diagnose.
Microsoft.AspNetCore.DataProtection Gibt an, welche Schlüssel in Betracht gezogen, gefunden und verwendet wurden.
Microsoft.AspNetCore.HostFiltering Hosts sind zulässig.
Microsoft.AspNetCore.Hosting Gibt an, wie lange es bis zum Abschluss von HTTP-Anforderungen gedauert hat und zu welcher Zeit sie gestartet wurden. Gibt an, welche Hostingstartassemblys geladen wurden.
Microsoft.AspNetCore.Mvc MVC und Razor-Diagnose Modellbindung, Filterausführung, Ansichtskompilierung, Aktionsauswahl.
Microsoft.AspNetCore.Routing Gibt Routenabgleichsinformationen an.
Microsoft.AspNetCore.Server Start-, Beendigungs- und Keep-Alive-Antworten der Verbindung. HTTPS-Zertifikatinformationen.
Microsoft.AspNetCore.StaticFiles Die bereitgestellten Dateien.
Microsoft.EntityFrameworkCore Allgemeine Entity Framework Core-Diagnose. Datenbankaktivität und -konfiguration, Änderungserkennung, Migrationen.

Wenn Sie weitere Kategorien im Konsolenfenster anzeigen möchten, legen Sie appsettings.Development.json auf Folgendes fest:

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

Protokollbereiche

Ein Bereich kann einen Satz logischer Vorgänge gruppieren. Diese Gruppierung kann verwendet werden, um an jedes Protokoll, das als Teil einer Gruppe erstellt wird, die gleichen Daten anzufügen. So kann beispielsweise jedes Protokoll, das im Rahmen der Verarbeitung einer Transaktion erstellt wird, die Transaktions-ID enthalten.

Ein Bereich:

  • Ist ein IDisposable-Typ, der von der BeginScope-Methode zurückgegeben wird.
  • Er bleibt bestehen, bis er verworfen wird.

Die folgenden Anbieter unterstützen Bereiche:

Verwenden Sie einen Bereich, indem Sie Protokollierungsaufrufe mit einem using-Block umschließen, der als Wrapper verwendet wird:

[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);
}

Integrierte Protokollierungsanbieter

ASP.NET Core enthält die folgenden Protokollierungsanbieter als Teil des freigegebenen Frameworks:

Die folgenden Protokollierungsanbieter werden von Microsoft bereitgestellt, aber nicht als Teil des freigegebenen Frameworks. Sie müssen als zusätzliche NuGet-Pakete installiert werden.

ASP.NET Core enthält keinen Protokollierungsanbieter zum Schreiben von Protokollen in Dateien. Um Protokolle aus einer ASP.NET Core-App in Dateien zu schreiben, erwägen Sie die Verwendung eines Protokollierungsdrittanbieters.

Informationen zu stdout und zum Debuggen der Protokollierung mit dem ASP.NET Core-Modul finden Sie unter Problembehandlung bei ASP.NET Core in Azure App Service und IIS und unter ASP.NET Core-Modul (ANCM) für IIS.

Konsole

Der Console-Anbieter protokolliert die Ausgabe in der Konsole. Weitere Informationen zum Anzeigen von Console-Protokollen in der Entwicklung finden Sie unter Protokollieren der Ausgabe von dotnet run und Visual Studio.

Debuggen

Der Debug-Anbieter schreibt die Protokollausgabe mithilfe der System.Diagnostics.Debug-Klasse. Aufrufe von System.Diagnostics.Debug.WriteLine schreiben in den Debug-Anbieter.

Unter Linux ist der Speicherort des Protokolls des Debug-Anbieters abhängig von der Distribution und kann wie folgt lauten:

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

Ereignisquelle

Der EventSource-Anbieter schreibt in eine plattformübergreifende Ereignisquelle mit dem Namen Microsoft-Extensions-Logging. Unter Windows verwendet der Anbieter die Ereignisablaufverfolgung für Windows (ETW).

dotnet-trace-Tool

Das Tool dotnet-trace ist ein plattformübergreifendes globales Befehlszeilenschnittstellentool zum Sammeln von .NET Core-Ablaufverfolgungen eines ausgeführten Prozesses. Das Tool sammelt Microsoft.Extensions.Logging.EventSource-Anbieterdaten mithilfe einer LoggingEventSource.

Installationsanweisungen finden Sie unter dotnet-trace.

Verwenden Sie das dotnet-trace-Tool, um die Ablaufverfolgung aus einer App zu erfassen:

  1. Führen Sie die App mit dem Befehl dotnet run aus.

  2. Bestimmen Sie den Prozessbezeichner der .NET Core-App:

    dotnet trace ps
    

    Suchen Sie den Prozessbezeichner für den Prozess, der den gleichen Namen wie die App-Assembly hat.

  3. Führen Sie den dotnet trace-Befehl aus.

    Allgemeine Befehlssyntax:

    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}\"
    

    Wenn Sie eine PowerShell-Befehlsshell verwenden, schließen Sie den --providers-Wert in einfache Anführungszeichen (') ein:

    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}\"'
    

    Auf Plattformen, die nicht unter Windows ausgeführt werden, fügen Sie die -f speedscope-Option hinzu, um das Format der Ablaufverfolgungsdatei der Ausgabe in speedscope zu ändern.

    In der folgenden Tabelle wird das Schlüsselwort definiert:

    Schlüsselwort BESCHREIBUNG
    1 Protokolliert Metaereignisse über die LoggingEventSource. Es werden keine Ereignisse von ILogger protokolliert.
    2 Aktiviert das Message-Ereignis, wenn ILogger.Log() aufgerufen wird. Die Informationen werden in einer programmgesteuerten (nicht formatierten) Weise ausgegeben.
    4 Aktiviert das FormatMessage-Ereignis, wenn ILogger.Log() aufgerufen wird. Gibt die formatierte Zeichenfolgeversion der Informationen an.
    8 Aktiviert das MessageJson-Ereignis, wenn ILogger.Log() aufgerufen wird. Stellt eine JSON-Darstellung der Argumente bereit.

    Die folgende Tabelle listet die Anbieterebenen auf:

    Anbieterebene BESCHREIBUNG
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    Die Analyse für eine Kategorieebene kann entweder eine Zeichenfolge oder eine Zahl sein:

    Benannter Wert der Kategorie Numerischer Wert
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    Für die Anbieter- und Kategorieebene gilt:

    • Sie befinden sich in umgekehrter Reihenfolge.
    • Die Zeichenfolgenkonstanten sind nicht alle identisch.

    Wenn keine FilterSpecs angegeben werden, versucht die EventSourceLogger-Implementierung, die Anbieterebene in eine Kategorieebene zu konvertieren, und wendet sie auf alle Kategorien an.

    Anbieterebene Kategorieebene
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    Wenn FilterSpecs angegeben werden, wird für jede in der Liste enthaltene Kategorie die dort codierte Kategorieebene verwendet. Alle anderen Kategorien werden herausgefiltert.

    Bei den folgenden Beispielen wird Folgendes vorausgesetzt:

    • Eine App wird ausgeführt und ruft logger.LogDebug("12345") auf.
    • Die Prozess-ID (PID) wurde über set PID=12345 festgelegt, wobei 12345 der tatsächlichen PID entspricht.

    Betrachten Sie den folgenden Befehl:

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

    Der vorherige Befehl:

    • Erfasst Debugmeldungen.
    • FilterSpecs werden nicht angewendet.
    • Gibt Ebene 5 an, wodurch die Kategorie „Debug“ zugeordnet wird.

    Betrachten Sie den folgenden Befehl:

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

    Der vorherige Befehl:

    • Erfasst keine Debugmeldungen, weil die Kategorieebene 5 Critical lautet.
    • Stellt FilterSpecs bereit.

    Der folgende Befehl erfasst Debugmeldungen, weil Kategorieebene 1 Debug angibt.

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

    Der folgende Befehl erfasst Debugmeldungen, weil die Kategorie Debug angibt.

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

    FilterSpecs-Einträge für {Logger Category} und {Category Level} stellen zusätzliche Protokollfilterbedingungen dar. Trennen Sie FilterSpecs-Einträge durch ein Semikolon (;).

    Beispiel für die Verwendung einer Windows-Befehlsshell:

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

    Mit dem vorangestellten Komma wird Folgendes aktiviert:

    • Die Ereignisquellenprotokollierung zur Erzeugung von formatierten Zeichenfolgen (4) für Fehler (2)
    • Microsoft.AspNetCore.Hosting-Protokollierung auf Informational-Protokollierungsebene (4)
  4. Halten Sie das dotnet-trace-Tool an, indem Sie die EINGABETASTE oder STRG+C drücken.

    Die Ablaufverfolgung wird mit dem Namen trace.nettrace in dem Ordner gespeichert, in dem der dotnet trace-Befehl ausgeführt wird.

  5. Öffnen Sie die Ablaufverfolgung mit Perfview. Öffnen Sie die Datei trace.nettrace, und untersuchen Sie die Ablaufverfolgungsereignisse.

Wenn die App den Host nicht mit CreateDefaultBuilder erstellt, fügen Sie den Ereignisquellenanbieter zur Protokollierungskonfiguration der App hinzu.

Weitere Informationen finden Sie unter:

PerfView

Verwenden Sie das PerfView-Hilfsprogramm zum Sammeln und Anzeigen von Protokollen. Es gibt andere Tools zur Anzeige von ETW-Protokollen, aber PerfView bietet die besten Ergebnisse bei der Arbeit mit ETW-Ereignissen, die von ASP.NET Core ausgegeben werden.

Um PerfView für das Erfassen von Ereignissen zu konfigurieren, die von diesem Anbieter protokolliert wurden, fügen Sie die Zeichenfolge *Microsoft-Extensions-Logging zur Liste Zusätzliche Anbieter hinzu. Vergessen Sie nicht das * am Anfang der Zeichenfolge.

Windows-EventLog

Der EventLog-Anbieter sendet die Protokollausgabe an das Windows-Ereignisprotokoll. Im Gegensatz zu den anderen Anbietern erbt der EventLog-Anbieter nicht die Standardeinstellungen für Nicht-Anbieter. Wenn keine EventLog-Protokolleinstellungen angegeben werden, wird standardmäßig LogLevel.Warning verwendet.

Legen Sie die Protokollierungsebene fest, um Ereignisse, die niedriger als LogLevel.Warning sind, zu protokollieren. Im folgenden Beispiel wird der Standardprotokolliergrad auf LogLevel.Information festgelegt:

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

AddEventLog-Überladungen können EventLogSettings übergeben. Wenn null oder nicht angegeben, werden die folgenden Standardeinstellungen verwendet:

  • LogName: „Anwendung“
  • SourceName: „.NET Runtime“
  • MachineName: Der Name des lokalen Computers wird verwendet.

Der folgende Code ändert SourceName aus dem Standardwert ".NET Runtime" in 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

Das Anbieterpaket Microsoft.Extensions.Logging.AzureAppServices schreibt Protokolle in Textdateien in das Dateisystem einer Azure App Service-App und in Blob Storage in einem Azure Storage-Konto.

Das Anbieterpaket ist nicht im freigegebenen Framework enthalten. Zum Verwenden des Anbieters müssen Sie das Anbieterpaket dem Projekt hinzufügen.

Verwenden Sie AzureFileLoggerOptions und AzureBlobLoggerOptions wie im folgenden Beispiel, um die Anbietereinstellungen zu konfigurieren:

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>();
                });
    }
}

Wenn eine Bereitstellung in Azure App Service erfolgt, verwendet die App die Einstellungen im Abschnitt App Service logs (App Service-Protokolle) auf der Seite App Service im Azure-Portal. Bei einem Update der folgenden Einstellungen werden die Änderungen sofort wirksam, ohne dass ein Neustart oder eine erneute Bereitstellung der App notwendig ist.

  • Anwendungsprotokoll (Dateisystem)
  • Anwendungsprotokoll (Blob)

Der Standardspeicherort für Protokolldateien ist der Ordner D:\home\LogFiles\Application, und der standardmäßige Dateiname lautet diagnostics-yyyymmdd.txt. Die Dateigröße ist standardmäßig auf 10 MB beschränkt, und die maximal zulässige Anzahl beibehaltener Dateien lautet 2. Der Standardblobname lautet {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt.

Der Anbieter führt nur Protokollierung aus, wenn das Projekt in der Azure-Umgebung ausgeführt wird.

Azure-Protokollstreaming

Azure-Protokollstreaming unterstützt das Anzeigen der Protokollaktivität in Echtzeit:

  • App-Server
  • Webserver
  • Ablaufverfolgung für Anforderungsfehler

So konfigurieren Sie das Azure-Protokollstreaming

  • Navigieren Sie von der Portalseite Ihrer App zur Seite App Service-Protokolle.
  • Legen Sie Anwendungsprotokollierung (Dateisystem) auf Ein fest.
  • Wählen Sie die Protokollierungsebene. Diese Einstellung gilt nur für Azure-Protokollstreaming.

Navigieren Sie zur Seite Log Stream (Protokollstream), um Protokolle anzuzeigen. Die protokollierten Nachrichten werden mit der ILogger-Schnittstelle protokolliert.

Azure Application Insights

Das Microsoft.Extensions.Logging.ApplicationInsights-Anbieterpaket schreibt Protokolle in Azure Application Insights. Application Insights ist ein Dienst, der eine Web-App überwacht und Tools für Abfragen und Analysen von Telemetriedaten zur Verfügung stellt. Wenn Sie diesen Anbieter verwenden, können Sie Ihre Protokolle mithilfe der Application Insights-Tools abfragen und analysieren.

Der Protokollierungsanbieter ist als Abhängigkeit von Microsoft.ApplicationInsights.AspNetCore enthalten, d.h. als das Paket, das alle verfügbaren Telemetriedaten für ASP.NET Core bereitstellt. Wenn Sie dieses Paket verwenden, ist nicht erforderlich, das Anbieterpaket zu installieren.

Das Microsoft.ApplicationInsights.Web-Paket bezieht sich auf ASP.NET 4.x, nicht auf ASP.NET Core.

Weitere Informationen finden Sie in den folgenden Ressourcen:

Protokollierungsanbieter von Drittanbietern

Protokollierungsframeworks von Drittanbietern aufgeführt, die mit ASP.NET Core funktionieren:

Einige Drittanbieterframeworks können eine semantische Protokollierung (auch als strukturierte Protokollierung bezeichnet) ausführen.

Die Verwendung eines Frameworks von Drittanbietern ist ähnlich wie die Verwendung eines integrierten Anbieters:

  1. Fügen Sie Ihrem Paket ein NuGet-Paket hinzu.
  2. Rufen Sie eine ILoggerFactory-Erweiterungsmethode auf, die vom Protokollierungsframework bereitgestellt wird.

Weitere Informationen finden Sie in der Dokumentation zum jeweiligen Anbieter. Protokollierungsanbieter von Drittanbietern werden von Microsoft nicht unterstützt.

Nicht-Host-Konsolen-App

Ein Beispiel zum Verwenden des generischen Hosts in einer nicht webbasierten Konsolen-App finden Sie in der Datei Program.cs der Beispiel-App für Hintergrundaufgaben (Hintergrundaufgaben mit gehosteten Diensten in ASP.NET Core).

Das Protokollieren von Code für Apps ohne generischen Host weicht in Bezug auf das Hinzufügen von Anbietern und das Erstellen von Protokollierungen ab.

Protokollierungsanbieter

Rufen Sie in einer Konsolen-App ohne Host die Add{provider name}-Erweiterungsmethode des Anbieters auf, während Sie eine LoggerFactory erstellen:

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");
    }
}

Erstellen von Protokollen

Verwenden Sie zum Erstellen von Protokollen ein ILogger<TCategoryName>-Objekt. Verwenden Sie LoggerFactory, um ein ILogger-Element zu erstellen.

Im folgenden Beispiel wird eine Protokollierung mit LoggingConsoleApp.Program als Kategorie erstellt.

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");
    }
}

Im folgenden Beispiel werden durch die Protokollierung Protokolle mit dem Protokolliergrad Information erstellt. Der Protokollierungsgrad gibt den Schweregrad des protokollierten Ereignisses an.

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");
    }
}

Grade und Kategorien werden in diesem Dokument ausführlicher erläutert.

Protokollierung während der Hosterstellung

Die Protokollierung während der Hosterstellung wird nicht direkt unterstützt. Es kann jedoch eine separate Protokollierung verwendet werden. Im folgenden Beispiel wird eine Serilog-Protokollierung zum Anmelden von CreateHostBuilder verwendet. AddSerilog verwendet die in Log.Logger angegebene statische Konfiguration:

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();
        }
    }
}

Konfigurieren eines Diensts, der von ILogger abhängig ist

Die Konstruktorinjektion einer Protokollierung in Startup funktioniert in früheren Versionen von ASP.NET Core, da für den Webhost ein separater Abhängigkeitsinjektion-Container erstellt wird. Weitere Informationen dazu, warum nur ein Container für den generischen Host erstellt wird, erhalten Sie in der Breaking Change-Ankündigung.

Um einen Dienst zu konfigurieren, der von ILogger<T> abhängt, verwenden Sie die Konstruktorinjektion oder stellen eine Factorymethode bereit. Die Nutzung einer Factorymethode wird nur empfohlen, wenn Sie keine andere Wahl haben. Angenommen, ein Dienst benötigt z. B. eine durch Abhängigkeitsinjektion bereitgestellte ILogger<T>-Instanz:

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

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

Der hervorgehobene Code oben ist eine Func<T,TResult>, die ausgeführt wird, wenn der Abhängigkeitsinjektion-Container eine Instanz von MyService erstellen muss. Auf diese Weise können Sie auf alle registrierten Dienste zugreifen.

Erstellen von Protokollen in Main

Der folgende Code führt Protokollierung in Main aus, indem nach dem Erstellen des Hosts eine ILogger-Instanz von der Abhängigkeitsinjektion abgerufen wird:

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>();
        });

Erstellen von Protokollen in der Startklasse

Der folgende Code schreibt Protokolle in 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();
    });
}

Das Schreiben von Protokollen vor Abschluss der Einrichtung des Abhängigkeitsinjektion-Containers in der Startup.ConfigureServices-Methode wird nicht unterstützt:

  • Die Protokollierungsinjektion in den Startup-Konstruktor wird nicht unterstützt.
  • Die Protokollierungsinjektion in die Startup.ConfigureServices-Methodensignatur wird nicht unterstützt.

Dies Einschränkung ist darauf zurückzuführen, dass die Protokollierung von der Abhängigkeitsinjektion und der Konfiguration abhängt (die wiederum von der Abhängigkeitsinjektion abhängt). Der Abhängigkeitsinjektion-Container wird erst nach Fertigstellung von ConfigureServices eingerichtet.

Informationen zum Konfigurieren eines Diensts, der von ILogger<T> abhängt, oder dazu, warum die Konstruktorinjektion einer Protokollierung in Startup in früheren Versionen funktioniert hat, finden Sie unter Konfigurieren eines Diensts, der von ILogger abhängt.

Keine asynchronen Protokollierungsmethoden

Die Protokollierung sollte so schnell erfolgen, dass sich die Leistungskosten von asynchronem Code nicht lohnen. Wenn ein Protokollierungsdatenspeicher langsam ist, schreiben Sie nicht direkt in diesen. Erwägen Sie, die Protokollnachrichten zunächst in einen schnellen Speicher zu schreiben und sie dann später in den langsamen Speicher zu verschieben. Wenn Sie beispielsweise in SQL Server protokollieren, verwenden Sie nicht direkt eine Log-Methode, da die Log-Methoden synchron sind. Fügen Sie stattdessen die Protokollmeldungen synchron zu einer Warteschlange im Arbeitsspeicher hinzu, und rufen Sie mithilfe eines Hintergrundworkers die Nachrichten aus der Warteschlange ab, um sie dann asynchron per Pushvorgang an SQL Server zu übertragen. Weitere Informationen finden Sie in diesem GitHub-Issue.

Ändern von Protokolliergraden in einer aktuell ausgeführten App

Die Protokollierungs-API umfasst kein Szenario zum Ändern der Protokollebene, während eine App ausgeführt wird. Einige Konfigurationsanbieter können jedoch die Konfiguration erneut laden, was sich unmittelbar auf die Protokollierungskonfiguration auswirkt. Beispielsweise lädt der Dateikonfigurationsanbieter die Protokollierungskonfiguration standardmäßig erneut. Wenn die Konfiguration im Code geändert wird, während eine App ausgeführt wird, kann die App IConfigurationRoot.Reload aufrufen, um ihre Protokollierungskonfiguration zu aktualisieren.

ILogger und ILoggerFactory

Die ILogger<TCategoryName>- und ILoggerFactory-Schnittstellen und -Implementierungen sind im .NET Core SDK enthalten. Sie sind auch in den folgenden NuGet-Paketen verfügbar:

Anwenden von Protokollfilterregeln in Code

Die bevorzugte Vorgehensweise zum Festlegen von Protokollfilterregeln ist die Verwendung von Konfiguration.

Das folgende Beispiel zeigt, wie Filterregeln im Code registriert werden:

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) gibt die System-Kategorie und den Protokolliergrad Debug an. Der Filter wird auf alle Anbieter angewendet, da kein bestimmter Anbieter konfiguriert wurde.

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) gibt Folgendes an:

  • Den Debug-Protokollanbieter.
  • Der Protokolliergrad Information oder höher.
  • Alle Kategorien, die mit "Microsoft" beginnen.

Automatisches Protokollieren des Bereichs mit SpanId, TraceId und ParentId

Die Protokollierungsbibliotheken erstellen implizit ein Bereichsobjekt mit SpanId, TraceId und ParentId. Dieses Verhalten wird über ActivityTrackingOptions konfiguriert.

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

Wenn der HTTP-Anforderungsheader traceparent festgelegt ist, zeigt die ParentId im Protokollbereich die W3C-parent-id aus dem eingehenden traceparent-Header, und die SpanId im Protokollbereich zeigt die aktualisierte parent-id für den nächsten ausgehenden Schritt/Bereich. Weitere Informationen finden Sie unter Verändern des traceparent-Felds.

Erstellen einer benutzerdefinierten Protokollierung

Weitere Informationen zum Erstellen einer benutzerdefinierten Protokollierung finden Sie unter Implementieren eines benutzerdefinierten Protokollierungsanbieters in .NET.

Zusätzliche Ressourcen