Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Als Autor einer Bibliothek ist es eine großartige Möglichkeit, die Protokollierung offenzulegen, um den Verbrauchern einen Einblick in die Funktionsweise Ihrer Bibliothek zu bieten. Dieser Leitfaden hilft Ihnen, die Protokollierung auf eine Weise verfügbar zu machen, die mit anderen .NET-Bibliotheken und Frameworks konsistent ist. Es hilft Ihnen auch, häufige Leistungsengpässe zu vermeiden, die andernfalls nicht offensichtlich sind.
Wann die Schnittstelle ILoggerFactory verwendet werden soll
Beim Schreiben einer Bibliothek, die Protokolle ausgibt, benötigen Sie ein ILogger Objekt, um die Protokolle aufzuzeichnen. Um dieses Objekt abzurufen, kann Ihre API entweder einen ILogger<TCategoryName> Parameter akzeptieren oder einen ILoggerFactory akzeptieren, danach rufen Sie ILoggerFactory.CreateLogger auf. Welcher Ansatz sollte bevorzugt werden?
Wenn Sie ein Protokollierungsobjekt benötigen, das an mehrere Klassen übergeben werden kann, damit alle Protokolle ausgeben können, verwenden Sie
ILoggerFactory. Es wird empfohlen, dass jede Klasse Protokolle mit einer separaten Kategorie erstellt, die identisch mit der Klasse ist. Dazu benötigen Sie die Factory, um eindeutigeILogger<TCategoryName>Objekte für jede Klasse zu erstellen, die Protokolle ausgibt. Häufige Beispiele sind öffentliche Einstiegspunkt-APIs für eine Bibliothek oder öffentliche Konstruktoren von Typen, die Hilfsklassen intern erstellen können.Wenn Sie ein Protokollierungsobjekt benötigen, das nur innerhalb einer Klasse verwendet und nie freigegeben wird, verwenden Sie
ILogger<TCategoryName>, wobeiTCategoryNameder Typ ist, der die Protokolle erzeugt. Ein gängiges Beispiel hierfür ist ein Konstruktor für eine Klasse, die durch Abhängigkeitsinjektion erstellt wurde.
Wenn Sie eine öffentliche API entwerfen, die im Laufe der Zeit stabil bleiben muss, denken Sie daran, dass Sie ihre interne Implementierung in Zukunft umgestalten möchten. Auch wenn eine Klasse anfänglich keine internen Hilfstypen erstellt, kann dies sich ändern, wenn sich der Code weiterentwickelt. Die Verwendung ILoggerFactory bietet Platz für das Erstellen neuer ILogger<TCategoryName> Objekte für alle neuen Klassen, ohne die öffentliche API zu ändern.
Weitere Informationen finden Sie unter Anwenden von Filterregeln.
Bevorzugen der aus der Quelle generierten Protokollierung
Die ILogger API unterstützt zwei Ansätze für die Verwendung der API. Sie können Methoden wie LoggerExtensions.LogError und LoggerExtensions.LogInformation aufrufen oder den Protokollierungs-Quellengenerator verwenden, um stark typisierte Protokollierungsmethoden zu definieren. In den meisten Fällen wird der Quellgenerator empfohlen, da er eine überlegene Leistung und eine stärkere Eingabe bietet. Außerdem werden protokollierungsspezifische Bedenken wie Nachrichtenvorlagen, IDs und Protokollebenen vom aufrufenden Code isoliert. Der nicht aus der Quelle generierte Ansatz ist in erster Linie für Szenarien nützlich, in denen Sie bereit sind, diese Vorteile aufzugeben, um den Code präziser zu gestalten.
using Microsoft.Extensions.Logging;
namespace Logging.LibraryAuthors;
internal static partial class LogMessages
{
[LoggerMessage(
Message = "Sold {Quantity} of {Description}",
Level = LogLevel.Information)]
internal static partial void LogProductSaleDetails(
this ILogger logger,
int quantity,
string description);
}
Der vorherige Code:
- Definiert ein
partial classmit dem NamenLogMessages, dasstaticist, sodass es verwendet werden kann, um Erweiterungsmethoden für den TypILoggerzu definieren. - Schmückt eine
LogProductSaleDetails-Erweiterungsmethode mit dem AttributLoggerMessageund der VorlageMessage. - Deklariert
LogProductSaleDetails, das dieILoggererweitert und einquantityunddescriptionakzeptiert.
Tipp
Sie können während des Debuggens in den quellcodegenerierten Code eintauchen, da er Teil derselben Assembly ist wie der Code, der ihn aufruft.
Wird IsEnabled verwendet, um teure Parameterauswertung zu vermeiden
Es kann Situationen geben, in denen die Auswertung von Parametern teuer ist. Erweitern Sie das vorherige Beispiel, stellen Sie sich vor, dass der description Parameter ein string ist, dessen Berechnung teuer ist. Vielleicht erhält das verkaufte Produkt eine freundliche Produktbeschreibung und basiert auf einer Datenbankabfrage oder dem Lesen aus einer Datei. In diesen Situationen können Sie den Quellgenerator anweisen, den IsEnabled Schutz zu überspringen und den IsEnabled Schutz an der Anrufstelle manuell hinzuzufügen. Auf diese Weise kann der Benutzer ermitteln, wo der Schutz aufgerufen wird, und stellt sicher, dass Parameter, die möglicherweise teuer zu berechnen sind, nur ausgewertet werden, wenn sie wirklich benötigt werden. Beachten Sie den folgenden Code:
using Microsoft.Extensions.Logging;
namespace Logging.LibraryAuthors;
internal static partial class LogMessages
{
[LoggerMessage(
Message = "Sold {Quantity} of {Description}",
Level = LogLevel.Information,
SkipEnabledCheck = true)]
internal static partial void LogProductSaleDetails(
this ILogger logger,
int quantity,
string description);
}
Wenn die LogProductSaleDetails-Erweiterungsmethode aufgerufen wird, wird der IsEnabled-Guard manuell ausgelöst, und die teure Parameterauswertung erfolgt nur bei Bedarf. Beachten Sie den folgenden Code:
if (_logger.IsEnabled(LogLevel.Information))
{
// Expensive parameter evaluation
var description = product.GetFriendlyProductDescription();
_logger.LogProductSaleDetails(
quantity,
description);
}
Weitere Informationen finden Sie unter Kompilierungszeitprotokollierungsquellengenerierung und Hochleistungsprotokollierung in .NET.
Vermeiden der Zeichenfolgeninterpolation bei der Protokollierung
Ein häufiger Fehler besteht darin, die Zeichenfolgeninterpolation zum Erstellen von Protokollmeldungen zu verwenden. Die Zeichenfolgeninterpolation in der Protokollierung ist für die Leistung problematisch, da die Zeichenfolge ausgewertet wird, auch wenn die entsprechende LogLevel nicht aktiviert ist. Verwenden Sie anstelle der Zeichenfolgeninterpolation die Protokollnachrichtenvorlage, Formatierung und Argumentliste. Weitere Informationen finden Sie unter Protokollierung in .NET: Protokollnachrichtenvorlage.
Verwenden von no-op-Protokollierungseinstellungen
Es kann vorkommen, dass beim Verwenden einer Bibliothek, die Protokollierungs-APIs bereitstellt, die entweder einen ILogger oder ILoggerFactory erwarten, Sie keinen Protokollierer bereitstellen möchten. In diesen Fällen stellt das NuGet-Paket Microsoft.Extensions.Logging.Abstractions Standardeinstellungen für die Nichtausführung der Protokollierung bereit.
Bibliotheksconsumer können standardmäßig auf Null Protokollierung festgelegt werden, wenn keine ILoggerFactory bereitgestellt wird. Die Verwendung der Null-Protokollierung unterscheidet sich von der Definition von Typen als Nullable-Typen (ILoggerFactory?), da die Typen nicht null sind. Diese benutzerfreundlichen Typen protokollieren nichts und führen im Wesentlichen keine Operationen durch. Erwägen Sie ggf. die Verwendung der verfügbaren Abstraktionstypen: