Protokollieren in .NET Core und ASP.NET Core

Von Kirk Larkin, Jürgen Gutsch und Rick Anderson

.NET Core unterstützt eine Protokollierungs-API, die mit einer Vielzahl von integrierten Protokollierungsanbietern und Drittanbieter-Protokollierungslösungen zusammenarbeitet. Dieser Artikel zeigt, wie Sie die Protokollierungs-API mit integrierten Anbietern verwenden können.

Die meisten der Codebeispiele in diesem Artikel stammen aus ASP.NET Core-Apps. Die auf die Protokollierung bezogenen Teile dieser Codeausschnitte gelten für jede .NET Core-App, die den generischen Host verwendet. Die ASP.NET Core Web-App-Vorlagen verwenden den generischen Host.

Anzeigen oder Herunterladen von Beispielcode (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.

Weitere Informationen zu Blazor finden Sie unter Erstellen von Protokollen in Blazor und Blazor WebAssembly in diesem Dokument.

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 von 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 oben stehenden JSON-Code 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. Sehen Sie sich die nachfolgende Datei appsettings.json an:

{
  "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
    • Debug
    • 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

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, einschließlich der Befehlszeile, Azure Key Vault, Azure App Configuration, anderer Dateiformate und mehr 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("MyCategory");
    }

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

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-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 diese Option auf 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
  • Navigation Sie zur Seite „Datenschutz“:
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

Der folgende JSON-Code 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 Platzhalter – nicht ihre Namen – bestimmt, welche Parameter verwendet werden, um ihre Werte zur Verfügung zu stellen. Im folgenden Code befinden sich die Parameternamen in der Meldungsvorlage nicht in der richtigen Reihenfolge:

string p1 = "param1";
string p2 = "param2";
_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);

Dieser Code oben erstellt eine Protokollierungsmeldung mit den Parameterwerten in der richtigen Reihenfolge:

Parameter values: param1, param2

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

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

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

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

    return ItemToDTO(todoItem);
}

Der folgende JSON-Code aktiviert Bereiche für den Konsolenanbieter:

{
  "Logging": {
    "Debug": {
      "LogLevel": {
        "Default": "Information"
      }
    },
    "Console": {
      "IncludeScopes": true, // Required to use Scopes.
      "LogLevel": {
        "Microsoft": "Warning",
        "Default": "Information"
      }
    },
    "LogLevel": {
      "Default": "Debug"
    }
  }
}

Der folgende Code aktiviert Bereiche für den Konsolenanbieter:

Im Allgemeinen sollte Protokollierung in der Konfiguration und nicht im Code angegeben werden.

Integrierte Protokollierungsanbieter

ASP.NET Core umfasst die folgenden Protokollierungsanbieter:

Informationen zu stdout und zur Debugprotokollierung mit dem ASP.NET Core-Modul finden Sie unter Problembehandlung bei ASP.NET Core in Azure App Service und IIS und ASP.NET Core-Modul.

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.

Debug

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:

    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}:{Event Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Event Level 1};
                {Logger Category 2}:{Event Level 2};
                ...
                {Logger Category N}:{Event 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}:{Event Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Event Level 1};
                {Logger Category 2}:{Event Level 2};
                ...
                {Logger Category N}:{Event 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.

    Stichwort 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.
    Ereignisgrad Beschreibung
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

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

    Beispiel mit einer Windows-Befehlsshell (keine einfachen Anführungszeichen um den --providers-Wert):

    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 Program.cs-Datei der Beispiel-App für Hintergrundaufgaben (Hintergrundtasks 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");
    }
}

In den folgenden ASP.NET Core-Beispielen werden von der 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, die ausgeführt wird, wenn der Abhängigkeitsinjektionscontainer erstmals 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.

Erstellen einer benutzerdefinierten Protokollierung

Fügen Sie einen ILoggerProvider mit einer ILoggerFactory hinzu, um eine benutzerdefinierte Protokollierung hinzuzufügen:

public void Configure(
    IApplicationBuilder app,
    IWebHostEnvironment env,
    ILoggerFactory loggerFactory)
{
    loggerFactory.AddProvider(new CustomLoggerProvider(new CustomLoggerConfiguration()));

ILoggerProvider erstellt mindestens eine ILogger-Instanz. Die ILogger-Instanzen werden vom Framework zum Protokollieren der Informationen verwendet.

Beispielkonfiguration für benutzerdefinierte Protokollierung

Im Beispiel geschieht Folgendes:

  • Es ist ein sehr einfaches Beispiel, mit dem die Farbe der Protokollkonsole nach Ereignis-ID und Protokolliergrad festgelegt wird. Protokollierungen ändern sich in der Regel nicht anhand der Ereignis-ID und sind nicht spezifisch für den Protokolliergrad.
  • Es werden unterschiedliche Farbkonsoleneinträge pro Protokolliergrad und Ereignis-ID mithilfe des folgenden Konfigurationstyps erstellt:
public class ColorConsoleLoggerConfiguration
{
    public LogLevel LogLevel { get; set; } = LogLevel.Warning;
    public int EventId { get; set; } = 0;
    public ConsoleColor Color { get; set; } = ConsoleColor.Yellow;
}

Der vorangehende Code legt den Standardprotokolliergrad auf Warning und die Farbe auf Yellow fest. Wenn die EventId auf 0 festgelegt ist, werden alle Ereignisse protokolliert.

Erstellen der benutzerdefinierten Protokollierung

Der Kategoriename der ILogger-Implementierung ist in der Regel die Protokollierungsquelle. Beispielsweise der Typ, in dem die Protokollierung erstellt wird:

public class ColorConsoleLogger : ILogger
{
    private readonly string _name;
    private readonly ColorConsoleLoggerConfiguration _config;

    public ColorConsoleLogger(string name, ColorConsoleLoggerConfiguration config)
    {
        _name = name;
        _config = config;
    }

    public IDisposable BeginScope<TState>(TState state)
    {
        return null;
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        return logLevel == _config.LogLevel;
    }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, 
                        Exception exception, Func<TState, Exception, string> formatter)
    {
        if (!IsEnabled(logLevel))
        {
            return;
        }

        if (_config.EventId == 0 || _config.EventId == eventId.Id)
        {
            var color = Console.ForegroundColor;
            Console.ForegroundColor = _config.Color;
            Console.WriteLine($"{logLevel} - {eventId.Id} " +
                              $"- {_name} - {formatter(state, exception)}");
            Console.ForegroundColor = color;
        }
    }
}

Der vorangehende Code:

  • Erstellt eine Protokollierungsinstanz pro Kategoriename.
  • Überprüft logLevel == _config.LogLevel in IsEnabled, sodass jedes logLevel-Element über eine eindeutige Protokollierung verfügt. Protokollierungen sollten im Allgemeinen auch für alle höheren Protokolliergrade aktiviert werden:
public bool IsEnabled(LogLevel logLevel)
{
    return logLevel >= _config.LogLevel;
}

Erstellen des benutzerdefinierten LoggerProvider

LoggerProvider ist die Klasse, mit der die Protokollierungsinstanzen erstellt werden. Möglicherweise ist sie nicht erforderlich, um eine Protokollierungsinstanz pro Kategorie zu erstellen. Dies ist jedoch für einige Protokollierungen sinnvoll, etwa für NLog oder log4net. Auf diese Weise können Sie bei Bedarf auch verschiedene Protokollierungsausgabeziele pro Kategorie auswählen:

public class ColorConsoleLoggerProvider : ILoggerProvider
{
    private readonly ColorConsoleLoggerConfiguration _config;
    private readonly ConcurrentDictionary<string, ColorConsoleLogger> _loggers = new ConcurrentDictionary<string, ColorConsoleLogger>();

    public ColorConsoleLoggerProvider(ColorConsoleLoggerConfiguration config)
    {
        _config = config;
    }

    public ILogger CreateLogger(string categoryName)
    {
        return _loggers.GetOrAdd(categoryName, name => new ColorConsoleLogger(name, _config));
    }

    public void Dispose()
    {
        _loggers.Clear();
    }
}

Im Code oben erstellt CreateLogger eine einzelne Instanz von ColorConsoleLogger pro Kategoriename und speichert sie in ConcurrentDictionary<TKey,TValue>;

Verwendung und Registrierung der benutzerdefinierten Protokollierung

Registrieren Sie die Protokollierung in Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
                      ILoggerFactory loggerFactory)
{
    // Default registration.
    loggerFactory.AddProvider(new ColorConsoleLoggerProvider(
                              new ColorConsoleLoggerConfiguration
    {
        LogLevel = LogLevel.Error,
        Color = ConsoleColor.Red
    }));

    // Custom registration with default values.
    loggerFactory.AddColorConsoleLogger();

    // Custom registration with a new configuration instance.
    loggerFactory.AddColorConsoleLogger(new ColorConsoleLoggerConfiguration
    {
        LogLevel = LogLevel.Debug,
        Color = ConsoleColor.Gray
    });

    // Custom registration with a configuration object.
    loggerFactory.AddColorConsoleLogger(c =>
    {
        c.LogLevel = LogLevel.Information;
        c.Color = ConsoleColor.Blue;
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Geben Sie für den Code oben mindestens eine Erweiterungsmethode für ILoggerFactory an:

public static class ColorConsoleLoggerExtensions
{
    public static ILoggerFactory AddColorConsoleLogger(
                                      this ILoggerFactory loggerFactory, 
                                      ColorConsoleLoggerConfiguration config)
    {
        loggerFactory.AddProvider(new ColorConsoleLoggerProvider(config));
        return loggerFactory;
    }
    public static ILoggerFactory AddColorConsoleLogger(
                                      this ILoggerFactory loggerFactory)
    {
        var config = new ColorConsoleLoggerConfiguration();
        return loggerFactory.AddColorConsoleLogger(config);
    }
    public static ILoggerFactory AddColorConsoleLogger(
                                    this ILoggerFactory loggerFactory, 
                                    Action<ColorConsoleLoggerConfiguration> configure)
    {
        var config = new ColorConsoleLoggerConfiguration();
        configure(config);
        return loggerFactory.AddColorConsoleLogger(config);
    }
}

Zusätzliche Ressourcen

Von Tom Dykstra und Steve Smith

.NET Core unterstützt eine Protokollierungs-API, die mit einer Vielzahl von integrierten Protokollierungsanbietern und Drittanbieter-Protokollierungslösungen zusammenarbeitet. Dieser Artikel zeigt, wie Sie die Protokollierungs-API mit integrierten Anbietern verwenden können.

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Hinzufügen von Anbietern

Ein Protokollierungsanbieter zeigt Protokolle an oder speichert diese. Beispielsweise zeigt der Konsolenanbieter Protokolle in der Konsole an, und der Azure Application Insights-Anbieter speichert sie in Azure Application Insights. Protokolle können durch das Hinzufügen mehrerer Anbieter an mehrere Ziele gesendet werden.

Um einen Anbieter hinzuzufügen, rufen Sie die Add{provider name}-Erweiterungsmethode des Anbieters in Program.cs auf:

public static void Main(string[] args)
{
    var webHost = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            var env = hostingContext.HostingEnvironment;
            config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                  .AddJsonFile($"appsettings.{env.EnvironmentName}.json", 
                      optional: true, reloadOnChange: true);
            config.AddEnvironmentVariables();
        })
        .ConfigureLogging((hostingContext, logging) =>
        {
            // Requires `using Microsoft.Extensions.Logging;`
            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
            logging.AddConsole();
            logging.AddDebug();
            logging.AddEventSourceLogger();
        })
        .UseStartup<Startup>()
        .Build();

    webHost.Run();
}

Der vorstehende Code erfordert Verweise auf Microsoft.Extensions.Logging und Microsoft.Extensions.Configuration.

Die Standardprojektvorlage ruft die Methode CreateDefaultBuilder auf, die die folgenden Protokollierungsanbieter hinzufügt:

  • Konsole
  • Debug
  • EventSource (beginnend mit ASP.NET Core 2.2)
public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();

Bei Verwendung von CreateDefaultBuilder können Sie die Standardanbieter durch Ihre eigene Auswahl ersetzen. Rufen Sie ClearProviders auf, und fügen Sie die gewünschten Anbieter hinzu.

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

    var todoRepository = host.Services.GetRequiredService<ITodoRepository>();
    todoRepository.Add(new Core.Model.TodoItem() { Name = "Feed the dog" });
    todoRepository.Add(new Core.Model.TodoItem() { Name = "Walk the dog" });

    var logger = host.Services.GetRequiredService<ILogger<Program>>();
    logger.LogInformation("Seeded the database.");

    host.Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        });

Informationen zu den integrierten Protokollierungsanbietern sowie zu Protokollierungsanbietern von Drittanbietern finden Sie weiter unten in diesem Artikel.

Erstellen von Protokollen

Verwenden Sie zum Erstellen von Protokollen ein ILogger<TCategoryName>-Objekt. Rufen Sie in einer Web-App oder einem gehosteten Dienst einen ILogger aus der Abhängigkeitsinjektion ab. Verwenden Sie in Konsolen-Apps ohne Host LoggerFactory, um einen ILogger zu erstellen.

Im folgenden ASP.NET Core-Beispiel wird eine Protokollierung mit TodoApiSample.Pages.AboutModel als Kategorie erstellt. Die Protokollkategorie ist eine Zeichenfolge, die jedem Protokoll zugeordnet ist. Die von der Abhängigkeitsinjektion bereitgestellte ILogger<T>-Instanz erstellt Protokolle, die den vollqualifizierten Namen vom Typ T als Kategorie aufweisen.

public class AboutModel : PageModel
{
    private readonly ILogger _logger;

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

In den folgenden Beispielen zu ASP.NET Core und einer Konsolen-App werden von der Protokollierung Protokolle mit dem Protokolliergrad Information erstellt. Der Protokollierungsgrad gibt den Schweregrad des protokollierten Ereignisses an.

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

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

Erstellen von Protokollen in der Startklasse

Zum Schreiben von Protokollen in der Startup-Klasse schließen Sie einen ILogger-Parameter in die Konstruktorsignatur ein:

public class Startup
{
    private readonly ILogger _logger;

    public Startup(IConfiguration configuration, ILogger<Startup> logger)
    {
        Configuration = configuration;
        _logger = logger;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        // Add our repository type
        services.AddSingleton<ITodoRepository, TodoRepository>();
        _logger.LogInformation("Added TodoRepository to services");
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            _logger.LogInformation("In Development environment");
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

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

        app.UseMvc();
    }
}

Erstellen von Protokollen in der Program-Klasse

Zum Schreiben von Protokollen in der Program-Klasse rufen Sie eine ILogger-Instanz aus DI ab:

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

    var todoRepository = host.Services.GetRequiredService<ITodoRepository>();
    todoRepository.Add(new Core.Model.TodoItem() { Name = "Feed the dog" });
    todoRepository.Add(new Core.Model.TodoItem() { Name = "Walk the dog" });

    var logger = host.Services.GetRequiredService<ILogger<Program>>();
    logger.LogInformation("Seeded the database.");

    host.Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        });

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 CreateWebHostBuilder verwendet. AddSerilog verwendet die in Log.Logger angegebene statische Konfiguration:

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

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

    public static IWebHostBuilder CreateWebHostBuilder(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 WebHost.CreateDefaultBuilder(args)
                .ConfigureServices((context, services) =>
                {
                    services.AddMvc();
                })
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddConfiguration(builtConfig);
                })
                .ConfigureLogging(logging =>
                {
                    logging.AddSerilog();
                })
                .UseStartup<Startup>();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host builder error");

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

Keine asynchronen Protokollierungsmethoden

Die Protokollierung sollte so schnell erfolgen, dass sich die Leistungskosten von asynchronem Code nicht lohnen. Wenn Ihr Protokollierungsdatenspeicher langsam ist, schreiben Sie nicht direkt in ihn. 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, möchten Sie dies nicht direkt in einer Log-Methode tun, 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.

Konfiguration

Die Konfiguration von Protokollierungsanbietern erfolgt durch mindestens einen Konfigurationsanbieter:

  • Dateiformate (INI, JSON und XML)
  • Befehlszeilenargumenten
  • Umgebungsvariablen.
  • Speicherinterne .NET-Objekte
  • Der unverschlüsselte Speicher von Secret Manager.
  • Ein unverschlüsselter Benutzerspeicher, z.B. Azure Key Vault.
  • Benutzerdefinierte Anbieter (installiert oder erstellt).

Die Konfiguration der Protokollierung wird meist vom Logging-Abschnitt von Anwendungseinstellungsdateien angegeben. Im folgenden Beispiel werden die Inhalte einer herkömmlichen appsettings.Development.json-Datei veranschaulicht:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    },
    "Console":
    {
      "IncludeScopes": true
    }
  }
}

Die Logging-Eigenschaft kann den LogLevel und Protokollanbietereigenschaften beinhalten (Konsole wird angezeigt).

Die LogLevel-Eigenschaft unter Logging gibt den Mindestgrad an, der für ausgewählte Kategorien protokolliert werden soll. Im Beispiel protokollieren die Kategorien System und Microsoft mit dem Grad Information und alle anderen Kategorien mit dem Grad Debug.

Weitere Eigenschaften unter Logging geben Protokollierungsanbieter an. Das Beispiel bezieht sich auf den Konsolenanbieter. Wenn ein Anbieter Protokollbereiche unterstützt, gibt IncludeScopes an, ob sie aktiviert sind. Eine Anbietereigenschaft (z.B. Console im Beispiel) kann auch eine LogLevel-Eigenschaft angeben. LogLevel unter einem Anbieter gibt die Grade an, die für diesen Anbieter protokolliert werden sollen.

Wenn Grade in Logging.{providername}.LogLevel angegeben werden, überschreiben sie alle Angaben in Logging.LogLevel. Betrachten Sie beispielsweise den folgenden JSON-Code:

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

Im JSON-Code oben wird der vorherige Protokolliergrad (Standardprotokolliergrad) durch die Console-Anbietereinstellungen überschrieben.

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, der durch CreateDefaultBuilder zum Lesen von Einstellungsdateien hinzugefügt wird, 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.

Informationen zur Implementierung von Konfigurationsanbieter finden Sie hier: Konfiguration in ASP.NET Core.

Beispiel einer Protokollierungsausgabe

Mit dem im vorherigen Abschnitt gezeigten Beispielcode werden Protokolle in der Konsole angezeigt, wenn die Anwendung über die Befehlszeile ausgeführt wird. Hier ein Beispiel für eine Konsolenausgabe:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/api/todo/0
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action method TodoApi.Controllers.TodoController.GetById (TodoApi) with arguments (0) - ModelState is Valid
info: TodoApi.Controllers.TodoController[1002]
      Getting item 0
warn: TodoApi.Controllers.TodoController[4000]
      GetById(0) NOT FOUND
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
      Executing HttpStatusCodeResult, setting HTTP status code 404
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action TodoApi.Controllers.TodoController.GetById (TodoApi) in 42.9286ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 148.889ms 404

Die vorherigen Protokolle wurden generiert, indem eine HTTP Get-Anforderung an die Beispiel-App unter http://localhost:5000/api/todo/0 vorgenommen wurde.

Nachfolgend sehen Sie, wie die gleichen Protokolle im Debugfenster angezeigt werden, wenn Sie die Beispiel-App in Visual Studio ausführen:

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:53104/api/todo/0  
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executing action method TodoApi.Controllers.TodoController.GetById (TodoApi) with arguments (0) - ModelState is Valid
TodoApi.Controllers.TodoController:Information: Getting item 0
TodoApi.Controllers.TodoController:Warning: GetById(0) NOT FOUND
Microsoft.AspNetCore.Mvc.StatusCodeResult:Information: Executing HttpStatusCodeResult, setting HTTP status code 404
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action TodoApi.Controllers.TodoController.GetById (TodoApi) in 152.5657ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 316.3195ms 404

Die über die ILogger-Aufrufe aus dem vorherigen Abschnitt erstellten Protokolle beginnen mit „TodoApi“. Protokolle, die mit Microsoft-Kategorien beginnen, stammen aus ASP.NET Core-Frameworkcode. ASP.NET Core und Anwendungscode verwenden dieselbe Protokollierungs-API und dieselben Protokollierungsanbieter.

In den übrigen Abschnitten dieses Artikels werden einige Details und Optionen für die Protokollierung erläutert.

NuGet-Pakete

Die Schnittstellen ILogger und ILoggerFactory befinden sich in Microsoft.Extensions.Logging.Abstractions, ihre Standardimplementierungen sind in Microsoft.Extensions.Logging enthalten.

Protokollkategorie

Wenn ein ILogger-Objekt erstellt wird, wird eine Kategorie für dieses Objekt angegeben. Diese Kategorie ist in jeder Protokollmeldung enthalten, die von dieser Instanz von ILogger erstellt wird. Die Kategorie kann eine beliebige Zeichenfolge sein, aber die Konvention besteht in der Verwendung des Klassennamens, z.B. „TodoApi.Controllers.TodoController“.

Verwenden Sie ILogger<T> zum Abrufen einer ILogger-Instanz, die den vollqualifizierten Typnamen von T als Kategorie verwendet:

public class TodoController : Controller
{
    private readonly ITodoRepository _todoRepository;
    private readonly ILogger _logger;

    public TodoController(ITodoRepository todoRepository,
        ILogger<TodoController> logger)
    {
        _todoRepository = todoRepository;
        _logger = logger;
    }

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

public class TodoController : Controller
{
    private readonly ITodoRepository _todoRepository;
    private readonly ILogger _logger;

    public TodoController(ITodoRepository todoRepository,
        ILoggerFactory logger)
    {
        _todoRepository = todoRepository;
        _logger = logger.CreateLogger("TodoApiSample.Controllers.TodoController");
    }

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

Protokolliergrad

Jedes Protokoll gibt einen LogLevel-Wert an. Der Protokolliergrad gibt den Schweregrad oder die Wichtigkeit an. Sie können beispielsweise ein Information-Protokoll schreiben, wenn eine Methode normal endet, und ein Warning-Protokoll, wenn eine Methode den Statuscode 404 Not Found zurückgibt.

Der folgende Code erstellt Information- und Warning-Protokolle:

public IActionResult GetById(string id)
{
    _logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
    var item = _todoRepository.Find(id);
    if (item == null)
    {
        _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
        return NotFound();
    }
    return new ObjectResult(item);
}

Im Code oben sind die Parameter MyLogEvents.GetItem und MyLogEvents.GetItemNotFound 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 „Protokollmeldungsvorlage“ in diesem Artikel erläutert.

Protokollmethoden, die den Protokolliergrad im Methodennamen enthalten (z.B. LogInformation und LogWarning), sind Erweiterungsmethoden für ILogger. Diese Methoden rufen eine Log-Methode auf, die einen LogLevel-Parameter annimmt. Sie können anstelle eines Aufrufs dieser Erweiterungsmethoden die Log-Methode direkt aufrufen, aber die Syntax ist relativ kompliziert. Weitere Informationen finden Sie unter ILogger und im Quellcode für Protokollierungserweiterungen.

ASP.NET Core definiert die folgenden Protokolliergrade. Die Reihenfolge reicht vom geringsten bis zum höchsten Schweregrad.

  • Trace = 0

    Protokolliert Informationen, die in der Regel nur für das Debuggen nützlich sind. Diese Meldungen können sensible Anwendungsdaten enthalten und sollten daher nicht in einer Produktionsumgebung aktiviert werden. Standardmäßig deaktiviert.

  • Debug = 1

    Protokolliert Informationen, die bei der Entwicklung und beim Debuggen hilfreich sein können. Beispiel: Entering method Configure with flag set to true. Aktivieren Sie Protokolle mit dem Protokolliergrad Debug aufgrund des hohen Protokollaufkommens nur zur Problembehandlung in der Produktion.

  • Information = 2

    Zur Nachverfolgung des allgemeinen Ablaufs der App. Diese Protokolle haben typischerweise einen langfristigen Nutzen. Ein Beispiel: Request received for path /api/todo

  • Warning = 3

    Für ungewöhnliche oder unerwartete Ereignisse im App-Verlauf. Dazu können Fehler oder andere Bedingungen gehören, die zwar nicht zum Beenden der App führen, aber eventuell untersucht werden müssen. Behandelte Ausnahmen sind eine typische Verwendung für den Protokolliergrad Warning. Ein Beispiel: FileNotFoundException for file quotes.txt.

  • Error = 4

    Für Fehler und Ausnahmen, die nicht behandelt werden können. Diese Meldungen weisen auf einen Fehler in der aktuellen Aktivität oder im aktuellen Vorgang (z.B. in der aktuellen HTTP-Anforderung) und nicht auf einen anwendungsweiten Fehler hin. Beispielprotokollmeldung: Cannot insert record due to duplicate key violation.

  • Critical = 5

    Für Fehler, die sofortige Aufmerksamkeit erfordern. Beispiel: Szenarios mit Datenverlust, Speichermangel.

Verwenden Sie den Protokolliergrad, um die Menge an Protokollausgabedaten zu steuern, die in ein bestimmtes Speichermedium geschrieben oder an ein Anzeigefenster ausgegeben werden. Zum Beispiel:

  • In einer Produktionsumgebung
    • Das Protokollieren von Trace über die Information-Ebenen verursacht viele detaillierte Protokollmeldungen. Protokollieren Sie Trace über Nachrichten auf Information-Ebene in einem kostengünstigen Speicher mit hohem Volumen, um die Kosten zu überwachen und die Grenzwerte des Datenspeichers nicht zu überschreiten.
    • Das Protokollieren von Warning über die Critical-Ebenen verursacht weniger und kürzere Protokollmeldungen. Daher müssen Sie sich über Kosten- und Speichergrenzwerte keine Sorgen machen und sind bei der Auswahl des Datenspeichers flexibler.
  • Entwicklungsphase:
    • Protokollieren Sie Warning über Critical-Meldungen an der Konsole.
    • Fügen Sie bei der Fehlerbehebung Trace über Information-Meldungen hinzu.

Im Abschnitt Protokollfilterung weiter unten in diesem Artikel wird erläutert, wie Sie steuern, welche Protokolliergrade ein Anbieter verarbeitet.

ASP.NET Core schreibt Protokolle für Frameworkereignisse. Die zuvor in diesem Artikel gezeigten Protokollbeispiele enthielten Protokolle unterhalb des Protokolliergrads Information, deshalb wurden keine Protokolle des Protokolliergrads Debug oder Trace erstellt. Hier ist ein Beispiel für Konsolenprotokolle, die durch Ausführen der Beispiel-App generiert werden, die so konfiguriert ist, dass sie Debug-Protokolle anzeigt:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:62555/api/todo/0
dbug: Microsoft.AspNetCore.Routing.Tree.TreeRouter[1]
      Request successfully matched the route with name 'GetTodo' and template 'api/Todo/{id}'.
dbug: Microsoft.AspNetCore.Mvc.Internal.ActionSelector[2]
      Action 'TodoApi.Controllers.TodoController.Update (TodoApi)' with id '089d59b6-92ec-472d-b552-cc613dfd625d' did not match the constraint 'Microsoft.AspNetCore.Mvc.Internal.HttpMethodActionConstraint'
dbug: Microsoft.AspNetCore.Mvc.Internal.ActionSelector[2]
      Action 'TodoApi.Controllers.TodoController.Delete (TodoApi)' with id 'f3476abe-4bd9-4ad3-9261-3ead09607366' did not match the constraint 'Microsoft.AspNetCore.Mvc.Internal.HttpMethodActionConstraint'
dbug: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action TodoApi.Controllers.TodoController.GetById (TodoApi)
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action method TodoApi.Controllers.TodoController.GetById (TodoApi) with arguments (0) - ModelState is Valid
info: TodoApi.Controllers.TodoController[1002]
      Getting item 0
warn: TodoApi.Controllers.TodoController[4000]
      GetById(0) NOT FOUND
dbug: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action method TodoApi.Controllers.TodoController.GetById (TodoApi), returned result Microsoft.AspNetCore.Mvc.NotFoundResult.
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
      Executing HttpStatusCodeResult, setting HTTP status code 404
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action TodoApi.Controllers.TodoController.GetById (TodoApi) in 0.8788ms
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
      Connection id "0HL6L7NEFF2QD" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 2.7286ms 404

Protokollereignis-ID

Jedes Protokoll kann eine Ereignis-ID angeben. Die Beispiel-App verwendet hierzu eine lokal definierte LoggingEvents-Klasse:

public IActionResult GetById(string id)
{
    _logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
    var item = _todoRepository.Find(id);
    if (item == null)
    {
        _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
        return NotFound();
    }
    return new ObjectResult(item);
}
public class LoggingEvents
{
    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 GetItemNotFound = 4000;
    public const int UpdateItemNotFound = 4001;
}

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.TodoController[1002]
      Getting item invalidid
warn: TodoApi.Controllers.TodoController[4000]
      GetById(invalidid) NOT FOUND

Protokollmeldungsvorlage

Jedes Protokoll gibt eine Meldungsvorlage an. Die Meldungsvorlage kann Platzhalter enthalten, für die Argumente bereitgestellt werden. Verwenden Sie Namen für die Platzhalter, keine Zahlen.

public IActionResult GetById(string id)
{
    _logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
    var item = _todoRepository.Find(id);
    if (item == null)
    {
        _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
        return NotFound();
    }
    return new ObjectResult(item);
}

Die Reihenfolge der Platzhalter – nicht ihre Namen – bestimmt, welche Parameter verwendet werden, um ihre Werte zur Verfügung zu stellen. Beachten Sie im folgenden Code, dass die Parameternamen in der Meldungsvorlage nicht in der richtigen Reihenfolge vorhanden sind:

string p1 = "parm1";
string p2 = "parm2";
_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);

Dieser Code erstellt eine Protokollierungsmeldung mit den Parameterwerten in der richtigen Reihenfolge:

Parameter values: parm1, parm2

Das Protokollierungsframework funktioniert auf diese Weise, damit Protokollierungsanbieter semantische Protokollierung, die auch als strukturierte Protokollierung bezeichnet wird, implementieren können. Die Argumente selbst (nicht nur die formatierte Meldungsvorlage) werden an das Protokollierungssystem übergeben. Diese Informationen ermöglichen es Protokollierungsanbietern, die Parameterwerte als Felder zu speichern. Nehmen wir zum Beispiel an, dass Aufrufe von Protokollierungsmethoden folgendermaßen aussehen:

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

Wenn Sie die Protokolle an Azure Table Storage senden, kann jede Azure Table-Entität die Eigenschaften ID und RequestTime aufweisen. Dies vereinfacht die Abfrage von Protokolldaten. Eine Abfrage kann alle Protokolle in einem bestimmten RequestTime-Bereich finden, ohne die Uhrzeit aus den Textmeldungen zu analysieren.

Protokollieren von Ausnahmen

Die Protokollierungsmethoden umfassen Überladungen, die das Übergeben von Ausnahmen ermöglichen, wie im folgenden Beispiel gezeigt:

catch (Exception ex)
{
    _logger.LogWarning(LoggingEvents.GetItemNotFound, ex, "GetById({Id}) NOT FOUND", id);
    return NotFound();
}
return new ObjectResult(item);

Die verschiedenen Anbieter verarbeiten die Ausnahmeinformationen auf unterschiedliche Weise. Hier sehen Sie ein Beispiel einer Debuganbieterausgabe aus dem obigen Codebeispiel.

TodoApiSample.Controllers.TodoController: Warning: GetById(55) NOT FOUND

System.Exception: Item not found exception.
   at TodoApiSample.Controllers.TodoController.GetById(String id) in C:\TodoApiSample\Controllers\TodoController.cs:line 226

Protokollfilterung

Sie können einen Mindestprotokolliergrad für einen bestimmten Anbieter und eine bestimmte Kategorie oder für alle Anbieter oder alle Kategorien festlegen. Alle Protokolle unter dem Mindestgrad werden nicht an diesen Anbieter weitergeleitet, sodass sie nicht angezeigt oder gespeichert werden.

Wenn Sie alle Protokolle unterdrücken möchten, geben Sie LogLevel.None als Mindestprotokolliergrad an. Der ganzzahlige Wert von LogLevel.None lautet 6 und liegt über LogLevel.Critical (5).

Erstellen von Filterregeln in der Konfiguration

Der Projektvorlagencode ruft CreateDefaultBuilder auf, um die Protokollierung für die Konsolen-, Debug- und EventSource-Anbieter (ASP.NET Core 2.2 oder höher) einzurichten. Die CreateDefaultBuilder-Methode richtet die Protokollierung ein, um nach der Konfiguration in einem Logging-Abschnitt zu suchen; dies wird weiter oben in diesem Artikel erläutert.

Die Konfigurationsdaten geben die Mindestprotokolliergrade nach Anbieter und Kategorie an, wie im folgenden Beispiel gezeigt:

{
  "Logging": {
    "Debug": {
      "LogLevel": {
        "Default": "Information"
      }
    },
    "Console": {
      "IncludeScopes": false,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "Default": "Information"
      }
    },
    "LogLevel": {
      "Default": "Debug"
    }
  }
}

Diese JSON-Konfiguration erstellt sechs Filterregeln: eine für den Debuganbieter, vier für den Konsolenanbieter und eine für alle Anbieter. Eine einzelne Regel wird für jeden Anbieter ausgewählt, wenn ein ILogger-Objekt erstellt wird.

Filterregeln im Code

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

WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
    .ConfigureLogging(logging =>
        logging.AddFilter("System", LogLevel.Debug)
               .AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Trace));

Das zweite AddFilter gibt den Debuganbieter durch Verwendung des zugehörigen Typnamens an. Das erste AddFilter gilt für alle Anbieter, weil kein Anbietertyp angegeben wird.

Anwendung von Filterregeln

Die Konfigurationsdaten und der in den vorangegangenen Beispielen gezeigte AddFilter-Code erzeugen die in der folgenden Tabelle gezeigten Regeln. Die ersten sechs Regeln stammen aus dem Konfigurationsbeispiel, die letzten zwei Filter stammen aus dem Codebeispiel.

Anzahl Anbieter Kategorien beginnend mit... Mindestprotokolliergrad
1 Debug Alle Kategorien Information
2 Konsole Microsoft.AspNetCore.Mvc.Razor.Internal Warnung
3 Konsole Microsoft.AspNetCore.Mvc.Razor.Razor Debug
4 Konsole Microsoft.AspNetCore.Mvc.Razor Fehler
5 Konsole Alle Kategorien Information
6 Alle Anbieter Alle Kategorien Debug
7 Alle Anbieter System Debug
8 Debug Microsoft Ablaufverfolgung

Wenn ein ILogger-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.

Angenommen, Sie erstellen mit der oben aufgeführten Liste mit Regeln ein ILogger-Objekt für die Kategorie „Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine“:

  • Für den Debuganbieter gelten die Regeln 1, 6 und 8. Regel 8 ist die spezifischste Regel, deshalb wird diese Regel ausgewählt.
  • Für den Konsolenanbieter gelten die Regeln 3, 4, 5 und 6. Regel 3 ist die spezifischste Regel.

Die sich ergebende ILogger-Instanz sendet Protokolle mit dem Protokolliergrad Trace und höher an den Debuganbieter. Protokolle mit dem Protokolliergrad Debug und höher werden an den Konsolenanbieter gesendet.

Anbieteraliase

Jeder Anbieter definiert einen Alias, der in der Konfiguration anstelle des vollqualifizierten Typnamens verwendet werden kann. Verwenden Sie für die integrierten Anbieter die folgenden Aliase:

  • Konsole
  • Debug
  • EventSource
  • EventLog
  • TraceSource
  • AzureAppServicesFile
  • AzureAppServicesBlob
  • ApplicationInsights

Standardmindestprotokolliergrad

Es gibt eine Einstellung für den Mindestprotokolliergrad, die nur dann wirksam wird, wenn für einen bestimmten Anbieter und eine bestimmte Kategorie keine Regeln aus Konfiguration oder Code gelten. Im folgenden Beispiel wird das Festlegen des Mindestprotokolliergrads veranschaulicht:

WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
    .ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Warning));

Wenn Sie den Mindestprotokolliergrad nicht explizit festlegen, lautet der Standardwert Information, d.h. Protokolle der Ebene Trace und Debug werden ignoriert.

Filterfunktionen

Eine Filterfunktion wird für alle Anbieter und Kategorien aufgerufen, denen keine Regeln durch Konfiguration oder Code zugewiesen sind. Code in der Funktion verfügt über Zugriff auf den Anbietertyp, die Kategorie und den Protokolliergrad. Zum Beispiel:

WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
    .ConfigureLogging(logBuilder =>
    {
        logBuilder.AddFilter((provider, category, logLevel) =>
        {
            if (provider == "Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider" &&
                category == "TodoApiSample.Controllers.TodoController")
            {
                return false;
            }
            return true;
        });
    });

Systemkategorien und -protokolliergrade

Dies sind einige Kategorien, die vom ASP.NET Core und Entity Framework Core verwendet werden, mit Hinweisen darauf, welche Protokolle von ihnen zu erwarten sind:

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.

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 und so lange beibehalten wird, bis er verworfen wird. Verwenden Sie einen Bereich, indem Sie Protokollierungsaufrufe mit einem using-Block umschließen, der als Wrapper verwendet wird:

public IActionResult GetById(string id)
{
    TodoItem item;
    using (_logger.BeginScope("Message attached to logs created in the using block"))
    {
        _logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
        item = _todoRepository.Find(id);
        if (item == null)
        {
            _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
            return NotFound();
        }
    }
    return new ObjectResult(item);
}

Der folgende Code aktiviert Bereiche für den Konsolenanbieter:

Program.cs:

.ConfigureLogging((hostingContext, logging) =>
{
    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
    logging.AddConsole(options => options.IncludeScopes = true);
    logging.AddDebug();
})

Hinweis

Um die bereichsbasierte Protokollierung zu aktivieren, muss die Konsolenprotokollierungsoption IncludeScopes konfiguriert werden.

Weitere Informationen zur Konfiguration finden Sie im Abschnitt Konfiguration.

Jede Protokollmeldung enthält die bereichsbezogenen Informationen:

info: TodoApiSample.Controllers.TodoController[1002]
      => RequestId:0HKV9C49II9CK RequestPath:/api/todo/0 => TodoApiSample.Controllers.TodoController.GetById (TodoApi) => Message attached to logs created in the using block
      Getting item 0
warn: TodoApiSample.Controllers.TodoController[4000]
      => RequestId:0HKV9C49II9CK RequestPath:/api/todo/0 => TodoApiSample.Controllers.TodoController.GetById (TodoApi) => Message attached to logs created in the using block
      GetById(0) NOT FOUND

Integrierte Protokollierungsanbieter

ASP.NET Core wird mit den folgenden Anbietern bereitgestellt:

Weitere Informationen zu „stdout“ und zur Debugprotokollierung mit dem ASP.NET Core-Modul finden Sie unter Problembehandlung bei ASP.NET Core in Azure App Service und IIS und ASP.NET Core-Modul.

Der Konsolenanbieter

Das Anbieterpaket Microsoft.Extensions.Logging.Console sendet eine Protokollausgabe an die Konsole.

logging.AddConsole();

Um die Ausgabe der Konsolenprotokollierung anzuzeigen, öffnen Sie eine Eingabeaufforderung im Projektordner und führen den folgenden Befehl aus:

dotnet run

Der Debuganbieter

Beim Anbieterpaket Microsoft.Extensions.Logging.Debug erfolgt die Protokollausgabe unter Verwendung der Klasse System.Diagnostics.Debug (Debug.WriteLine-Methodenaufrufe).

Unter Linux werden Protokolle dieses Anbieters in /var/log/message geschrieben.

logging.AddDebug();

Ereignisquellenanbieter

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

logging.AddEventSourceLogger();

Der Ereignisquellenanbieter wird automatisch hinzugefügt, wenn CreateDefaultBuilder zum Erstellen des Hosts aufgerufen wird.

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 Sternchen am Anfang der Zeichenfolge.)

Zusätzliche PerfView-Anbieter

Der Windows-EventLog-Anbieter

Das Anbieterpaket Microsoft.Extensions.Logging.EventLog sendet eine Protokollausgabe in das Windows-Ereignisprotokoll.

logging.AddEventLog();

Mithilfe von AddEventLog-Überladungen können Sie 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.

Ereignisse werden für die Warnstufe und höher protokolliert. Im folgenden Beispiel wird der Standardprotokolliergrad auf LogLevel.Information festgelegt:

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

Der TraceSource-Anbieter

Das Anbieterpaket Microsoft.Extensions.Logging.TraceSource verwendet die TraceSource-Bibliotheken und -Anbieter.

logging.AddTraceSource(sourceSwitchName);

Mithilfe von AddTraceSource-Überladungen können Sie eine Quelloption und einen Listener für die Ablaufverfolgung übergeben.

Um diesen Anbieter zu verwenden, muss eine App unter .NET Framework (anstelle von .NET Core) ausgeführt werden. Der Anbieter kann Nachrichten an eine Vielzahl von Listenern weiterleiten, z.B. an den in der Beispiel-App verwendeten TextWriterTraceListener.

Der Azure App Service-Anbieter

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.

logging.AddAzureWebAppDiagnostics();

Dieses Anbieterpaket ist nicht im Microsoft.AspNetCore.App-Metapaket enthalten. Wenn Sie Anwendungen für .NET Framework entwickeln oder auf das Microsoft.AspNetCore.App-Metapaket verweisen, fügen Sie das Anbieterpaket dem Projekt hinzu.

Eine AddAzureWebAppDiagnostics-Überladung ermöglicht das Übergeben von AzureAppServicesDiagnosticsSettings. Das settings-Objekt kann Standardeinstellungen überschreiben, z.B. die Protokollierungsausgabevorlage, den Blobnamen und die maximale Dateigröße. (Die Ausgabevorlage ist eine Nachrichtenvorlage, die auf alle Protokolle zusätzlich zu dem angewendet wird, was mit einem ILogger-Methodenaufruf bereitgestellt wird.)

Wenn Sie eine Bereitstellung in einer App Service-App durchführen, berücksichtigt die Anwendung die Einstellungen im Abschnitt App Service logs (App Service-Protokolle) auf der Seite App Services 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 funktioniert nur, wenn das Projekt in der Azure-Umgebung ausgeführt wird. Bei einer lokalen Ausführung zeigt er keine Auswirkungen. Der Anbieter schreibt keine Protokolle in lokale Dateien oder den lokalen Entwicklungsspeicher für BLOBs.

Azure-Protokollstreaming

Azure-Protokollstreaming ermöglicht Ihnen eine Echtzeitanzeige der Protokollaktivität für:

  • 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 das Azure-Protokollstreaming, nicht für andere Protokollierungsanbieter in der App.

Navigieren Sie zur Seite Log Stream (Protokollstream), um App-Meldungen anzuzeigen. Diese werden von der App über die ILogger-Schnittstelle protokolliert.

Ablaufverfolgungsprotokollierung für 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.

Verwenden Sie nicht das Microsoft.ApplicationInsights.Web-Paket, das für ASP.NET 4.x bestimmt ist.

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.

Zusätzliche Ressourcen